├── CommandPattern └── src │ ├── client.h │ ├── command.h │ ├── helloworldoutputcommand.h │ ├── main.cpp │ ├── server.h │ └── waitcommand.h ├── CommandProcessorPattern └── src │ ├── command.h │ ├── commandprocessor.h │ ├── drawcirclecommand.h │ ├── drawingprocessor.h │ ├── main.cpp │ ├── point.h │ └── undocommand.h ├── Compare └── src │ └── main.cpp ├── CompositePattern └── src │ ├── command.h │ ├── commandprocessor.h │ ├── compositecommand.h │ ├── drawcirclecommand.h │ ├── drawingprocessor.h │ ├── drawrectanglecommand.h │ ├── main.cpp │ ├── point.h │ └── undocommand.h ├── CopySwap └── src │ ├── clazz.h │ └── main.cpp ├── Functors └── src │ ├── binary.h │ ├── main.cpp │ ├── predicate.h │ ├── randomgenerator.h │ └── unary.h ├── HigherOrderFunction └── src │ └── main.cpp ├── ImmutableObject └── src │ ├── employee.h │ └── main.cpp ├── Lambda └── src │ └── main.cpp ├── Logging └── src │ ├── BoostTrivialLogAdapter.cpp │ ├── BoostTrivialLogAdapter.h │ ├── Customer.h │ ├── CustomerRepository.cpp │ ├── CustomerRepository.h │ ├── FilesystemLogger.cpp │ ├── FilesystemLogger.h │ ├── LoggerFactory.h │ ├── LoggingFacility.h │ ├── StandardOutputLogger.cpp │ ├── StandardOutputLogger.h │ └── main.cpp ├── ObserverPattern └── src │ ├── main.cpp │ ├── observer.h │ ├── spreadsheetmodel.h │ ├── spreadsheetviews.h │ └── subject.h ├── Palindrome └── src │ └── palindrome.cpp ├── PimplPattern └── src │ ├── address.h │ ├── customer.cpp │ ├── customer.h │ ├── customerid.h │ ├── formatter.cpp │ ├── formatter.h │ ├── main.cpp │ ├── plaintextformatter.h │ └── xmlformatter.h ├── README.md ├── RomanNumeral └── src │ ├── ArabicToRomanConversion.cpp │ ├── ArabicToRomanConversion.h │ ├── ArabicToRomanConversionTest.cpp │ └── main.cpp ├── SFINAE └── src │ ├── main.cpp │ └── sfinae.h ├── Sort └── src │ └── main.cpp ├── StrategyPattern └── src │ ├── address.h │ ├── customer.cpp │ ├── customer.h │ ├── customerid.h │ ├── formatter.cpp │ ├── formatter.h │ ├── jsonformatter.cpp │ ├── jsonformatter.h │ ├── main.cpp │ ├── plaintextformatter.h │ └── xmlformatter.h └── Switch └── src ├── lamp.h ├── main.cpp ├── switch.cpp ├── switch.h └── switchable.h /CommandPattern/src/client.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIENT_H_ 2 | #define CLIENT_H_ 3 | 4 | #include "server.h" 5 | #include "helloworldoutputcommand.h" 6 | #include "waitcommand.h" 7 | 8 | class Client 9 | { 10 | public: 11 | void run() 12 | { 13 | Server server; 14 | 15 | const uint32_t SERVER_DELAY_TIMESPAN {2000U}; 16 | CommandPtr waitCmd = std::make_shared(SERVER_DELAY_TIMESPAN); 17 | server.acceptCommand(waitCmd); 18 | 19 | CommandPtr helloCmd = std::make_shared(); 20 | server.acceptCommand(helloCmd); 21 | } 22 | }; 23 | 24 | #endif /* CLIENT_H_ */ 25 | -------------------------------------------------------------------------------- /CommandPattern/src/command.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMAND_H_ 2 | #define COMMAND_H_ 3 | 4 | #include 5 | 6 | class Command 7 | { 8 | public: 9 | virtual ~Command() = default; 10 | virtual void execute() = 0; 11 | }; 12 | 13 | using CommandPtr = std::shared_ptr; 14 | 15 | #endif /* COMMAND_H_ */ 16 | -------------------------------------------------------------------------------- /CommandPattern/src/helloworldoutputcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef HELLOWORLDOUTPUTCOMMAND_H_ 2 | #define HELLOWORLDOUTPUTCOMMAND_H_ 3 | 4 | #include "command.h" 5 | #include 6 | 7 | class HelloWorldOutputCommand : public Command 8 | { 9 | public: 10 | virtual void execute() override { 11 | std::cout << "Hello World!\n"; 12 | } 13 | }; 14 | 15 | 16 | #endif /* HELLOWORLDOUTPUTCOMMAND_H_ */ 17 | -------------------------------------------------------------------------------- /CommandPattern/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "client.h" 3 | 4 | int main() 5 | { 6 | Client client; 7 | client.run(); 8 | } 9 | -------------------------------------------------------------------------------- /CommandPattern/src/server.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVER_H_ 2 | #define SERVER_H_ 3 | 4 | #include "command.h" 5 | 6 | class Server 7 | { 8 | public: 9 | void acceptCommand(const CommandPtr& command) 10 | { 11 | command->execute(); 12 | } 13 | }; 14 | 15 | #endif /* SERVER_H_ */ 16 | -------------------------------------------------------------------------------- /CommandPattern/src/waitcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef WAITCOMMAND_H_ 2 | #define WAITCOMMAND_H_ 3 | 4 | #include "command.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class WaitCommand : public Command 11 | { 12 | public: 13 | explicit WaitCommand(const uint32_t durationMilliseconds) noexcept 14 | : durationMilliseconds{durationMilliseconds} { }; 15 | 16 | virtual void execute() override 17 | { 18 | std::cout << "[INFO] Sleeping for " << durationMilliseconds << " milliseconds" << std::endl; 19 | 20 | std::chrono::milliseconds duration(durationMilliseconds); 21 | std::this_thread::sleep_for(duration); 22 | } 23 | 24 | private: 25 | uint32_t durationMilliseconds; 26 | }; 27 | 28 | #endif /* WAITCOMMAND_H_ */ 29 | -------------------------------------------------------------------------------- /CommandProcessorPattern/src/command.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMAND_H_ 2 | #define COMMAND_H_ 3 | 4 | #include 5 | 6 | class Command 7 | { 8 | public: 9 | virtual ~Command() = default; 10 | virtual void execute() = 0; 11 | }; 12 | 13 | class Revertable 14 | { 15 | public: 16 | virtual ~Revertable() = default; 17 | virtual void undo() = 0; 18 | 19 | }; 20 | 21 | class UndoableCommand : public Command, public Revertable { }; 22 | 23 | using CommandPtr = std::shared_ptr; 24 | using UndoableCommandPtr = std::shared_ptr; 25 | 26 | #endif /* COMMAND_H_ */ 27 | -------------------------------------------------------------------------------- /CommandProcessorPattern/src/commandprocessor.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMANDPROCESSOR_H_ 2 | #define COMMANDPROCESSOR_H_ 3 | 4 | #include "command.h" 5 | #include 6 | #include 7 | #include 8 | 9 | class CommandProcessor 10 | { 11 | public: 12 | void execute(const UndoableCommandPtr& command) { 13 | command->execute(); 14 | commandHistory.push(command); 15 | } 16 | 17 | void undoLastCommand() { 18 | if (commandHistory.empty()) { 19 | std::cout << "[WARN] No commands in history" << std::endl; 20 | return; 21 | } 22 | 23 | commandHistory.top()->undo(); 24 | commandHistory.pop(); 25 | } 26 | 27 | private: 28 | std::stack> commandHistory; 29 | }; 30 | 31 | #endif /* COMMANDPROCESSOR_H_ */ 32 | -------------------------------------------------------------------------------- /CommandProcessorPattern/src/drawcirclecommand.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWCIRCLECOMMAND_H_ 2 | #define DRAWCIRCLECOMMAND_H_ 3 | 4 | #include "command.h" 5 | #include "drawingprocessor.h" 6 | 7 | class DrawCircleCommand : public UndoableCommand 8 | { 9 | public: 10 | DrawCircleCommand(DrawingProcessor& receiver, const Point& centerPoint, const double radius) 11 | : receiver(receiver), centerPoint(centerPoint), radius(radius) {} 12 | 13 | virtual void execute() override { 14 | receiver.drawCircle(centerPoint, radius); 15 | } 16 | 17 | virtual void undo() override { 18 | receiver.eraseCircle(centerPoint, radius); 19 | } 20 | 21 | private: 22 | DrawingProcessor& receiver; 23 | const Point centerPoint; 24 | const double radius; 25 | }; 26 | 27 | #endif /* DRAWCIRCLECOMMAND_H_ */ 28 | -------------------------------------------------------------------------------- /CommandProcessorPattern/src/drawingprocessor.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWINGPROCESSOR_H_ 2 | #define DRAWINGPROCESSOR_H_ 3 | 4 | #include 5 | #include "point.h" 6 | 7 | class DrawingProcessor 8 | { 9 | public: 10 | void drawCircle(const Point& centerPoint, const double radius) { 11 | std::cout << "Draw Circle: " << centerPoint << ", radius=" << radius << std::endl; 12 | } 13 | 14 | void eraseCircle(const Point& centerPoint, const double radius) { 15 | std::cout << "Erase Circle: " << centerPoint << ", radius=" << radius << std::endl; 16 | } 17 | }; 18 | 19 | #endif /* DRAWINGPROCESSOR_H_ */ 20 | -------------------------------------------------------------------------------- /CommandProcessorPattern/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "drawingprocessor.h" 2 | #include "drawcirclecommand.h" 3 | #include "undocommand.h" 4 | 5 | int main() 6 | { 7 | CommandProcessor cmdProcessor; 8 | UndoCommand undo(cmdProcessor); 9 | 10 | DrawingProcessor receiver; 11 | 12 | UndoableCommandPtr drawCircleCmd1 = std::make_shared(receiver, Point(1, 2), 5.0); 13 | cmdProcessor.execute(drawCircleCmd1); 14 | 15 | UndoableCommandPtr drawCircleCmd2 = std::make_shared(receiver, Point(3, 4), 6.5); 16 | cmdProcessor.execute(drawCircleCmd2); 17 | 18 | undo.execute(); 19 | 20 | UndoableCommandPtr drawCircleCmd3 = std::make_shared(receiver, Point(5, 6), 5.0); 21 | cmdProcessor.execute(drawCircleCmd3); 22 | 23 | undo.execute(); 24 | undo.execute(); 25 | } 26 | -------------------------------------------------------------------------------- /CommandProcessorPattern/src/point.h: -------------------------------------------------------------------------------- 1 | #ifndef POINT_H_ 2 | #define POINT_H_ 3 | 4 | #include 5 | 6 | class Point 7 | { 8 | public: 9 | Point() : _x(0.0), _y(0.0) {} 10 | Point(double x, double y) : _x(x), _y(y) {} 11 | Point(const Point& p) : _x(p._x), _y(p._y) {} 12 | 13 | double getX() const { return _x; } 14 | double getY() const { return _y; } 15 | 16 | private: 17 | double _x; 18 | double _y; 19 | }; 20 | 21 | std::ostream& operator<<(std::ostream& os, const Point& point) 22 | { 23 | os << "(" << point.getX() << ", " << point.getY() << ")"; 24 | return os; 25 | } 26 | 27 | #endif /* POINT_H_ */ 28 | -------------------------------------------------------------------------------- /CommandProcessorPattern/src/undocommand.h: -------------------------------------------------------------------------------- 1 | #ifndef UNDOCOMMAND_H_ 2 | #define UNDOCOMMAND_H_ 3 | 4 | #include "command.h" 5 | #include "commandprocessor.h" 6 | 7 | class UndoCommand : public UndoableCommand 8 | { 9 | public: 10 | explicit UndoCommand(CommandProcessor& receiver) 11 | : receiver(receiver) {} 12 | 13 | virtual void execute() override { 14 | receiver.undoLastCommand(); 15 | } 16 | 17 | virtual void undo() override { 18 | // Blank -- undo should not be undone. 19 | } 20 | 21 | private: 22 | CommandProcessor& receiver; 23 | }; 24 | 25 | #endif /* UNDOCOMMAND_H_ */ 26 | -------------------------------------------------------------------------------- /Compare/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void printText(const std::string& text) 7 | { 8 | std::cout << text << " "; 9 | } 10 | 11 | int main() 12 | { 13 | std::vector names1 = {"Peter", "Harry", "Julia", "John", "Antonio", "Glenn" }; 14 | std::vector names2 = {"Peter", "Harry", "Julia", "Johnson", "Antonio", "Glenn" }; 15 | 16 | // C++14 17 | bool isEqual = std::equal(std::begin(names1), std::end(names1), 18 | std::begin(names2), std::end(names2)); 19 | if (isEqual) 20 | { 21 | std::cout << "Content of both sequences are equal\n"; 22 | } 23 | else 24 | { 25 | std::cout << "Content of both sequences differ\n"; 26 | } 27 | 28 | bool isEqualFirstThreeChars = std::equal(std::begin(names1), 29 | std::end(names1), std::begin(names2), std::end(names2), 30 | [](const std::string& lhs, const std::string& rhs) { 31 | return (lhs.compare(0, 3, rhs, 0, 3) == 0); 32 | }); 33 | if (isEqualFirstThreeChars) 34 | { 35 | std::cout << "Content of both sequences are equal\n"; 36 | } 37 | else 38 | { 39 | std::cout << "Content of both sequences differ\n"; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /CompositePattern/src/command.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMAND_H_ 2 | #define COMMAND_H_ 3 | 4 | #include 5 | 6 | class Command 7 | { 8 | public: 9 | virtual ~Command() = default; 10 | virtual void execute() = 0; 11 | }; 12 | 13 | class Revertable 14 | { 15 | public: 16 | virtual ~Revertable() = default; 17 | virtual void undo() = 0; 18 | 19 | }; 20 | 21 | class UndoableCommand : public Command, public Revertable { }; 22 | 23 | using CommandPtr = std::shared_ptr; 24 | 25 | #endif /* COMMAND_H_ */ 26 | -------------------------------------------------------------------------------- /CompositePattern/src/commandprocessor.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMANDPROCESSOR_H_ 2 | #define COMMANDPROCESSOR_H_ 3 | 4 | #include "command.h" 5 | #include 6 | #include 7 | #include 8 | 9 | class CommandProcessor 10 | { 11 | public: 12 | void execute(const CommandPtr& command) { 13 | command->execute(); 14 | commandHistory.push(command); 15 | } 16 | 17 | void undoLastCommand() { 18 | if (commandHistory.empty()) { 19 | std::cout << "[WARN] No commands in history" << std::endl; 20 | return; 21 | } 22 | 23 | commandHistory.top()->undo(); 24 | commandHistory.pop(); 25 | } 26 | 27 | private: 28 | std::stack> commandHistory; 29 | }; 30 | 31 | #endif /* COMMANDPROCESSOR_H_ */ 32 | -------------------------------------------------------------------------------- /CompositePattern/src/compositecommand.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPOSITECOMMAND_H_ 2 | #define COMPOSITECOMMAND_H_ 3 | 4 | #include 5 | #include "command.h" 6 | 7 | class CompositeCommand : public UndoableCommand 8 | { 9 | public: 10 | void addCommand(CommandPtr command) { 11 | commands.push_back(command); 12 | } 13 | 14 | virtual void execute() override { 15 | for (const auto& command : commands) { 16 | command->execute(); 17 | } 18 | } 19 | 20 | virtual void undo() override { 21 | for (const auto& command : commands) { 22 | command->undo(); 23 | } 24 | } 25 | 26 | private: 27 | std::vector commands; 28 | }; 29 | 30 | #endif /* COMPOSITECOMMAND_H_ */ 31 | -------------------------------------------------------------------------------- /CompositePattern/src/drawcirclecommand.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWCIRCLECOMMAND_H_ 2 | #define DRAWCIRCLECOMMAND_H_ 3 | 4 | #include "command.h" 5 | #include "drawingprocessor.h" 6 | 7 | class DrawCircleCommand : public UndoableCommand 8 | { 9 | public: 10 | DrawCircleCommand(DrawingProcessor& receiver, const Point& centerPoint, const double radius) 11 | : receiver(receiver), centerPoint(centerPoint), radius(radius) {} 12 | 13 | virtual void execute() override { 14 | receiver.drawCircle(centerPoint, radius); 15 | } 16 | 17 | virtual void undo() override { 18 | receiver.eraseCircle(centerPoint, radius); 19 | } 20 | 21 | private: 22 | DrawingProcessor& receiver; 23 | const Point centerPoint; 24 | const double radius; 25 | }; 26 | 27 | #endif /* DRAWCIRCLECOMMAND_H_ */ 28 | -------------------------------------------------------------------------------- /CompositePattern/src/drawingprocessor.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWINGPROCESSOR_H_ 2 | #define DRAWINGPROCESSOR_H_ 3 | 4 | #include 5 | #include "point.h" 6 | 7 | class DrawingProcessor 8 | { 9 | public: 10 | void drawCircle(const Point& centerPoint, const double radius) { 11 | std::cout << "[Draw Circle] " 12 | << "{ " << centerPoint 13 | << ", radius=" << radius << " }" << std::endl; 14 | } 15 | 16 | void eraseCircle(const Point& centerPoint, const double radius) { 17 | std::cout << "[Erase Circle] " 18 | << "{ " << centerPoint 19 | << ", radius=" << radius << " }" << std::endl; 20 | } 21 | 22 | void drawRectangle(const Point& centerPoint, const double length, const double width) { 23 | std::cout << "[Draw Rectangle] " 24 | << centerPoint 25 | << " L = " << length << " W = " << width << std::endl; 26 | } 27 | 28 | void eraseRectangle(const Point& centerPoint, const double length, const double width) { 29 | std::cout << "[Erase Rectangle] " 30 | << centerPoint 31 | << " L = " << length << " W = " << width << std::endl; 32 | } 33 | }; 34 | 35 | #endif /* DRAWINGPROCESSOR_H_ */ 36 | -------------------------------------------------------------------------------- /CompositePattern/src/drawrectanglecommand.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWRECTANGLECOMMAND_H_ 2 | #define DRAWRECTANGLECOMMAND_H_ 3 | 4 | #include "command.h" 5 | #include "drawingprocessor.h" 6 | 7 | class DrawRectangleCommand: public UndoableCommand 8 | { 9 | public: 10 | DrawRectangleCommand(DrawingProcessor& receiver, const Point& centerPoint, const double length, const double width) : 11 | receiver(receiver), centerPoint(centerPoint), length(length), width(width) 12 | { 13 | } 14 | 15 | virtual void execute() override 16 | { 17 | receiver.drawRectangle(centerPoint, length, width); 18 | } 19 | 20 | virtual void undo() override 21 | { 22 | receiver.eraseRectangle(centerPoint, length, width); 23 | } 24 | 25 | private: 26 | DrawingProcessor& receiver; 27 | const Point centerPoint; 28 | const double length; 29 | const double width; 30 | }; 31 | 32 | #endif /* DRAWRECTANGLECOMMAND_H_ */ 33 | -------------------------------------------------------------------------------- /CompositePattern/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "drawingprocessor.h" 2 | #include "drawcirclecommand.h" 3 | #include "drawrectanglecommand.h" 4 | #include "undocommand.h" 5 | #include "compositecommand.h" 6 | #include "point.h" 7 | 8 | void testSingleCommands() 9 | { 10 | CommandProcessor commandProcessor; 11 | DrawingProcessor drawingProcessor; 12 | 13 | Point circleCenterPoint1{20, 20}; 14 | double circleRadius1 = 10.0; 15 | CommandPtr drawCircleCommand1 = std::make_shared(drawingProcessor, circleCenterPoint1, circleRadius1); 16 | commandProcessor.execute(drawCircleCommand1); 17 | 18 | Point circleCenterPoint2{25, 25}; 19 | double circleRadius2 = 15.0; 20 | CommandPtr drawCircleCommand2 = std::make_shared(drawingProcessor, circleCenterPoint2, circleRadius2); 21 | commandProcessor.execute(drawCircleCommand2); 22 | 23 | Point rectangleCenterPoint{30, 10}; 24 | CommandPtr drawRectangleCommand = std::make_shared(drawingProcessor, rectangleCenterPoint, 5, 8); 25 | commandProcessor.execute(drawRectangleCommand); 26 | 27 | UndoCommand undo(commandProcessor); 28 | undo.execute(); 29 | undo.execute(); 30 | } 31 | 32 | int main() 33 | { 34 | // testSingleCommands(); 35 | 36 | auto macroRecorder = std::make_shared(); 37 | DrawingProcessor drawingProcessor; 38 | 39 | Point circleCenterPoint1{20, 20}; 40 | double circleRadius1 = 10.0; 41 | CommandPtr drawCircleCommand1 = std::make_shared(drawingProcessor, circleCenterPoint1, circleRadius1); 42 | macroRecorder->addCommand(drawCircleCommand1); 43 | 44 | Point circleCenterPoint2{25, 25}; 45 | double circleRadius2 = 15.0; 46 | CommandPtr drawCircleCommand2 = std::make_shared(drawingProcessor, circleCenterPoint2, circleRadius2); 47 | macroRecorder->addCommand(drawCircleCommand2); 48 | 49 | Point rectangleCenterPoint{30, 10}; 50 | CommandPtr drawRectangleCommand = std::make_shared(drawingProcessor, rectangleCenterPoint, 5, 8); 51 | macroRecorder->addCommand(drawRectangleCommand); 52 | 53 | std::cout << "-- Execute commands in macro recorder --" << std::endl; 54 | macroRecorder->execute(); 55 | 56 | std::cout << "-- Undo commands in macro recorder --" << std::endl; 57 | macroRecorder->undo(); 58 | } 59 | -------------------------------------------------------------------------------- /CompositePattern/src/point.h: -------------------------------------------------------------------------------- 1 | #ifndef POINT_H_ 2 | #define POINT_H_ 3 | 4 | #include 5 | 6 | class Point 7 | { 8 | public: 9 | Point() : _x(0.0), _y(0.0) {} 10 | Point(double x, double y) : _x(x), _y(y) {} 11 | Point(const Point& p) : _x(p._x), _y(p._y) {} 12 | 13 | double getX() const { return _x; } 14 | double getY() const { return _y; } 15 | 16 | private: 17 | double _x; 18 | double _y; 19 | }; 20 | 21 | std::ostream& operator<<(std::ostream& os, const Point& point) 22 | { 23 | os << "(" << point.getX() << ", " << point.getY() << ")"; 24 | return os; 25 | } 26 | 27 | #endif /* POINT_H_ */ 28 | -------------------------------------------------------------------------------- /CompositePattern/src/undocommand.h: -------------------------------------------------------------------------------- 1 | #ifndef UNDOCOMMAND_H_ 2 | #define UNDOCOMMAND_H_ 3 | 4 | #include "command.h" 5 | #include "commandprocessor.h" 6 | 7 | class UndoCommand : public UndoableCommand 8 | { 9 | public: 10 | explicit UndoCommand(CommandProcessor& receiver) 11 | : receiver(receiver) {} 12 | 13 | virtual void execute() override { 14 | receiver.undoLastCommand(); 15 | } 16 | 17 | virtual void undo() override { 18 | // Blank -- undo should not be undone. 19 | } 20 | 21 | private: 22 | CommandProcessor& receiver; 23 | }; 24 | 25 | #endif /* UNDOCOMMAND_H_ */ 26 | -------------------------------------------------------------------------------- /CopySwap/src/clazz.h: -------------------------------------------------------------------------------- 1 | #ifndef CLAZZ_H_ 2 | #define CLAZZ_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Clazz final 10 | { 11 | public: 12 | Clazz() : resourceToManage { nullptr }, size{0} { } 13 | 14 | Clazz(const std::size_t size) : resourceToManage { new char[size+1]() }, size{size} { } 15 | 16 | Clazz(const std::size_t size, char ch) : resourceToManage { new char[size+1]() }, size{size} 17 | { 18 | for (std::size_t i = 0; i < size; ++i) { 19 | resourceToManage[i] = ch; 20 | } 21 | } 22 | 23 | Clazz(const Clazz& other) : Clazz { other.size } { 24 | std::copy(other.resourceToManage, other.resourceToManage + other.size, resourceToManage); 25 | } 26 | 27 | Clazz& operator=(Clazz other) { 28 | swap(other); 29 | return *this; 30 | } 31 | 32 | ~Clazz() { 33 | delete [] resourceToManage; 34 | } 35 | 36 | std::size_t getSize() const { return size; } 37 | const char* getResource() const { return resourceToManage; } 38 | 39 | private: 40 | void swap(Clazz& other) noexcept 41 | { 42 | using std::swap; 43 | swap(resourceToManage, other.resourceToManage); 44 | swap(size, other.size); 45 | } 46 | 47 | private: 48 | char* resourceToManage; 49 | std::size_t size; 50 | }; 51 | 52 | std::ostream& operator<<(std::ostream& os, const Clazz& c) 53 | { 54 | os << "[ " 55 | << "Buffer Size: " << c.getSize() << " " 56 | << "Resource: " << c.getResource() << " " 57 | << " ]"; 58 | return os; 59 | } 60 | 61 | #endif /* CLAZZ_H_ */ 62 | -------------------------------------------------------------------------------- /CopySwap/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "clazz.h" 3 | 4 | int main() 5 | { 6 | Clazz c1 {8, 'B'}; 7 | Clazz c2 {c1}; 8 | Clazz c3; 9 | c3 = c2; 10 | 11 | std::cout << "c1: " << c1 << std::endl; 12 | std::cout << "c2: " << c2 << std::endl; 13 | std::cout << "c3: " << c3 << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Functors/src/binary.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARY_H_ 2 | #define BINARY_H_ 3 | 4 | template 5 | class IsGreaterOrEqual { 6 | public: 7 | bool operator()(const T& lhs, const T& rhs) const noexcept { 8 | return lhs >= rhs; 9 | } 10 | }; 11 | 12 | #endif /* BINARY_H_ */ 13 | -------------------------------------------------------------------------------- /Functors/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "randomgenerator.h" 7 | #include "unary.h" 8 | #include "predicate.h" 9 | #include "binary.h" 10 | 11 | template 12 | void print(const std::vector& v) 13 | { 14 | for (T n : v) { 15 | std::cout << n << " "; 16 | } 17 | std::cout << std::endl; 18 | } 19 | 20 | class IncreasingNumberGenerator 21 | { 22 | public: 23 | int operator()() noexcept { 24 | return number++; 25 | } 26 | 27 | private: 28 | int number {0}; 29 | }; 30 | 31 | void testIncreasingNumberGenerator() 32 | { 33 | IncreasingNumberGenerator numGen; 34 | std::cout << numGen() << " " << numGen() << " " << numGen() << std::endl; 35 | } 36 | 37 | void testGenerateIncreasingNumberGenerator() 38 | { 39 | const size_t AMOUNT_OF_NUMBERS {10}; 40 | std::vector numbers(AMOUNT_OF_NUMBERS); 41 | std::generate(std::begin(numbers), std::end(numbers), IncreasingNumberGenerator()); 42 | print(numbers); 43 | } 44 | 45 | void testIota() 46 | { 47 | const size_t AMOUNT_OF_NUMBERS {10}; 48 | std::vector numbers(AMOUNT_OF_NUMBERS); 49 | std::iota(numbers.begin(), numbers.end(), 1); 50 | print(numbers); 51 | } 52 | 53 | void testRandomGenerator() 54 | { 55 | RandomNumberGenerator randGen; 56 | 57 | const size_t AMOUNT_OF_NUMBERS {10}; 58 | std::vector randomNumbers(AMOUNT_OF_NUMBERS); 59 | std::generate(std::begin(randomNumbers), std::end(randomNumbers), std::ref(randGen)); 60 | print(randomNumbers); 61 | 62 | } 63 | 64 | void testUnary() 65 | { 66 | const size_t AMOUNT_OF_NUMBERS {10}; 67 | std::vector numbers(AMOUNT_OF_NUMBERS); 68 | std::iota(numbers.begin(), numbers.end(), 1); 69 | std::transform(std::begin(numbers), std::end(numbers), std::begin(numbers), ToSquare()); 70 | print(numbers); 71 | } 72 | 73 | void testUnaryPredicate() 74 | { 75 | std::vector numbers(10); 76 | std::iota(numbers.begin(), numbers.end(), 1); 77 | numbers.erase( std::remove_if(std::begin(numbers), std::end(numbers), IsOdd()), 78 | std::end(numbers) ); 79 | print(numbers); 80 | } 81 | 82 | void testUnaryPredicateTemplate() 83 | { 84 | using Vector = std::vector; 85 | 86 | Vector numbers(10); 87 | std::iota(numbers.begin(), numbers.end(), 1); 88 | numbers.erase( std::remove_if(std::begin(numbers), std::end(numbers), IsOddNumeric()), 89 | std::end(numbers) ); 90 | print(numbers); 91 | } 92 | 93 | void testBinary() 94 | { 95 | std::vector numbers(10); 96 | std::iota(numbers.begin(), numbers.end(), 1); 97 | // std::sort(numbers.begin(), numbers.end(), IsGreaterOrEqual()); 98 | std::sort(numbers.begin(), numbers.end(), std::greater()); 99 | print(numbers); 100 | } 101 | 102 | int main() 103 | { 104 | testIncreasingNumberGenerator(); 105 | testGenerateIncreasingNumberGenerator(); 106 | testIota(); 107 | testRandomGenerator(); 108 | 109 | testUnary(); 110 | testUnaryPredicate(); 111 | testUnaryPredicateTemplate(); 112 | testBinary(); 113 | 114 | } 115 | -------------------------------------------------------------------------------- /Functors/src/predicate.h: -------------------------------------------------------------------------------- 1 | #ifndef PREDICATE_H_ 2 | #define PREDICATE_H_ 3 | 4 | #include 5 | 6 | class IsOdd { 7 | public: 8 | constexpr bool operator()(const int value) const noexcept { 9 | return (value % 2) != 0; 10 | } 11 | }; 12 | 13 | template 14 | class IsOddNumeric { 15 | public: 16 | static_assert(std::is_integral::value, 17 | "IsOddNumeric requires an integer type for template parameter"); 18 | 19 | constexpr bool operator()(const T value) const noexcept { 20 | return (value % 2) != 0; 21 | } 22 | }; 23 | 24 | #endif /* PREDICATE_H_ */ 25 | -------------------------------------------------------------------------------- /Functors/src/randomgenerator.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOMGENERATOR_H_ 2 | #define RANDOMGENERATOR_H_ 3 | 4 | #include 5 | 6 | template 7 | class RandomNumberGenerator { 8 | public: 9 | RandomNumberGenerator() { 10 | mersenneTwisterEngine.seed(randomDevice()); 11 | } 12 | 13 | T operator()() { 14 | return distribution(mersenneTwisterEngine); 15 | } 16 | 17 | private: 18 | std::random_device randomDevice; 19 | std::uniform_int_distribution distribution; 20 | std::mt19937_64 mersenneTwisterEngine; 21 | }; 22 | 23 | 24 | #endif /* RANDOMGENERATOR_H_ */ 25 | -------------------------------------------------------------------------------- /Functors/src/unary.h: -------------------------------------------------------------------------------- 1 | #ifndef UNARY_H_ 2 | #define UNARY_H_ 3 | 4 | // Example of unary function -- functor with one parameter 5 | class ToSquare { 6 | public: 7 | constexpr int operator()(const int value) const noexcept { 8 | return value * value; 9 | } 10 | }; 11 | 12 | #endif /* UNARY_H_ */ 13 | -------------------------------------------------------------------------------- /HigherOrderFunction/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | void myForEach(const CONTAINER_TYPE& container, UNARY_FUNCTION_TYPE unaryFunction) 8 | { 9 | for (const auto& element : container) { 10 | unaryFunction(element); 11 | } 12 | } 13 | 14 | template 15 | void myTransform(CONTAINER_TYPE& container, UNARY_OPERATION_TYPE unaryOperator) 16 | { 17 | for (auto& element : container) { 18 | element = unaryOperator(element); 19 | } 20 | } 21 | 22 | template 23 | class ToSquare 24 | { 25 | public: 26 | NUMBER_TYPE operator()(const NUMBER_TYPE& number) const noexcept { 27 | return number * number; 28 | } 29 | }; 30 | 31 | template 32 | void printOnStdOut(const T& thing) 33 | { 34 | std::cout << thing << " "; 35 | } 36 | 37 | int main() 38 | { 39 | std::vector numbers(10); 40 | std::iota(numbers.begin(), numbers.end(), 1); 41 | 42 | myTransform(numbers, ToSquare()); 43 | 44 | std::function printNumbers = printOnStdOut; 45 | myForEach(numbers, printNumbers); 46 | std::cout << std::endl; 47 | } 48 | -------------------------------------------------------------------------------- /ImmutableObject/src/employee.h: -------------------------------------------------------------------------------- 1 | #ifndef EMPLOYEE_H 2 | #define EMPLOYEE_H 3 | 4 | #include 5 | #include 6 | 7 | class Employee final 8 | { 9 | public: 10 | Employee(std::string firstName, std::string lastName, int staffNumber, double salary) : 11 | firstName(firstName), lastName(lastName), staffNumber(staffNumber), salary(salary) { } 12 | 13 | ~Employee() = default; 14 | 15 | Employee(const Employee& other) = default; 16 | Employee& operator=(const Employee& other) = default; 17 | Employee(Employee&& other) = default; 18 | Employee& operator=(Employee&& other) = default; 19 | 20 | std::string getFirstName() const noexcept { 21 | return firstName; 22 | } 23 | 24 | std::string getLastName() const noexcept { 25 | return lastName; 26 | } 27 | 28 | int getStaffNumber() const noexcept { 29 | return staffNumber; 30 | } 31 | 32 | double getSalary() const noexcept { 33 | return salary; 34 | } 35 | 36 | Employee changeSalary(double newSalary) const noexcept { 37 | return Employee(firstName, lastName, staffNumber, newSalary); 38 | } 39 | 40 | private: 41 | const std::string firstName; 42 | const std::string lastName; 43 | const int staffNumber; 44 | const double salary; 45 | }; 46 | 47 | std::ostream& operator<<(std::ostream& os, const Employee& employee) 48 | { 49 | os << "[ " 50 | << employee.getFirstName() << " " 51 | << employee.getLastName() << " " 52 | "" << " " 53 | << "" 54 | << " ]"; 55 | return os; 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /ImmutableObject/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "employee.h" 4 | 5 | int main() 6 | { 7 | Employee e1("Jane", "Smith", 100, 45000.00); 8 | Employee e2("Mike", "Jones", 101, 57000.00); 9 | Employee e3("Brian", "Carter", 102, 48000.00); 10 | 11 | std::vector employees; 12 | employees.push_back(e1); 13 | employees.push_back(e2); 14 | employees.push_back(e3); 15 | 16 | for (const auto& emp : employees) { 17 | std::cout << emp << std::endl; 18 | } 19 | 20 | Employee e2_c = e2.changeSalary(59000.00); 21 | std::cout << " " << e2 << std::endl; 22 | std::cout << " " << e2_c << std::endl; 23 | } 24 | -------------------------------------------------------------------------------- /Lambda/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | std::vector quote {"One", "small", "step", "for", "a", "man"}; 10 | 11 | std::vector result; 12 | std::transform(std::begin(quote), std::end(quote), std::back_inserter(result), 13 | [](const std::string& word) { return "<" + word + ">";}); 14 | std::for_each(std::begin(result), std::end(result), 15 | [](const std::string& word) { std::cout << word << " "; }); 16 | std::cout << std::endl; 17 | 18 | 19 | // C++14 only -- generic lambda expressions 20 | auto square = [](const auto& value) noexcept { return value * value; }; 21 | 22 | auto res1 = square(12.56); 23 | auto res2 = square(-6); 24 | auto res3 = square(std::complex(4.0, 2.5)); 25 | std::cout << "result 1: " << res1 << "\n"; 26 | std::cout << "result 2: " << res2 << "\n"; 27 | std::cout << "result 3: " << res3 << "\n"; 28 | } 29 | -------------------------------------------------------------------------------- /Logging/src/BoostTrivialLogAdapter.cpp: -------------------------------------------------------------------------------- 1 | #include "BoostTrivialLogAdapter.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | // Notes for compilation: 19 | // - BOOST_LOG_DYN_LINK defined as preprocessor symbol 20 | // - Linked to libboost_log-mt library 21 | 22 | // REF: 23 | // https://gist.github.com/xiongjia/e23b9572d3fc3d677e3d 24 | 25 | BoostTrivialLogAdapter::BoostTrivialLogAdapter() 26 | { 27 | /* init boost log 28 | * 1. Add common attributes 29 | * 2. set log filter to trace 30 | */ 31 | boost::log::add_common_attributes(); 32 | boost::log::core::get()->add_global_attribute("Scope", 33 | boost::log::attributes::named_scope()); 34 | boost::log::core::get()->set_filter( 35 | boost::log::trivial::severity >= boost::log::trivial::trace 36 | ); 37 | 38 | /* log formatter: 39 | * [TimeStamp] [ThreadId] [Severity Level] [Scope] Log message 40 | */ 41 | auto fmtTimeStamp = boost::log::expressions:: 42 | format_date_time("TimeStamp", "%Y-%m-%d %H:%M:%S.%f"); 43 | 44 | // auto fmtThreadId = boost::log::expressions:: 45 | // attr("ThreadID"); 46 | 47 | auto fmtSeverity = boost::log::expressions:: 48 | attr("Severity"); 49 | 50 | auto fmtScope = boost::log::expressions::format_named_scope("Scope", 51 | boost::log::keywords::format = "%n(%f:%l)", 52 | boost::log::keywords::iteration = boost::log::expressions::reverse, 53 | boost::log::keywords::depth = 2); 54 | 55 | // boost::log::formatter logFmt = 56 | // boost::log::expressions::format("[%1%] (%2%) [%3%] [%4%] %5%") 57 | // % fmtTimeStamp % fmtThreadId % fmtSeverity % fmtScope 58 | // % boost::log::expressions::smessage; 59 | boost::log::formatter logFmt = 60 | boost::log::expressions::format("[%1%] [%2%] %3%") 61 | % fmtTimeStamp % fmtSeverity % boost::log::expressions::smessage; 62 | 63 | /* console sink */ 64 | auto consoleSink = boost::log::add_console_log(std::clog); 65 | consoleSink->set_formatter(logFmt); 66 | 67 | /* fs sink */ 68 | auto fsSink = boost::log::add_file_log( 69 | // boost::log::keywords::file_name = "/temp/test_%Y-%m-%d_%H-%M-%S.%N.log", 70 | boost::log::keywords::file_name = "/temp/test_%Y-%m-%d.log", 71 | boost::log::keywords::rotation_size = 10 * 1024 * 1024, 72 | boost::log::keywords::min_free_space = 30 * 1024 * 1024, 73 | boost::log::keywords::open_mode = std::ios_base::app); 74 | fsSink->set_formatter(logFmt); 75 | fsSink->locked_backend()->auto_flush(true); 76 | } 77 | 78 | void BoostTrivialLogAdapter::writeInfoEntry(std::string_view entry) 79 | { 80 | BOOST_LOG_TRIVIAL(info) << entry; 81 | } 82 | 83 | void BoostTrivialLogAdapter::writeWarnEntry(std::string_view entry) 84 | { 85 | BOOST_LOG_TRIVIAL(warning) << entry; 86 | } 87 | 88 | void BoostTrivialLogAdapter::writeErrorEntry(std::string_view entry) 89 | { 90 | BOOST_LOG_TRIVIAL(error) << entry; 91 | } 92 | -------------------------------------------------------------------------------- /Logging/src/BoostTrivialLogAdapter.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOSTTRIVIALLOGADAPTER_H_ 2 | #define BOOSTTRIVIALLOGADAPTER_H_ 3 | 4 | #include "LoggingFacility.h" 5 | 6 | class BoostTrivialLogAdapter : public LoggingFacility 7 | { 8 | public: 9 | BoostTrivialLogAdapter(); 10 | virtual ~BoostTrivialLogAdapter() = default; 11 | 12 | virtual void writeInfoEntry(std::string_view entry) override; 13 | virtual void writeWarnEntry(std::string_view entry) override; 14 | virtual void writeErrorEntry(std::string_view entry) override; 15 | }; 16 | 17 | #endif /* BOOSTTRIVIALLOGADAPTER_H_ */ 18 | -------------------------------------------------------------------------------- /Logging/src/Customer.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMER_H_ 2 | #define CUSTOMER_H_ 3 | 4 | class Customer 5 | { 6 | public: 7 | Customer() = default; 8 | virtual ~Customer() = default; 9 | 10 | virtual bool findCustomerById(int id) = 0; 11 | }; 12 | 13 | #endif /* CUSTOMER_H_ */ 14 | -------------------------------------------------------------------------------- /Logging/src/CustomerRepository.cpp: -------------------------------------------------------------------------------- 1 | #include "CustomerRepository.h" 2 | #include 3 | 4 | bool CustomerRepository::findCustomerById(int id) 5 | { 6 | logger->writeInfoEntry("Starting to search for customer with ID: " + std::to_string(id)); 7 | return true; 8 | } 9 | -------------------------------------------------------------------------------- /Logging/src/CustomerRepository.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMERREPOSITORY_H_ 2 | #define CUSTOMERREPOSITORY_H_ 3 | 4 | #include "Customer.h" 5 | #include "LoggingFacility.h" 6 | 7 | class CustomerRepository : public Customer 8 | { 9 | public: 10 | CustomerRepository() = delete; 11 | explicit CustomerRepository(const Logger& loggingService) : logger {loggingService} { } 12 | 13 | virtual bool findCustomerById(int id) override; 14 | 15 | private: 16 | Logger logger; 17 | }; 18 | 19 | #endif /* CUSTOMERREPOSITORY_H_ */ 20 | -------------------------------------------------------------------------------- /Logging/src/FilesystemLogger.cpp: -------------------------------------------------------------------------------- 1 | #include "FilesystemLogger.h" 2 | #include 3 | 4 | FilesystemLogger::FilesystemLogger(const std::string path) 5 | : out(path, std::ofstream::out) 6 | { 7 | // empty body 8 | } 9 | 10 | void FilesystemLogger::writeInfoEntry(std::string_view entry) 11 | { 12 | out << "[INFO] " << entry << std::endl; 13 | } 14 | 15 | void FilesystemLogger::writeWarnEntry(std::string_view entry) 16 | { 17 | out << "[WARN] " << entry << std::endl; 18 | } 19 | 20 | void FilesystemLogger::writeErrorEntry(std::string_view entry) 21 | { 22 | out << "[ERROR] " << entry << std::endl; 23 | } 24 | -------------------------------------------------------------------------------- /Logging/src/FilesystemLogger.h: -------------------------------------------------------------------------------- 1 | #ifndef FILESYSTEMLOGGER_H_ 2 | #define FILESYSTEMLOGGER_H_ 3 | 4 | #include "LoggingFacility.h" 5 | #include 6 | 7 | class FilesystemLogger : public LoggingFacility 8 | { 9 | public: 10 | explicit FilesystemLogger(const std::string path); 11 | 12 | virtual void writeInfoEntry(std::string_view entry) override; 13 | virtual void writeWarnEntry(std::string_view entry) override; 14 | virtual void writeErrorEntry(std::string_view entry) override; 15 | 16 | private: 17 | std::ofstream out; 18 | }; 19 | 20 | #endif /* FILESYSTEMLOGGER_H_ */ 21 | -------------------------------------------------------------------------------- /Logging/src/LoggerFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGGERFACTORY_H_ 2 | #define LOGGERFACTORY_H_ 3 | 4 | #include "StandardOutputLogger.h" 5 | #include "FilesystemLogger.h" 6 | #include "BoostTrivialLogAdapter.h" 7 | 8 | #include 9 | #include 10 | 11 | class LoggerFactory 12 | { 13 | private: 14 | enum class OutputTarget 15 | { 16 | STDOUT, FILE, BOOST 17 | }; 18 | 19 | public: 20 | static Logger create(const std::string& configurationFileName) { 21 | std::string configurationFileContent = readConfigurationFile(configurationFileName); 22 | OutputTarget outputTarget = evaluateConfiguration(configurationFileName); 23 | return createLogger(outputTarget); 24 | } 25 | 26 | private: 27 | static std::string readConfigurationFile(const std::string& configurationFileName) { 28 | std::ifstream filestream(configurationFileName); 29 | return std::string(std::istreambuf_iterator(filestream), 30 | std::istreambuf_iterator()); 31 | } 32 | 33 | static OutputTarget evaluateConfiguration(const std::string& configurationFileContent) { 34 | // TODO Evaluate content of configuration file 35 | return OutputTarget::BOOST; 36 | } 37 | 38 | static Logger createLogger(OutputTarget outputTarget) { 39 | std::string fileLogPath("/temp/customer_log.txt"); 40 | 41 | switch (outputTarget) { 42 | case OutputTarget::FILE: 43 | return std::make_shared(fileLogPath); 44 | case OutputTarget::STDOUT: 45 | return std::make_shared(); 46 | case OutputTarget::BOOST: 47 | return std::make_shared(); 48 | default: 49 | return std::make_shared(); 50 | } 51 | } 52 | }; 53 | 54 | #endif /* LOGGERFACTORY_H_ */ 55 | -------------------------------------------------------------------------------- /Logging/src/LoggingFacility.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGGINGFACILITY_H_ 2 | #define LOGGINGFACILITY_H_ 3 | 4 | #include 5 | #include 6 | 7 | class LoggingFacility 8 | { 9 | public: 10 | virtual ~LoggingFacility() = default; 11 | 12 | virtual void writeInfoEntry(std::string_view entry) = 0; 13 | virtual void writeWarnEntry(std::string_view entry) = 0; 14 | virtual void writeErrorEntry(std::string_view entry) = 0; 15 | }; 16 | 17 | using Logger = std::shared_ptr; 18 | 19 | #endif /* LOGGINGFACILITY_H_ */ 20 | -------------------------------------------------------------------------------- /Logging/src/StandardOutputLogger.cpp: -------------------------------------------------------------------------------- 1 | #include "StandardOutputLogger.h" 2 | #include 3 | 4 | void StandardOutputLogger::writeInfoEntry(std::string_view entry) 5 | { 6 | std::cout << "[INFO] " << entry << std::endl; 7 | } 8 | 9 | void StandardOutputLogger::writeWarnEntry(std::string_view entry) 10 | { 11 | std::cout << "[WARN] " << entry << std::endl; 12 | } 13 | 14 | void StandardOutputLogger::writeErrorEntry(std::string_view entry) 15 | { 16 | std::cout << "[ERROR] " << entry << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Logging/src/StandardOutputLogger.h: -------------------------------------------------------------------------------- 1 | #ifndef STANDARDOUTPUTLOGGER_H_ 2 | #define STANDARDOUTPUTLOGGER_H_ 3 | 4 | #include "LoggingFacility.h" 5 | 6 | class StandardOutputLogger : public LoggingFacility 7 | { 8 | public: 9 | virtual void writeInfoEntry(std::string_view entry) override; 10 | virtual void writeWarnEntry(std::string_view entry) override; 11 | virtual void writeErrorEntry(std::string_view entry) override; 12 | }; 13 | 14 | #endif /* STANDARDOUTPUTLOGGER_H_ */ 15 | -------------------------------------------------------------------------------- /Logging/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "LoggerFactory.h" 4 | #include "CustomerRepository.h" 5 | 6 | // Example of Dependency Injection design pattern 7 | // @see Clean C++ Chapter 9 8 | int main() 9 | { 10 | // TODO: specify path of configuration file name 11 | std::string configurationFileName; 12 | Logger logger = LoggerFactory::create(configurationFileName); 13 | 14 | auto customerRepository = std::make_shared(logger); 15 | customerRepository->findCustomerById(23); 16 | } 17 | -------------------------------------------------------------------------------- /ObserverPattern/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "spreadsheetmodel.h" 3 | #include "spreadsheetviews.h" 4 | 5 | int main() 6 | { 7 | SpreadsheetModel model; 8 | 9 | ObserverPtr observer1 = std::make_shared(model); 10 | model.addObserer(observer1); 11 | 12 | ObserverPtr observer2 = std::make_shared(model); 13 | model.addObserer(observer2); 14 | 15 | ObserverPtr observer3 = std::make_shared(model); 16 | model.addObserer(observer3); 17 | 18 | model.displayAllObservers(); 19 | 20 | model.changeCellValue("A", 1, 42); 21 | model.changeCellValue("B", 2, 23.1); 22 | 23 | model.removeObserver(observer1); 24 | model.displayAllObservers(); 25 | 26 | model.changeCellValue("C", 3, 3.14159); 27 | } 28 | -------------------------------------------------------------------------------- /ObserverPattern/src/observer.h: -------------------------------------------------------------------------------- 1 | #ifndef OBSERVER_H_ 2 | #define OBSERVER_H_ 3 | 4 | #include 5 | #include 6 | 7 | class Observer 8 | { 9 | public: 10 | virtual ~Observer() = default; 11 | virtual int getId() = 0; 12 | virtual void update() = 0; 13 | virtual std::string getName() const = 0; 14 | }; 15 | 16 | using ObserverPtr = std::shared_ptr; 17 | 18 | #endif /* OBSERVER_H_ */ 19 | -------------------------------------------------------------------------------- /ObserverPattern/src/spreadsheetmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef SPREADSHEETMODEL_H_ 2 | #define SPREADSHEETMODEL_H_ 3 | 4 | #include "subject.h" 5 | #include 6 | #include 7 | 8 | class SpreadsheetModel : public Subject 9 | { 10 | public: 11 | void changeCellValue(std::string_view column, const int row, const double value) 12 | { 13 | std::cout << "Cell [" << column << ", " << row << "] = " << value << std::endl; 14 | // Change value of spreadsheet cell, and then notify 15 | notifyAllObservers(); 16 | } 17 | }; 18 | 19 | #endif /* SPREADSHEETMODEL_H_ */ 20 | -------------------------------------------------------------------------------- /ObserverPattern/src/spreadsheetviews.h: -------------------------------------------------------------------------------- 1 | #ifndef SPREADSHEETVIEWS_H_ 2 | #define SPREADSHEETVIEWS_H_ 3 | 4 | #include "observer.h" 5 | #include "spreadsheetmodel.h" 6 | 7 | class TableView : public Observer 8 | { 9 | public: 10 | explicit TableView(SpreadsheetModel& model_) : model{model_} { } 11 | 12 | virtual int getId() override { 13 | return 1; 14 | } 15 | 16 | virtual void update() override { 17 | std::cout << "Update TableView" << std::endl; 18 | } 19 | 20 | virtual std::string getName() const { 21 | return "TableView"; 22 | } 23 | 24 | private: 25 | SpreadsheetModel& model; 26 | }; 27 | 28 | class BarChartView : public Observer 29 | { 30 | public: 31 | explicit BarChartView(SpreadsheetModel& model_) : model{model_} { } 32 | 33 | virtual int getId() override { 34 | return 2; 35 | } 36 | 37 | virtual void update() override { 38 | std::cout << "Update BarChartView" << std::endl; 39 | } 40 | 41 | virtual std::string getName() const { 42 | return "BarChartView"; 43 | } 44 | 45 | private: 46 | SpreadsheetModel& model; 47 | }; 48 | 49 | class PieChartView : public Observer 50 | { 51 | public: 52 | explicit PieChartView(SpreadsheetModel& model_) : model{model_} { } 53 | 54 | virtual int getId() override { 55 | return 3; 56 | } 57 | 58 | virtual void update() override { 59 | std::cout << "Update PieChartView" << std::endl; 60 | } 61 | 62 | virtual std::string getName() const { 63 | return "PieChartView"; 64 | } 65 | 66 | private: 67 | SpreadsheetModel& model; 68 | }; 69 | 70 | 71 | #endif /* SPREADSHEETVIEWS_H_ */ 72 | -------------------------------------------------------------------------------- /ObserverPattern/src/subject.h: -------------------------------------------------------------------------------- 1 | #ifndef SUBJECT_H_ 2 | #define SUBJECT_H_ 3 | 4 | #include "observer.h" 5 | #include 6 | #include 7 | 8 | class IsEqualTo final 9 | { 10 | public: 11 | explicit IsEqualTo(const ObserverPtr& observer) : 12 | observer { observer } 13 | { 14 | } 15 | 16 | bool operator()(const ObserverPtr& observerToCompare) { 17 | return observerToCompare->getId() == observer->getId(); 18 | } 19 | 20 | private: 21 | ObserverPtr observer; 22 | }; 23 | 24 | class Subject 25 | { 26 | public: 27 | void addObserer(ObserverPtr& observerToAdd) { 28 | auto iter = std::find_if(begin(observers), end(observers), 29 | IsEqualTo(observerToAdd)); 30 | if (iter == end(observers)) { 31 | observers.push_back(observerToAdd); 32 | } 33 | } 34 | 35 | void removeObserver(ObserverPtr& observerToRemove) { 36 | observers.erase(std::remove_if(begin(observers), end(observers), 37 | IsEqualTo(observerToRemove)), end(observers)); 38 | } 39 | 40 | void displayAllObservers() const { 41 | std::cout << "[ "; 42 | for (const auto& observer : observers) { 43 | std::cout << observer->getName() << " "; 44 | } 45 | std::cout << "]" << std::endl; 46 | } 47 | 48 | protected: 49 | void notifyAllObservers() const { 50 | for (const auto& observer : observers) { 51 | observer->update(); 52 | } 53 | } 54 | 55 | private: 56 | std::vector observers; 57 | }; 58 | 59 | #endif /* SUBJECT_H_ */ 60 | -------------------------------------------------------------------------------- /Palindrome/src/palindrome.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | void PRINT_ELEMENTS(const T& coll, const std::string& optstr = "") 10 | { 11 | std::cout << optstr; 12 | for (const auto& elem : coll) { 13 | std::cout << elem << ' '; 14 | } 15 | std::cout << std::endl; 16 | } 17 | 18 | class IsPalindrome 19 | { 20 | public: 21 | bool operator()(const std::string& word) const 22 | { 23 | const auto middleOfWord = begin(word) + word.size() / 2; 24 | return std::equal(begin(word), middleOfWord, rbegin(word)); 25 | } 26 | }; 27 | 28 | bool is_palindrome(const std::string& s) 29 | { 30 | return std::equal(s.begin(), s.begin() + s.size() / 2, s.rbegin()); 31 | } 32 | 33 | void testPalindrome(const std::string& s) 34 | { 35 | std::cout << "\"" << s << "\" " << (is_palindrome(s) ? "is" : "is not") 36 | << " a palindrome\n"; 37 | } 38 | 39 | int main() 40 | { 41 | testPalindrome("radar"); 42 | testPalindrome("hello"); 43 | 44 | std::vector words = { "dad", "hello", "radar", "vector", "level" }; 45 | PRINT_ELEMENTS(words, "words: "); 46 | 47 | // Example of Map 48 | std::vector angleWords; 49 | std::transform(begin(words), end(words), std::back_inserter(angleWords), 50 | [](const std::string& w) {return "<" + w + ">";}); 51 | PRINT_ELEMENTS(angleWords, "angle words: "); 52 | 53 | // Example of Filter 54 | words.erase(std::remove_if(begin(words), end(words), IsPalindrome()), 55 | end(words)); 56 | PRINT_ELEMENTS(words, "filtered words: "); 57 | 58 | std::vector all(10); 59 | std::iota(std::begin(all), std::end(all), 1); // Fill with 1, 2, ..., 10 60 | PRINT_ELEMENTS(all, "all: "); 61 | 62 | // Example of Reduce 63 | std::vector v(all); 64 | int sum = std::accumulate(v.begin(), v.end(), 0); 65 | int product = std::accumulate(v.begin(), v.end(), 1, 66 | std::multiplies()); 67 | std::string s = std::accumulate(std::next(v.begin()), v.end(), 68 | std::to_string(v[0]), // start with first element 69 | [](std::string a, int b) { 70 | return a + '-' + std::to_string(b); 71 | }); 72 | 73 | std::cout << "sum: " << sum << '\n' << "product: " << product << '\n' 74 | << "dash-separated string: " << s << '\n'; 75 | 76 | std::vector numbers {12, 45, -102, 33, 78, -8, 100, 2017, -110}; 77 | int maxValue = std::accumulate(numbers.begin(), numbers.end(), 0, 78 | [](int lhs, int rhs) { return lhs > rhs ? lhs : rhs; }); 79 | std::cout << "maxValue = " << maxValue << std::endl; 80 | 81 | std::vector even; 82 | std::copy_if(begin(all), end(all), std::back_inserter(even), 83 | [](int n) {return n % 2 == 0;}); 84 | PRINT_ELEMENTS(even, "even: "); 85 | 86 | // Example of Map 87 | std::transform(begin(even), end(even), begin(even), 88 | [](int n) {return n * n * n;}); 89 | PRINT_ELEMENTS(even, "evenCubed: "); 90 | } 91 | -------------------------------------------------------------------------------- /PimplPattern/src/address.h: -------------------------------------------------------------------------------- 1 | #ifndef ADDRESS_H_ 2 | #define ADDRESS_H_ 3 | 4 | #include 5 | 6 | class Address 7 | { 8 | public: 9 | Address() = default; 10 | ~Address() = default; 11 | 12 | std::string getStreet() const { 13 | return street; 14 | } 15 | 16 | std::string getCity() const { 17 | return city; 18 | } 19 | 20 | std::string getState() const { 21 | return state; 22 | } 23 | 24 | std::string getZipCodeAsString() const { 25 | return std::to_string(zipCode); 26 | } 27 | 28 | void setStreet(std::string street) { 29 | this->street = street; 30 | } 31 | 32 | void setCity(std::string city) { 33 | this->city = city; 34 | } 35 | 36 | void setState(std::string state) { 37 | this->state = state; 38 | } 39 | 40 | void setZipCode(int zipCode) { 41 | this->zipCode = zipCode; 42 | } 43 | 44 | private: 45 | std::string street; 46 | std::string city; 47 | std::string state; 48 | int zipCode {0}; 49 | }; 50 | 51 | #endif /* ADDRESS_H_ */ 52 | -------------------------------------------------------------------------------- /PimplPattern/src/customer.cpp: -------------------------------------------------------------------------------- 1 | #include "customer.h" 2 | #include "customerid.h" 3 | #include "formatter.h" 4 | 5 | class Customer::Impl final 6 | { 7 | public: 8 | Impl(CustomerId customerId, std::string forename, std::string surname, Address address); 9 | ~Impl() = default; 10 | 11 | std::string getAsFormattedString(const std::unique_ptr& formatter) const; 12 | 13 | private: 14 | CustomerId customerId; 15 | std::string forename; 16 | std::string surname; 17 | Address address; 18 | }; 19 | 20 | Customer::Impl::Impl(CustomerId customerId, std::string forename, std::string surname, Address address) 21 | : customerId(customerId) 22 | , forename(forename) 23 | , surname(surname) 24 | , address(address) 25 | {} 26 | 27 | std::string Customer::Impl::getAsFormattedString(const std::unique_ptr& formatter) const 28 | { 29 | return formatter-> 30 | withCustomerId(customerId.toString()). 31 | withForename(forename). 32 | withSurname(surname). 33 | withStreet(address.getStreet()). 34 | withZipCode(address.getZipCodeAsString()). 35 | withCity(address.getCity()). 36 | withState(address.getState()). 37 | format(); 38 | } 39 | 40 | Customer::Customer(int customerId, std::string forename, std::string surname, Address address) 41 | : impl { std::make_unique(CustomerId(customerId), forename, surname, address) } 42 | {} 43 | 44 | Customer::~Customer() = default; 45 | 46 | std::string Customer::getAsFormattedString(const std::unique_ptr& formatter) const 47 | { 48 | return impl->getAsFormattedString(formatter); 49 | } 50 | -------------------------------------------------------------------------------- /PimplPattern/src/customer.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMER_H_ 2 | #define CUSTOMER_H_ 3 | 4 | #include 5 | #include 6 | #include "address.h" 7 | 8 | // Forward declaration 9 | class Formatter; 10 | 11 | class Customer 12 | { 13 | public: 14 | Customer(int customerId, std::string forename, std::string surname, Address address); 15 | ~Customer(); 16 | 17 | std::string getAsFormattedString(const std::unique_ptr& formatter) const; 18 | 19 | private: 20 | class Impl; 21 | std::unique_ptr impl; 22 | }; 23 | 24 | #endif /* CUSTOMER_H_ */ 25 | -------------------------------------------------------------------------------- /PimplPattern/src/customerid.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMERID_H_ 2 | #define CUSTOMERID_H_ 3 | 4 | #include 5 | 6 | class CustomerId 7 | { 8 | public: 9 | CustomerId(int id): id(id) {} 10 | 11 | int getId() const { 12 | return id; 13 | } 14 | 15 | std::string toString() const { 16 | const int numberOfZeros = 5; 17 | std::string strId = std::string(numberOfZeros, '0').append(std::to_string(id)); 18 | return strId; 19 | } 20 | 21 | private: 22 | int id; 23 | }; 24 | 25 | #endif /* CUSTOMERID_H_ */ 26 | -------------------------------------------------------------------------------- /PimplPattern/src/formatter.cpp: -------------------------------------------------------------------------------- 1 | #include "formatter.h" 2 | 3 | Formatter& Formatter::withCustomerId(std::string_view customerId) 4 | { 5 | this->customerId = customerId; 6 | return *this; 7 | } 8 | 9 | Formatter& Formatter::withForename(std::string_view forename) 10 | { 11 | this->forename = forename; 12 | return *this; 13 | } 14 | 15 | Formatter& Formatter::withSurname(std::string_view surname) 16 | { 17 | this->surname = surname; 18 | return *this; 19 | } 20 | 21 | Formatter& Formatter::withStreet(std::string_view street) 22 | { 23 | this->street = street; 24 | return *this; 25 | } 26 | 27 | Formatter& Formatter::withZipCode(std::string_view zipCode) 28 | { 29 | this->zipCode = zipCode; 30 | return *this; 31 | } 32 | 33 | Formatter& Formatter::withCity(std::string_view city) 34 | { 35 | this->city = city; 36 | return *this; 37 | } 38 | 39 | Formatter& Formatter::withState(std::string_view state) 40 | { 41 | this->state = state; 42 | return *this; 43 | } 44 | -------------------------------------------------------------------------------- /PimplPattern/src/formatter.h: -------------------------------------------------------------------------------- 1 | #ifndef FORMATTER_H_ 2 | #define FORMATTER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Formatter 10 | { 11 | public: 12 | virtual ~Formatter() = default; 13 | 14 | Formatter& withCustomerId(std::string_view customerId); 15 | Formatter& withForename(std::string_view forename); 16 | Formatter& withSurname(std::string_view surname); 17 | Formatter& withStreet(std::string_view street); 18 | Formatter& withZipCode(std::string_view zipCode); 19 | Formatter& withCity(std::string_view city); 20 | Formatter& withState(std::string_view state); 21 | 22 | virtual std::string format() const = 0; 23 | 24 | protected: 25 | std::string customerId {"000000"}; 26 | std::string forename {"n/a"}; 27 | std::string surname {"n/a"}; 28 | std::string street {"n/a"}; 29 | std::string zipCode {"n/a"}; 30 | std::string city {"n/a"}; 31 | std::string state {"n/a"}; 32 | }; 33 | 34 | #endif /* FORMATTER_H_ */ 35 | -------------------------------------------------------------------------------- /PimplPattern/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "customer.h" 4 | #include "address.h" 5 | #include "customerid.h" 6 | #include "plaintextformatter.h" 7 | #include "xmlformatter.h" 8 | 9 | int main() 10 | { 11 | Address address1; 12 | address1.setStreet("123 Maple Lane"); 13 | address1.setCity("Atlanta"); 14 | address1.setState("GA"); 15 | address1.setZipCode(30338); 16 | 17 | int customerId = 1; 18 | Customer c1(customerId, "Bill", "Smith", address1); 19 | 20 | auto textFormatter = std::make_unique(); 21 | std::cout << c1.getAsFormattedString(std::move(textFormatter)) << std::endl; 22 | 23 | auto xmlFormatter = std::make_unique(); 24 | std::cout << c1.getAsFormattedString(std::move(xmlFormatter)) << std::endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /PimplPattern/src/plaintextformatter.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAINTEXTFORMATTER_H_ 2 | #define PLAINTEXTFORMATTER_H_ 3 | 4 | #include "formatter.h" 5 | 6 | class PlainTextFormatter : public Formatter 7 | { 8 | public: 9 | virtual std::string format() const override { 10 | std::stringstream formattedString; 11 | formattedString << "[" << customerId << "]: " 12 | << forename << " " << surname << ", " 13 | << street << ", " 14 | << city << ", " << state << " " << zipCode; 15 | return formattedString.str(); 16 | } 17 | }; 18 | 19 | #endif /* PLAINTEXTFORMATTER_H_ */ 20 | -------------------------------------------------------------------------------- /PimplPattern/src/xmlformatter.h: -------------------------------------------------------------------------------- 1 | #ifndef XMLFORMATTER_H_ 2 | #define XMLFORMATTER_H_ 3 | 4 | #include "formatter.h" 5 | 6 | class XmlFormatter : public Formatter 7 | { 8 | public: 9 | virtual std::string format() const override { 10 | std::stringstream formattedString; 11 | formattedString << "" << std::endl 12 | << " " << forename << "" << std::endl 13 | << " " << surname << "" << std::endl 14 | << " " << street << "" << std::endl 15 | << " " << city << "" << std::endl 16 | << " " << state << "" << std::endl 17 | << " " << zipCode << "" << std::endl 18 | << "" << std::endl; 19 | return formattedString.str(); 20 | } 21 | }; 22 | 23 | #endif /* XMLFORMATTER_H_ */ 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # clean-cpp 2 | Code samples from book "Clean C++: Sustainable Software Development Patterns and Best Practices with C++ 17" 3 | -------------------------------------------------------------------------------- /RomanNumeral/src/ArabicToRomanConversion.cpp: -------------------------------------------------------------------------------- 1 | #include "ArabicToRomanConversion.h" 2 | #include 3 | 4 | namespace roman { 5 | 6 | struct ArabicToRomanMapping 7 | { 8 | size_t arabicNumber; 9 | std::string romanNumeral; 10 | }; 11 | 12 | const std::size_t numberOfMappings { 13 }; 13 | using ArabicToRomanMappings = std::array; 14 | 15 | const ArabicToRomanMappings arabicToRomanMappings = { { 16 | { 1000, "M" }, 17 | { 900, "CM" }, 18 | { 500, "D" }, 19 | { 400, "CD" }, 20 | { 100, "C" }, 21 | { 90, "XC" }, 22 | { 50, "L" }, 23 | { 40, "XL" }, 24 | { 10, "X" }, 25 | { 9, "IX" }, 26 | { 5, "V" }, 27 | { 4, "IV" }, 28 | { 1, "I" } 29 | } }; 30 | 31 | std::string convertArabicNumberToRomanNumeral(size_t arabicNumber) 32 | { 33 | std::string romanNumeral; 34 | 35 | for (auto mapping : arabicToRomanMappings) { 36 | while (arabicNumber >= mapping.arabicNumber) { 37 | romanNumeral += mapping.romanNumeral; 38 | arabicNumber -= mapping.arabicNumber; 39 | } 40 | } 41 | 42 | return romanNumeral; 43 | } 44 | 45 | } // namespace roman 46 | -------------------------------------------------------------------------------- /RomanNumeral/src/ArabicToRomanConversion.h: -------------------------------------------------------------------------------- 1 | #ifndef ARABICTOROMANCONVERSION_H_ 2 | #define ARABICTOROMANCONVERSION_H_ 3 | 4 | #include 5 | #include 6 | 7 | namespace roman { 8 | 9 | std::string convertArabicNumberToRomanNumeral(size_t arabicNumber); 10 | 11 | } // namespace roman 12 | 13 | #endif /* ARABICTOROMANCONVERSION_H_ */ 14 | -------------------------------------------------------------------------------- /RomanNumeral/src/ArabicToRomanConversionTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ArabicToRomanConversion.h" 2 | #include "gtest/gtest.h" 3 | 4 | class ArabicToRomanTest : public ::testing::Test 5 | { 6 | public: 7 | std::string convertArabicNumberToRomanNumeral(size_t arabicNumber) { 8 | return roman::convertArabicNumberToRomanNumeral(arabicNumber); 9 | } 10 | }; 11 | 12 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_1) { 13 | ASSERT_EQ(convertArabicNumberToRomanNumeral(1), "I"); 14 | } 15 | 16 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_2) { 17 | ASSERT_EQ(convertArabicNumberToRomanNumeral(2), "II"); 18 | } 19 | 20 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_3) { 21 | ASSERT_EQ(convertArabicNumberToRomanNumeral(3), "III"); 22 | } 23 | 24 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_4) { 25 | ASSERT_EQ(convertArabicNumberToRomanNumeral(4), "IV"); 26 | } 27 | 28 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_5) { 29 | ASSERT_EQ(convertArabicNumberToRomanNumeral(5), "V"); 30 | } 31 | 32 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_6) { 33 | ASSERT_EQ(convertArabicNumberToRomanNumeral(6), "VI"); 34 | } 35 | 36 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_9) { 37 | ASSERT_EQ(convertArabicNumberToRomanNumeral(9), "IX"); 38 | } 39 | 40 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_10) { 41 | ASSERT_EQ(convertArabicNumberToRomanNumeral(10), "X"); 42 | } 43 | 44 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_20) { 45 | ASSERT_EQ(convertArabicNumberToRomanNumeral(20), "XX"); 46 | } 47 | 48 | TEST_F(ArabicToRomanTest, conversionOfArabicNumbersToRomanNumerals_Works) { 49 | 50 | ASSERT_EQ(convertArabicNumberToRomanNumeral(30), "XXX"); 51 | ASSERT_EQ(convertArabicNumberToRomanNumeral(33), "XXXIII"); 52 | ASSERT_EQ(convertArabicNumberToRomanNumeral(37), "XXXVII"); 53 | ASSERT_EQ(convertArabicNumberToRomanNumeral(50), "L"); 54 | ASSERT_EQ(convertArabicNumberToRomanNumeral(99), "XCIX"); 55 | ASSERT_EQ(convertArabicNumberToRomanNumeral(100), "C"); 56 | ASSERT_EQ(convertArabicNumberToRomanNumeral(200), "CC"); 57 | ASSERT_EQ(convertArabicNumberToRomanNumeral(300), "CCC"); 58 | ASSERT_EQ(convertArabicNumberToRomanNumeral(499), "CDXCIX"); 59 | ASSERT_EQ(convertArabicNumberToRomanNumeral(500), "D"); 60 | ASSERT_EQ(convertArabicNumberToRomanNumeral(1000), "M"); 61 | ASSERT_EQ(convertArabicNumberToRomanNumeral(2000), "MM"); 62 | ASSERT_EQ(convertArabicNumberToRomanNumeral(2017), "MMXVII"); 63 | ASSERT_EQ(convertArabicNumberToRomanNumeral(3000), "MMM"); 64 | ASSERT_EQ(convertArabicNumberToRomanNumeral(3333), "MMMCCCXXXIII"); 65 | ASSERT_EQ(convertArabicNumberToRomanNumeral(3999), "MMMCMXCIX"); 66 | } 67 | -------------------------------------------------------------------------------- /RomanNumeral/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | 3 | int main(int argc, char** argv) { 4 | ::testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } 7 | -------------------------------------------------------------------------------- /SFINAE/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "sfinae.h" 2 | 3 | enum Enumeration1 { 4 | Literal1, Literal2 5 | }; 6 | 7 | enum class Enumeration2 : int { 8 | Literal1, Literal2 9 | }; 10 | 11 | class Clazz { }; 12 | 13 | // Calling overloaded print() for enumerations. 14 | // Calling overloaded print() for enumerations. 15 | // Calling overloaded print() for classes. 16 | // Calling overloaded print() for integral types. 17 | // Calling overloaded print() for floating point types. 18 | // Calling overloaded print() for floating point types. 19 | int main() 20 | { 21 | Enumeration1 enum1 { }; 22 | print(enum1); 23 | 24 | Enumeration2 enum2 { }; 25 | print(enum2); 26 | 27 | Clazz instance { }; 28 | print(instance); 29 | 30 | print(42); 31 | print(42.0f); 32 | print(42.0); 33 | } 34 | -------------------------------------------------------------------------------- /SFINAE/src/sfinae.h: -------------------------------------------------------------------------------- 1 | #ifndef SFINAE_H_ 2 | #define SFINAE_H_ 3 | 4 | #include 5 | #include 6 | 7 | template 8 | void print(T var, typename std::enable_if::value, T>::type* = 0) 9 | { 10 | std::cout << "Calling overloaded print() for enumerations." << std::endl; 11 | } 12 | 13 | template 14 | void print(T var, typename std::enable_if::value, T>::type = 0) 15 | { 16 | std::cout << "Calling overloaded print() for integral types." << std::endl; 17 | } 18 | 19 | template 20 | void print(T var, typename std::enable_if::value, T>::type = 0) 21 | { 22 | std::cout << "Calling overloaded print() for floating point types." << std::endl; 23 | } 24 | 25 | template 26 | void print(const T& var, typename std::enable_if::value, T>::type* = 0) 27 | { 28 | std::cout << "Calling overloaded print() for classes." << std::endl; 29 | } 30 | 31 | #endif /* SFINAE_H_ */ 32 | -------------------------------------------------------------------------------- /Sort/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void printText(const std::string& text) 7 | { 8 | std::cout << text << " "; 9 | } 10 | 11 | int main() 12 | { 13 | std::vector names = {"Peter", "Harry", "Julia", "Marc", "Antonio", "Glenn" }; 14 | std::sort(std::begin(names), std::end(names)); 15 | std::for_each(std::begin(names), std::end(names), printText); 16 | } 17 | -------------------------------------------------------------------------------- /StrategyPattern/src/address.h: -------------------------------------------------------------------------------- 1 | #ifndef ADDRESS_H_ 2 | #define ADDRESS_H_ 3 | 4 | #include 5 | 6 | class Address 7 | { 8 | public: 9 | Address() = default; 10 | ~Address() = default; 11 | 12 | std::string getStreet() const { 13 | return street; 14 | } 15 | 16 | std::string getCity() const { 17 | return city; 18 | } 19 | 20 | std::string getZipCodeAsString() const { 21 | return std::to_string(zipCode); 22 | } 23 | 24 | void setStreet(std::string street) { 25 | this->street = street; 26 | } 27 | 28 | void setCity(std::string city) { 29 | this->city = city; 30 | } 31 | 32 | void setZipCode(int zipCode) { 33 | this->zipCode = zipCode; 34 | } 35 | 36 | private: 37 | std::string street; 38 | std::string city; 39 | int zipCode {0}; 40 | }; 41 | 42 | #endif /* ADDRESS_H_ */ 43 | -------------------------------------------------------------------------------- /StrategyPattern/src/customer.cpp: -------------------------------------------------------------------------------- 1 | #include "customer.h" 2 | 3 | Customer::Customer(CustomerId customerId, std::string forename, std::string surname, Address address) 4 | : customerId(customerId) 5 | , forename(forename) 6 | , surname(surname) 7 | , address(address) 8 | {} 9 | 10 | std::string Customer::getAsFormattedString(const FormatterPtr& formatter) const 11 | { 12 | std::string street = address.getStreet(); 13 | std::string zipCode = address.getZipCodeAsString(); 14 | std::string city = address.getCity(); 15 | 16 | return formatter-> 17 | withCustomerId(customerId.toString()). 18 | withForename(forename). 19 | withSurname(surname). 20 | withStreet(street). 21 | withZipCode(zipCode). 22 | withCity(city). 23 | format(); 24 | } 25 | -------------------------------------------------------------------------------- /StrategyPattern/src/customer.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMER_H_ 2 | #define CUSTOMER_H_ 3 | 4 | #include 5 | #include "customerid.h" 6 | #include "address.h" 7 | #include "formatter.h" 8 | 9 | class Customer 10 | { 11 | public: 12 | Customer(CustomerId customerId, std::string forename, std::string surname, Address address); 13 | 14 | std::string getAsFormattedString(const FormatterPtr& formatter) const; 15 | 16 | private: 17 | CustomerId customerId; 18 | std::string forename; 19 | std::string surname; 20 | Address address; 21 | }; 22 | 23 | #endif /* CUSTOMER_H_ */ 24 | -------------------------------------------------------------------------------- /StrategyPattern/src/customerid.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMERID_H_ 2 | #define CUSTOMERID_H_ 3 | 4 | #include 5 | 6 | class CustomerId 7 | { 8 | public: 9 | CustomerId(int id): id(id) {} 10 | 11 | int getId() const { 12 | return id; 13 | } 14 | 15 | std::string toString() const { 16 | const int numberOfZeros = 5; 17 | std::string strId = std::string(numberOfZeros, '0').append(std::to_string(id)); 18 | return strId; 19 | } 20 | 21 | private: 22 | int id; 23 | }; 24 | 25 | #endif /* CUSTOMERID_H_ */ 26 | -------------------------------------------------------------------------------- /StrategyPattern/src/formatter.cpp: -------------------------------------------------------------------------------- 1 | #include "formatter.h" 2 | 3 | Formatter& Formatter::withCustomerId(std::string_view customerId) 4 | { 5 | this->customerId = customerId; 6 | return *this; 7 | } 8 | 9 | Formatter& Formatter::withForename(std::string_view forename) 10 | { 11 | this->forename = forename; 12 | return *this; 13 | } 14 | 15 | Formatter& Formatter::withSurname(std::string_view surname) 16 | { 17 | this->surname = surname; 18 | return *this; 19 | } 20 | 21 | Formatter& Formatter::withStreet(std::string_view street) 22 | { 23 | this->street = street; 24 | return *this; 25 | } 26 | 27 | Formatter& Formatter::withZipCode(std::string_view zipCode) 28 | { 29 | this->zipCode = zipCode; 30 | return *this; 31 | } 32 | 33 | Formatter& Formatter::withCity(std::string_view city) 34 | { 35 | this->city = city; 36 | return *this; 37 | } 38 | -------------------------------------------------------------------------------- /StrategyPattern/src/formatter.h: -------------------------------------------------------------------------------- 1 | #ifndef FORMATTER_H_ 2 | #define FORMATTER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Formatter 10 | { 11 | public: 12 | virtual ~Formatter() = default; 13 | 14 | Formatter& withCustomerId(std::string_view customerId); 15 | Formatter& withForename(std::string_view forename); 16 | Formatter& withSurname(std::string_view surname); 17 | Formatter& withStreet(std::string_view street); 18 | Formatter& withZipCode(std::string_view zipCode); 19 | Formatter& withCity(std::string_view city); 20 | 21 | virtual std::string format() const = 0; 22 | 23 | protected: 24 | std::string customerId {"000000"}; 25 | std::string forename {"n/a"}; 26 | std::string surname {"n/a"}; 27 | std::string street {"n/a"}; 28 | std::string zipCode {"n/a"}; 29 | std::string city {"n/a"}; 30 | }; 31 | 32 | using FormatterPtr = std::unique_ptr; 33 | 34 | #endif /* FORMATTER_H_ */ 35 | -------------------------------------------------------------------------------- /StrategyPattern/src/jsonformatter.cpp: -------------------------------------------------------------------------------- 1 | #include "jsonformatter.h" 2 | #include 3 | 4 | // REF: 5 | // https://github.com/nlohmann/json 6 | 7 | std::string JsonFormatter::format() const 8 | { 9 | using json = nlohmann::json; 10 | 11 | json doc; 12 | doc["customer_id"] = customerId; 13 | doc["forename"] = forename; 14 | doc["surname"] = surname; 15 | doc["street"] = street; 16 | doc["zipCode"] = zipCode; 17 | doc["city"] = city; 18 | 19 | return doc.dump(4); 20 | } 21 | -------------------------------------------------------------------------------- /StrategyPattern/src/jsonformatter.h: -------------------------------------------------------------------------------- 1 | #ifndef JSONFORMATTER_H_ 2 | #define JSONFORMATTER_H_ 3 | 4 | #include "formatter.h" 5 | 6 | class JsonFormatter : public Formatter 7 | { 8 | public: 9 | virtual std::string format() const override; 10 | }; 11 | 12 | #endif /* JSONFORMATTER_H_ */ 13 | -------------------------------------------------------------------------------- /StrategyPattern/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "customer.h" 4 | #include "address.h" 5 | #include "plaintextformatter.h" 6 | #include "xmlformatter.h" 7 | #include "jsonformatter.h" 8 | 9 | int main() 10 | { 11 | Address address1; 12 | address1.setStreet("123 Maple Lane"); 13 | address1.setCity("Atlanta"); 14 | address1.setZipCode(30338); 15 | Customer c1(CustomerId(1), "Bill", "Smith", address1); 16 | 17 | auto textFormatter = std::make_unique(); 18 | std::cout << c1.getAsFormattedString(std::move(textFormatter)) << std::endl; 19 | 20 | auto xmlFormatter = std::make_unique(); 21 | std::cout << c1.getAsFormattedString(std::move(xmlFormatter)) << std::endl; 22 | 23 | auto jsonFormatter = std::make_unique(); 24 | std::cout << c1.getAsFormattedString(std::move(jsonFormatter)) << std::endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /StrategyPattern/src/plaintextformatter.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAINTEXTFORMATTER_H_ 2 | #define PLAINTEXTFORMATTER_H_ 3 | 4 | #include "formatter.h" 5 | 6 | class PlainTextFormatter : public Formatter 7 | { 8 | public: 9 | virtual std::string format() const override { 10 | std::stringstream formattedString; 11 | formattedString << "[" << customerId << "]: " 12 | << forename << " " << surname << ", " 13 | << street << ", " << zipCode << " " 14 | << city << "."; 15 | return formattedString.str(); 16 | } 17 | }; 18 | 19 | #endif /* PLAINTEXTFORMATTER_H_ */ 20 | -------------------------------------------------------------------------------- /StrategyPattern/src/xmlformatter.h: -------------------------------------------------------------------------------- 1 | #ifndef XMLFORMATTER_H_ 2 | #define XMLFORMATTER_H_ 3 | 4 | #include "formatter.h" 5 | 6 | class XmlFormatter : public Formatter 7 | { 8 | public: 9 | virtual std::string format() const override { 10 | std::stringstream formattedString; 11 | formattedString << "" << std::endl 12 | << " " << forename << "" << std::endl 13 | << " " << surname << "" << std::endl 14 | << " " << street << "" << std::endl 15 | << " " << zipCode << "" << std::endl 16 | << " " << city << "" << std::endl 17 | << "" << std::endl; 18 | return formattedString.str(); 19 | } 20 | }; 21 | 22 | #endif /* XMLFORMATTER_H_ */ 23 | -------------------------------------------------------------------------------- /Switch/src/lamp.h: -------------------------------------------------------------------------------- 1 | #ifndef LAMP_H_ 2 | #define LAMP_H_ 3 | 4 | #include "switchable.h" 5 | #include 6 | 7 | class Lamp : public Switchable 8 | { 9 | public: 10 | Lamp() = default; 11 | ~Lamp() = default; 12 | 13 | void on() override 14 | { 15 | std::cout << "Lamp is ON" << std::endl; 16 | } 17 | 18 | void off() override 19 | { 20 | std::cout << "Lamp is OFF" << std::endl; 21 | } 22 | }; 23 | 24 | #endif /* LAMP_H_ */ 25 | -------------------------------------------------------------------------------- /Switch/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "switch.h" 3 | #include "lamp.h" 4 | 5 | int main() 6 | { 7 | Lamp lamp; 8 | 9 | Switch s(lamp); 10 | s.toggle(); 11 | s.toggle(); 12 | } 13 | -------------------------------------------------------------------------------- /Switch/src/switch.cpp: -------------------------------------------------------------------------------- 1 | #include "switch.h" 2 | 3 | Switch::Switch(Switchable& switchable) 4 | : switchable(switchable) 5 | , state(false) 6 | { 7 | // empty body 8 | } 9 | 10 | void Switch::toggle() 11 | { 12 | if (state) 13 | { 14 | state = false; 15 | switchable.off(); 16 | } 17 | else 18 | { 19 | state = true; 20 | switchable.on(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Switch/src/switch.h: -------------------------------------------------------------------------------- 1 | #ifndef SWITCH_H_ 2 | #define SWITCH_H_ 3 | 4 | #include "switchable.h" 5 | 6 | class Switch 7 | { 8 | public: 9 | Switch(Switchable& switchable); 10 | ~Switch() = default; 11 | 12 | void toggle(); 13 | 14 | private: 15 | Switchable& switchable; 16 | bool state; 17 | }; 18 | 19 | #endif /* SWITCH_H_ */ 20 | -------------------------------------------------------------------------------- /Switch/src/switchable.h: -------------------------------------------------------------------------------- 1 | #ifndef SWITCHABLE_H_ 2 | #define SWITCHABLE_H_ 3 | 4 | class Switchable 5 | { 6 | public: 7 | virtual ~Switchable() = default; 8 | virtual void on() = 0; 9 | virtual void off() = 0; 10 | }; 11 | 12 | #endif /* SWITCHABLE_H_ */ 13 | --------------------------------------------------------------------------------