diff --git a/include/ExampleRegistry.h b/include/ExampleRegistry.h new file mode 100644 index 0000000..7945e4d --- /dev/null +++ b/include/ExampleRegistry.h @@ -0,0 +1,43 @@ +#pragma once +#include +#include +#include +#include "IExample.h" + +#define REGISTER_EXAMPLE(CLASS, GROUP, NAME) \ + namespace { \ + struct CLASS##Registrar { \ + CLASS##Registrar() { \ + ExampleRegistry::instance().registerExample( \ + GROUP, NAME, []() { return std::make_unique(); }); \ + } \ + }; \ + static CLASS##Registrar global_##CLASS##Registrar; \ + } + +class ExampleRegistry { + public: + using Factory = std::function()>; + + static ExampleRegistry& instance() { + static ExampleRegistry inst; + return inst; + } + + void registerExample(const std::string& group, const std::string& name, + Factory factory) { + registry_[group][name] = std::move(factory); + } + + const auto& getAll() const { return registry_; } + + std::unique_ptr create(const std::string& group, + const std::string& name) { + + return registry_.at(group).at(name)(); + } + + private: + std::unordered_map> + registry_; +}; diff --git a/include/IExample.h b/include/IExample.h new file mode 100644 index 0000000..eeaf027 --- /dev/null +++ b/include/IExample.h @@ -0,0 +1,12 @@ +#pragma once +#include +class IExample { + public: + virtual ~IExample() = default; + + virtual std::string group() const = 0; + virtual std::string name() const = 0; + virtual std::string description() const = 0; + + virtual void execute() = 0; +}; \ No newline at end of file diff --git a/src/controller/pid/PIDSim.cpp b/src/controller/pid/PIDSim.cpp index f037fe5..c54f970 100644 --- a/src/controller/pid/PIDSim.cpp +++ b/src/controller/pid/PIDSim.cpp @@ -1,6 +1,9 @@ #include #include "pid.h" +#include "ExampleRegistry.h" +#include "IExample.h" + namespace { void run() { PID pid = PID(0.1, 100, -100, 0.1, 0.01, 0.5); @@ -15,8 +18,12 @@ void run() { } } // namespace -struct PIDSimRunner { - PIDSimRunner() { run(); } +class PIDSim : public IExample { + public: + std::string group() const override { return "controller"; } + std::string name() const override { return "PIDSim"; } + std::string description() const override { return "PID example"; } + void execute() override { run(); } }; -static PIDSimRunner autoRunner; +REGISTER_EXAMPLE(PIDSim, "controller", "PIDSim"); diff --git a/src/core/basics/ControlFlow.cpp b/src/core/basics/ControlFlow.cpp index 8e67935..8a57328 100644 --- a/src/core/basics/ControlFlow.cpp +++ b/src/core/basics/ControlFlow.cpp @@ -116,12 +116,15 @@ void exceptions() { } } -// A struct that runs code when its object is created -struct ControlFlow { - ControlFlow() { - cout << "\n" - << "\n" - << "ControlFlow\n"; +#include "ExampleRegistry.h" +#include "IExample.h" + +class ControlFlow : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "ControlFlow"; } + std::string description() const override { return "ControlFlow"; } + void execute() override { conditionals(); jumps(); functionCalls(); @@ -131,5 +134,4 @@ struct ControlFlow { } }; -// All global and static objects are constructed before main() begins. -static ControlFlow autoRunInstance; +REGISTER_EXAMPLE(ControlFlow, "core", "ControlFlow"); diff --git a/src/core/basics/InitializeVariable.cpp b/src/core/basics/InitializeVariable.cpp index af15399..4410afd 100644 --- a/src/core/basics/InitializeVariable.cpp +++ b/src/core/basics/InitializeVariable.cpp @@ -1,20 +1,20 @@ #include using namespace std; +#include "ExampleRegistry.h" +#include "IExample.h" + void initialize_variable(); -// A struct that runs code when its object is created -struct InitializeVariable { - InitializeVariable() { - cout << "\n" - << "\n" - << "InitializeVariable\n"; - initialize_variable(); - } +class InitializeVariable : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "InitializeVariable"; } + std::string description() const override { return "InitializeVariable"; } + void execute() override { initialize_variable(); } }; -// All global and static objects are constructed before main() begins. -static InitializeVariable autoRunInstance; +REGISTER_EXAMPLE(InitializeVariable, "core", "InitializeVariable"); struct Foo { Foo() { cout << "Default constructor/ default init\n"; } diff --git a/src/core/basics/Operations.cpp b/src/core/basics/Operations.cpp index f86009b..d123057 100644 --- a/src/core/basics/Operations.cpp +++ b/src/core/basics/Operations.cpp @@ -1,22 +1,26 @@ #include using namespace std; +#include "ExampleRegistry.h" +#include "IExample.h" + void arithmeticOperator(); void logicalOperator(); void bitWiseOperator(); -struct Operations { - Operations() { - cout << "\n" - << "\n" - << "Operation\n"; +class Operations : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Operations"; } + std::string description() const override { return "Operation"; } + void execute() override { arithmeticOperator(); logicalOperator(); bitWiseOperator(); } }; -static Operations autoRunInstance; +REGISTER_EXAMPLE(Operations, "core", "Operations"); void arithmeticOperator() { cout << "\n--- ArithmeticOperator Examples ---\n"; @@ -94,33 +98,32 @@ void logicalOperator() { void bitWiseOperator() { cout << "\n--- BitWiseOperator Examples ---\n"; bitset<8> bitsA { - 0b1111'1111}; bitset<8> bitsB { - 0b1111'0000}; + 0b1111'1111}; bitset<8> bitsB { 0b1111'0000}; - cout - << "bitA = " << bitsA << ", bitB = " << bitsB << "\n"; + cout + << "bitA = " << bitsA << ", bitB = " << bitsB << "\n"; - // AND - bitset<8> result = bitsA & bitsB; - cout << "bitA && bitB= " << result << "\n"; + // AND + bitset<8> result = bitsA & bitsB; + cout << "bitA && bitB= " << result << "\n"; - // OR - result = bitsA | bitsB; - cout << "bitA | bitB= " << result << "\n"; + // OR + result = bitsA | bitsB; + cout << "bitA | bitB= " << result << "\n"; - // XOR - result = bitsA ^ bitsB; - cout << "bitA ^ bitB= " << result << "\n"; + // XOR + result = bitsA ^ bitsB; + cout << "bitA ^ bitB= " << result << "\n"; - // NOT - result = ~bitsA; - cout << "~bitA = " << result << "\n"; + // NOT + result = ~bitsA; + cout << "~bitA = " << result << "\n"; - // LEFT SHIFT - result = bitsA << 1; - cout << "bitA << 1 = " << result << "\n"; + // LEFT SHIFT + result = bitsA << 1; + cout << "bitA << 1 = " << result << "\n"; - // RIGHT SHIFT - result = bitsA >> 1; - cout << "bitA >> 1 = " << result << "\n"; - } \ No newline at end of file + // RIGHT SHIFT + result = bitsA >> 1; + cout << "bitA >> 1 = " << result << "\n"; + } \ No newline at end of file diff --git a/src/core/basics/TypeQualifier.cpp b/src/core/basics/TypeQualifier.cpp index d8fbdbc..95507d8 100644 --- a/src/core/basics/TypeQualifier.cpp +++ b/src/core/basics/TypeQualifier.cpp @@ -30,13 +30,15 @@ void run() { } // namespace -struct TypeQualifier { - TypeQualifier() { - cout << "\n" - << "\n" - << "TypeQualifier\n"; - Constant::run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class TypeQualifier : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "TypeQualifier"; } + std::string description() const override { return "TypeQualifier"; } + void execute() override { Constant::run(); } }; -static TypeQualifier autoRunInstance; +REGISTER_EXAMPLE(TypeQualifier, "core", "TypeQualifier"); diff --git a/src/core/datatypes/CArray.cpp b/src/core/datatypes/CArray.cpp index aff4ebc..3af858c 100644 --- a/src/core/datatypes/CArray.cpp +++ b/src/core/datatypes/CArray.cpp @@ -1,5 +1,8 @@ #include +#include "ExampleRegistry.h" +#include "IExample.h" + void arrayExamples() { std::cout << "\n--- Array Examples ---\n"; @@ -17,8 +20,12 @@ void arrayExamples() { } } -struct CArray { - CArray() { arrayExamples(); } +class CArray : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CArray"; } + std::string description() const override { return ""; } + void execute() override { arrayExamples(); } }; -static CArray autoRunArray; +REGISTER_EXAMPLE(CArray, "core", "CArray"); diff --git a/src/core/datatypes/CEnum.cpp b/src/core/datatypes/CEnum.cpp index aef51f5..13aca53 100644 --- a/src/core/datatypes/CEnum.cpp +++ b/src/core/datatypes/CEnum.cpp @@ -39,16 +39,15 @@ void enums() { [[maybe_unused]] ScopeEnumClassB st = ScopeEnumClassB::enumratorA; } -// A struct that runs code when its object is created -struct CEnum { - CEnum() { - cout << "\n" - << "\n" - << "Compound type: Enum\n"; - - enums(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class CEnum : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CEnum"; } + std::string description() const override { return "Compound type: Enum"; } + void execute() override { enums(); } }; -// All global and static objects are constructed before main() begins. -static CEnum autoRunInstance; +REGISTER_EXAMPLE(CEnum, "core", "CEnum"); diff --git a/src/core/datatypes/CPointers.cpp b/src/core/datatypes/CPointers.cpp index 114add5..1890898 100644 --- a/src/core/datatypes/CPointers.cpp +++ b/src/core/datatypes/CPointers.cpp @@ -103,16 +103,15 @@ void pointers() { std::cout << "By ptr: " << *b_ptr << '\n'; } -// A struct that runs code when its object is created -struct CPointers { - CPointers() { - cout << "\n" - << "\n" - << "Compound type: Pointers\n"; - - pointers(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class CPointers : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CPointers"; } + std::string description() const override { return "Compound type: Pointers"; } + void execute() override { pointers(); } }; -// All global and static objects are constructed before main() begins. -static CPointers autoRunInstance; +REGISTER_EXAMPLE(CPointers, "core", "CPointers"); diff --git a/src/core/datatypes/CReferences.cpp b/src/core/datatypes/CReferences.cpp index 83e6bbd..f8e044d 100644 --- a/src/core/datatypes/CReferences.cpp +++ b/src/core/datatypes/CReferences.cpp @@ -82,17 +82,20 @@ void run() { } // namespace RvalueReference -// A struct that runs code when its object is created -struct CReferences { - CReferences() { - cout << "\n" - << "\n" - << "Compound type: References\n"; - +#include "ExampleRegistry.h" +#include "IExample.h" + +class CReferences : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CReferences"; } + std::string description() const override { + return "Compound type: References"; + } + void execute() override { references(); RvalueReference::run(); } }; -// All global and static objects are constructed before main() begins. -static CReferences autoRunInstance; +REGISTER_EXAMPLE(CReferences, "core", "CReferences"); diff --git a/src/core/datatypes/CStruct.cpp b/src/core/datatypes/CStruct.cpp index f18eb7b..b181fb7 100644 --- a/src/core/datatypes/CStruct.cpp +++ b/src/core/datatypes/CStruct.cpp @@ -61,16 +61,15 @@ void structs() { s2.print(); } -// A struct that runs code when its object is created -struct CStruct { - CStruct() { - cout << "\n" - << "\n" - << "Compound type: Struct\n"; +#include "ExampleRegistry.h" +#include "IExample.h" - structs(); - } +class CStruct : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CStruct"; } + std::string description() const override { return "Compound type: Struct"; } + void execute() override { structs(); } }; -// All global and static objects are constructed before main() begins. -static CStruct autoRunInstance; +REGISTER_EXAMPLE(CStruct, "core", "CStruct"); diff --git a/src/core/datatypes/CUnion.cpp b/src/core/datatypes/CUnion.cpp index 022c4c1..7874094 100644 --- a/src/core/datatypes/CUnion.cpp +++ b/src/core/datatypes/CUnion.cpp @@ -37,12 +37,15 @@ void unionDemo() { } // --- Auto-run struct --- -struct CUnion { - CUnion() { - std::cout << "\nCompound type: Union\n"; - unionDemo(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class CUnion : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CUnion"; } + std::string description() const override { return "Compound type: Union"; } + void execute() override { unionDemo(); } }; -// Constructed before main() -static CUnion autoRunUnionInstance; \ No newline at end of file +REGISTER_EXAMPLE(CUnion, "core", "CUnion"); \ No newline at end of file diff --git a/src/core/datatypes/Fundamental.cpp b/src/core/datatypes/Fundamental.cpp index fc5c7e4..919cdf5 100644 --- a/src/core/datatypes/Fundamental.cpp +++ b/src/core/datatypes/Fundamental.cpp @@ -50,16 +50,15 @@ void primative() { cout << "nullptr_t: " << ptr << "\n"; } -// A struct that runs code when its object is created -struct Fundamental { - Fundamental() { - cout << "\n" - << "\n" - << "Fundamental\n"; +#include "ExampleRegistry.h" +#include "IExample.h" - primative(); - } +class Fundamental : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Fundamental"; } + std::string description() const override { return "Fundamental"; } + void execute() override { primative(); } }; -// All global and static objects are constructed before main() begins. -static Fundamental autoRunInstance; +REGISTER_EXAMPLE(Fundamental, "core", "Fundamental"); diff --git a/src/core/datatypes/TypeConVersions.cpp b/src/core/datatypes/TypeConVersions.cpp index 0706aa8..1d2a6d2 100644 --- a/src/core/datatypes/TypeConVersions.cpp +++ b/src/core/datatypes/TypeConVersions.cpp @@ -144,8 +144,15 @@ void typeDeduction() { cout << "common_type: " << val << "\n"; } -struct CTypeConversion { - CTypeConversion() { +#include "ExampleRegistry.h" +#include "IExample.h" + +class CTypeConversion : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CTypeConversion"; } + std::string description() const override { return ""; } + void execute() override { implicitConversion(); explicitConversion(); @@ -154,4 +161,4 @@ struct CTypeConversion { } }; -static CTypeConversion autoRunTypes; \ No newline at end of file +REGISTER_EXAMPLE(CTypeConversion, "core", "CTypeConversion"); \ No newline at end of file diff --git a/src/core/datatypes/class/CConstructors.cpp b/src/core/datatypes/class/CConstructors.cpp index b119d30..ce0841d 100644 --- a/src/core/datatypes/class/CConstructors.cpp +++ b/src/core/datatypes/class/CConstructors.cpp @@ -302,8 +302,15 @@ void constructers() { } } // namespace Move -struct CConstructorsAutoRunner { - CConstructorsAutoRunner() { +#include "ExampleRegistry.h" +#include "IExample.h" + +class CConstructors : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CConstructors"; } + std::string description() const override { return ""; } + void execute() override { InitializerList::constructers(); Default::constructers(); Delegate::constructors(); @@ -312,4 +319,4 @@ struct CConstructorsAutoRunner { } }; -static CConstructorsAutoRunner instance; +REGISTER_EXAMPLE(CConstructors, "core", "CConstructors"); diff --git a/src/core/datatypes/class/CDestructors.cpp b/src/core/datatypes/class/CDestructors.cpp index 1e3a651..15ce8b9 100644 --- a/src/core/datatypes/class/CDestructors.cpp +++ b/src/core/datatypes/class/CDestructors.cpp @@ -57,11 +57,18 @@ void destructers() { } } // namespace Virtual -struct CDestructorsAutoRunner { - CDestructorsAutoRunner() { +#include "ExampleRegistry.h" +#include "IExample.h" + +class CDestructors : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CDestructors"; } + std::string description() const override { return ""; } + void execute() override { Basic::destructers(); Virtual::destructers(); } }; -static CDestructorsAutoRunner instance; +REGISTER_EXAMPLE(CDestructors, "core", "CDestructors"); diff --git a/src/core/datatypes/class/RoleOfThreeFiveZero.cpp b/src/core/datatypes/class/RoleOfThreeFiveZero.cpp index 9ba2a93..9e4e96d 100644 --- a/src/core/datatypes/class/RoleOfThreeFiveZero.cpp +++ b/src/core/datatypes/class/RoleOfThreeFiveZero.cpp @@ -171,7 +171,7 @@ class Model { // noexcept is a specifier that indicates a function will not throw // exceptions. Model(Model&& other) noexcept - : cstring(std::exchange(other.cstring, nullptr)) {}; + : cstring(std::exchange(other.cstring, nullptr)){}; // V. move assignment Model& operator=(Model&& other) noexcept { @@ -271,9 +271,16 @@ void run() { } } // namespace RoleOfZero } // namespace -struct RoleOfThreeFiveZeroAutoRunner { - // Virtual default destructor: Does not break Rule of Three, Five, or Zero - RoleOfThreeFiveZeroAutoRunner() { + +#include "ExampleRegistry.h" +#include "IExample.h" + +class RoleOfThreeFiveZero : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "RoleOfThreeFiveZero"; } + std::string description() const override { return ""; } + void execute() override { Problem::run(); RoleOfThree::run(); RoleOfFive::run(); @@ -281,4 +288,4 @@ struct RoleOfThreeFiveZeroAutoRunner { } }; -static RoleOfThreeFiveZeroAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(RoleOfThreeFiveZero, "core", "RoleOfThreeFiveZero"); \ No newline at end of file diff --git a/src/core/datatypes/class/SallowDeepCopying.cpp b/src/core/datatypes/class/SallowDeepCopying.cpp index b89e2ef..845d05b 100644 --- a/src/core/datatypes/class/SallowDeepCopying.cpp +++ b/src/core/datatypes/class/SallowDeepCopying.cpp @@ -151,11 +151,18 @@ void run() { } // namespace DeepCopying } // namespace -struct ShallowDeepCopying { - ShallowDeepCopying() { +#include "ExampleRegistry.h" +#include "IExample.h" + +class ShallowDeepCopying : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "ShallowDeepCopying"; } + std::string description() const override { return ""; } + void execute() override { Shallow::run(); DeepCopying::run(); } }; -static ShallowDeepCopying instance; \ No newline at end of file +REGISTER_EXAMPLE(ShallowDeepCopying, "core", "ShallowDeepCopying"); \ No newline at end of file diff --git a/src/core/datatypes/container/adapter/Queue.cpp b/src/core/datatypes/container/adapter/Queue.cpp index 9b97966..da6fcbb 100644 --- a/src/core/datatypes/container/adapter/Queue.cpp +++ b/src/core/datatypes/container/adapter/Queue.cpp @@ -42,11 +42,15 @@ void run() { } } // namespace -struct QueueRunner { - QueueRunner() { - std::cout << "\n--- std::queue Example ---\n"; - run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Queue : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Queue"; } + std::string description() const override { return "std::queue Example"; } + void execute() override { run(); } }; -static QueueRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Queue, "core", "Queue"); \ No newline at end of file diff --git a/src/core/datatypes/container/adapter/Stack.cpp b/src/core/datatypes/container/adapter/Stack.cpp index ea254fc..f40be12 100644 --- a/src/core/datatypes/container/adapter/Stack.cpp +++ b/src/core/datatypes/container/adapter/Stack.cpp @@ -41,11 +41,15 @@ void run() { } } // namespace -struct StackRunner { - StackRunner() { - std::cout << "\n--- std::stack Example ---\n"; - run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Stack : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Stack"; } + std::string description() const override { return "std::stack Example"; } + void execute() override { run(); } }; -static StackRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Stack, "core", "Stack"); \ No newline at end of file diff --git a/src/core/datatypes/container/sequence/Array.cpp b/src/core/datatypes/container/sequence/Array.cpp index a267444..dd93c7e 100644 --- a/src/core/datatypes/container/sequence/Array.cpp +++ b/src/core/datatypes/container/sequence/Array.cpp @@ -10,8 +10,8 @@ #include namespace { -void example() { - std::cout << "\n--- std::array Example ---\n"; +void run() { + std::cout << "\n--- std::array Example ---\n"; // 1) Init std::array m_array = {9, 100, 0}; // m_array = {1,2,3,5,6}; // ERROR @@ -69,13 +69,20 @@ void example() { board.fill({0xE2, 0x96, 0x84, 0xE2, 0x96, 0x80, 0, 0}); // "▄▀"; // fill means fill all 16 Cell with "▄▀" // board = {Cell{0xE2, 0x96, 0x84, 0xE2, 0x96, 0x80, 0, 0},Cell{0xE2, 0x96, 0x84, 0xE2, 0x96, 0x80, 0, 0}}; - for (std::size_t count{}; Cell c : board) + for (size_t count{}; Cell c : board) std::cout << c.data() << ((++count % xy) ? "" : "\n"); } } // namespace -struct ArrayRunner { - ArrayRunner() { example(); } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Array : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Array"; } + std::string description() const override { return ""; } + void execute() override { run(); } }; -static ArrayRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Array, "core", "Array"); \ No newline at end of file diff --git a/src/core/datatypes/container/sequence/Deque.cpp b/src/core/datatypes/container/sequence/Deque.cpp index eb4d3f1..e9dc4cf 100644 --- a/src/core/datatypes/container/sequence/Deque.cpp +++ b/src/core/datatypes/container/sequence/Deque.cpp @@ -35,11 +35,15 @@ void run() { } } // namespace -struct DequeRunner { - DequeRunner() { - std::cout << "\n--- std::deque Example ---\n"; - run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Deque : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Deque"; } + std::string description() const override { return "std::deque Example"; } + void execute() override { run(); } }; -static DequeRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Deque, "core", "Deque"); \ No newline at end of file diff --git a/src/core/datatypes/container/sequence/Vector.cpp b/src/core/datatypes/container/sequence/Vector.cpp index deb663f..fc8c2b3 100644 --- a/src/core/datatypes/container/sequence/Vector.cpp +++ b/src/core/datatypes/container/sequence/Vector.cpp @@ -10,7 +10,7 @@ #include // for std::vector namespace { -void example() { +void run() { std::cout << "\n--- std::vector Example ---\n"; // 1) Init std::vector m_vec = {9, 100, 0}; @@ -47,8 +47,15 @@ void example() { } } // namespace -struct VectorRunner { - VectorRunner() { example(); } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Vector : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Vector"; } + std::string description() const override { return ""; } + void execute() override { run(); } }; -static VectorRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Vector, "core", "Vector"); \ No newline at end of file diff --git a/src/core/datatypes/container/unordered/UnorderedMap.cpp b/src/core/datatypes/container/unordered/UnorderedMap.cpp index 8e9b975..855403a 100644 --- a/src/core/datatypes/container/unordered/UnorderedMap.cpp +++ b/src/core/datatypes/container/unordered/UnorderedMap.cpp @@ -12,7 +12,7 @@ #include namespace { -void example() { +void run() { std::cout << "\n--- std::unordered_map Example ---\n"; // 1) Init std::unordered_map m_map{ @@ -69,8 +69,15 @@ void example() { } } // namespace -struct UnorderedMap { - UnorderedMap() { example(); } +#include "ExampleRegistry.h" +#include "IExample.h" + +class UnorderedMap : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "UnorderedMap"; } + std::string description() const override { return ""; } + void execute() override { run(); } }; -static UnorderedMap autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(UnorderedMap, "core", "UnorderedMap"); \ No newline at end of file diff --git a/src/core/datatypes/smart_pointer/Shared.cpp b/src/core/datatypes/smart_pointer/Shared.cpp index 519a12f..6af1d4a 100644 --- a/src/core/datatypes/smart_pointer/Shared.cpp +++ b/src/core/datatypes/smart_pointer/Shared.cpp @@ -65,11 +65,15 @@ void run() { } // namespace -struct SharedRunner { - SharedRunner() { - std::cout << "\n--- Shared Pointer Example ---\n"; - run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Shared : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Shared"; } + std::string description() const override { return "Shared Pointer Example"; } + void execute() override { run(); } }; -static SharedRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Shared, "core", "Shared"); \ No newline at end of file diff --git a/src/core/datatypes/smart_pointer/Unique.cpp b/src/core/datatypes/smart_pointer/Unique.cpp index 0869713..6ec9179 100644 --- a/src/core/datatypes/smart_pointer/Unique.cpp +++ b/src/core/datatypes/smart_pointer/Unique.cpp @@ -53,11 +53,15 @@ void run() { } } // namespace -struct UniqueRunner { - UniqueRunner() { - std::cout << "\n--- Unique Pointer Example ---\n"; - run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Unique : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Unique"; } + std::string description() const override { return "Unique Pointer Example"; } + void execute() override { run(); } }; -static UniqueRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Unique, "core", "Unique"); \ No newline at end of file diff --git a/src/core/datatypes/smart_pointer/Weak.cpp b/src/core/datatypes/smart_pointer/Weak.cpp index 9f3f164..6980aec 100644 --- a/src/core/datatypes/smart_pointer/Weak.cpp +++ b/src/core/datatypes/smart_pointer/Weak.cpp @@ -46,11 +46,15 @@ void run() { * wp.expired() == false // at least one shared_ptr still owns it * wp.lock() != nullptr // same condition */ -struct WeakRunner { - WeakRunner() { - std::cout << "\n--- Weak Pointer Example ---\n"; - run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class Weak : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Weak"; } + std::string description() const override { return "Weak Pointer Example"; } + void execute() override { run(); } }; -static WeakRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Weak, "core", "Weak"); \ No newline at end of file diff --git a/src/core/exception/BasicHandle.cpp b/src/core/exception/BasicHandle.cpp index 0125541..ee6746a 100644 --- a/src/core/exception/BasicHandle.cpp +++ b/src/core/exception/BasicHandle.cpp @@ -23,11 +23,17 @@ void run() { } } // namespace -struct BasicHandleRunner { - BasicHandleRunner() { - std::cout << "\n--- Basic Expception Handle Example ---\n"; - run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class BasicHandle : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "BasicHandle"; } + std::string description() const override { + return "Basic Expception Handle Example"; } + void execute() override { run(); } }; -static BasicHandleRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(BasicHandle, "core", "BasicHandle"); \ No newline at end of file diff --git a/src/core/exception/ThrowNoexcept.cpp b/src/core/exception/ThrowNoexcept.cpp index fbfa0ca..ee3315e 100644 --- a/src/core/exception/ThrowNoexcept.cpp +++ b/src/core/exception/ThrowNoexcept.cpp @@ -34,11 +34,17 @@ void run() { } } // namespace -struct ThrowNoexceptRunner { - ThrowNoexceptRunner() { - std::cout << "\n--- Exception throw/noexcept Example ---\n"; - run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class ThrowNoexcept : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "ThrowNoexcept"; } + std::string description() const override { + return "Exception throw/noexcept Example"; } + void execute() override { run(); } }; -static ThrowNoexceptRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(ThrowNoexcept, "core", "ThrowNoexcept"); \ No newline at end of file diff --git a/src/core/expression/FunctionPointer.cpp b/src/core/expression/FunctionPointer.cpp index 800af7d..388b05f 100644 --- a/src/core/expression/FunctionPointer.cpp +++ b/src/core/expression/FunctionPointer.cpp @@ -30,8 +30,7 @@ void run() { std::cout << "Before sorting : \n"; f_print(vect); - std::cout << "Sorting in descending " - << "order \n"; + std::cout << "Sorting in descending " << "order \n"; // Use auto auto sortTypeAuto = increase; @@ -41,8 +40,7 @@ void run() { SortFcn sortTypePtr = decrease; f_print(vect); - std::cout << "Sorting with absolute " - << "value as parameter\n "; + std::cout << "Sorting with absolute " << "value as parameter\n "; std::sort(vect.begin(), vect.end(), sortTypePtr); for (auto i : vect) @@ -51,11 +49,17 @@ void run() { } } // namespace -struct FunctionPointer { - FunctionPointer() { - std::cout << "\n--- Function Pointer Example ---\n"; - run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class FunctionPointer : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "FunctionPointer"; } + std::string description() const override { + return "Function Pointer Example"; } + void execute() override { run(); } }; -static FunctionPointer autoRunner; +REGISTER_EXAMPLE(FunctionPointer, "core", "FunctionPointer"); diff --git a/src/core/expression/Lambda.cpp b/src/core/expression/Lambda.cpp index 0887de2..58bdb56 100644 --- a/src/core/expression/Lambda.cpp +++ b/src/core/expression/Lambda.cpp @@ -22,14 +22,12 @@ void run() { std::cout << "Before sorting : \n"; f_print(vect); - std::cout << "Sorting in descending " - << "order \n"; + std::cout << "Sorting in descending " << "order \n"; std::sort(vect.begin(), vect.end(), [](int a, int b) { return a > b; }); f_print(vect); - std::cout << "Sorting with absolute " - << "value as parameter\n "; + std::cout << "Sorting with absolute " << "value as parameter\n "; std::sort(vect.begin(), vect.end(), [](int a, int b) { return a < b; }); for (auto i : vect) @@ -38,11 +36,17 @@ void run() { } } // namespace -struct LambdaRunner { - LambdaRunner() { - std::cout << "\n--- Lambda Expression Example ---\n"; - run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class Lambda : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Lambda"; } + std::string description() const override { + return "Lambda Expression Example"; } + void execute() override { run(); } }; -static LambdaRunner autoRunner; +REGISTER_EXAMPLE(Lambda, "core", "Lambda"); diff --git a/src/core/expression/README.md b/src/core/expression/README.md index 7f443f9..b31d604 100644 --- a/src/core/expression/README.md +++ b/src/core/expression/README.md @@ -18,6 +18,8 @@ - `throw()`: (O) - `-> int`: (O) trailing-return-type - body +- `[](){ ... }`defines a lambda +- `[](){ ... }()` defines and immediately CALLS it ### 1.1 Capture Clause - It uses to introduce new variables in its body, specifics which vars are captured, and whether the capture is `by value[=]` or `by reference [&]`. diff --git a/src/core/filehandle/Directory.cpp b/src/core/filehandle/Directory.cpp index aa34ddf..08365f7 100644 --- a/src/core/filehandle/Directory.cpp +++ b/src/core/filehandle/Directory.cpp @@ -1,6 +1,10 @@ #include // for creating dir #include #include + +#include "ExampleRegistry.h" +#include "IExample.h" + namespace { void run() { std::filesystem::path path1{"p1"}; @@ -38,8 +42,12 @@ void run() { } } // namespace -struct DirectoryRunner { - DirectoryRunner() { run(); } +class Directory : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Directory"; } + std::string description() const override { return ""; } + void execute() override { run(); } }; -static DirectoryRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(Directory, "core", "Directory"); \ No newline at end of file diff --git a/src/core/filehandle/FileIO.cpp b/src/core/filehandle/FileIO.cpp index 9039640..8de57dd 100644 --- a/src/core/filehandle/FileIO.cpp +++ b/src/core/filehandle/FileIO.cpp @@ -106,8 +106,15 @@ void run() { } } // namespace -struct FileIO { - FileIO() { run(); } +#include "ExampleRegistry.h" +#include "IExample.h" + +class FileIO : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "FileIO"; } + std::string description() const override { return ""; } + void execute() override { run(); } }; -static FileIO autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(FileIO, "core", "FileIO"); \ No newline at end of file diff --git a/src/core/filehandle/IOStream.cpp b/src/core/filehandle/IOStream.cpp index d455a69..0a93afe 100644 --- a/src/core/filehandle/IOStream.cpp +++ b/src/core/filehandle/IOStream.cpp @@ -2,6 +2,9 @@ #include #include +#include "ExampleRegistry.h" +#include "IExample.h" + namespace { void run() { std::cout << "\n--- IO Streams Example ---\n"; @@ -28,8 +31,12 @@ void run() { } } // namespace -struct IOStreamRunner { - IOStreamRunner() { run(); } +class IOStream : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "IOStream"; } + std::string description() const override { return ""; } + void execute() override { run(); } }; -static IOStreamRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(IOStream, "core", "IOStream"); \ No newline at end of file diff --git a/src/core/filehandle/StringStream.cpp b/src/core/filehandle/StringStream.cpp index e435a49..e77b261 100644 --- a/src/core/filehandle/StringStream.cpp +++ b/src/core/filehandle/StringStream.cpp @@ -1,8 +1,12 @@ #include #include #include + +#include "ExampleRegistry.h" +#include "IExample.h" + namespace { -void run() { +void runStringStreamExample() { std::cout << "\n--- String Stream Example ---\n"; std::stringstream os{}; @@ -34,8 +38,12 @@ void run() { } } // namespace -struct StringStreamRunner { - StringStreamRunner() { run(); } +class StringStream : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "StringStream"; } + std::string description() const override { return ""; } + void execute() override { runStringStreamExample(); } }; -static StringStreamRunner autoRunner; \ No newline at end of file +REGISTER_EXAMPLE(StringStream, "core", "StringStream"); \ No newline at end of file diff --git a/src/core/linkage/Linkage.cpp b/src/core/linkage/Linkage.cpp index 318c10c..59ea4f4 100644 --- a/src/core/linkage/Linkage.cpp +++ b/src/core/linkage/Linkage.cpp @@ -38,14 +38,18 @@ void run() { } // namespace External -struct LinkageAutoRunner { - LinkageAutoRunner() { - cout << "\n" - << "\n" - << "Linkage\n"; +#include "ExampleRegistry.h" +#include "IExample.h" + +class Linkage : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Linkage"; } + std::string description() const override { return "Linkage"; } + void execute() override { Internal::run(); External::run(); } }; -static LinkageAutoRunner autoRunInstance; +REGISTER_EXAMPLE(Linkage, "core", "Linkage"); diff --git a/src/core/linkage/sharing/Sharing.cpp b/src/core/linkage/sharing/Sharing.cpp index 4d87257..0e3d4e7 100644 --- a/src/core/linkage/sharing/Sharing.cpp +++ b/src/core/linkage/sharing/Sharing.cpp @@ -24,16 +24,21 @@ void run() { } } // namespace InlineWay -struct SharingGlobalConstantsAcrossMultipleFilesngAutoRunner { - SharingGlobalConstantsAcrossMultipleFilesngAutoRunner() { - cout << "\n" - << "\n" - << "SharingGlobalConstantsAcrossMultipleFiles\n"; +#include "ExampleRegistry.h" +#include "IExample.h" +class Sharing : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "Sharing"; } + std::string description() const override { + return "SharingGlobalConstantsAcrossMultipleFiles"; + } + void execute() override { InternalWay::run(); // prefer 2 ExternalWay::run(); InlineWay::run(); // prefer 1 } }; -static SharingGlobalConstantsAcrossMultipleFilesngAutoRunner autoRunInstance; +REGISTER_EXAMPLE(Sharing, "core", "Sharing"); diff --git a/src/core/linkage/sharing/external/constants.cpp b/src/core/linkage/sharing/external/constants.cpp index 98ab92e..ef4e8b9 100644 --- a/src/core/linkage/sharing/external/constants.cpp +++ b/src/core/linkage/sharing/external/constants.cpp @@ -1,9 +1,9 @@ #include "constants.h" -namespace ExternalConstants -{ - // We use extern to ensure these have external linkage - extern constexpr double pi { 3.14159 }; - extern constexpr double avogadro { 6.0221413e23 }; - extern constexpr double myGravity { 9.2 }; // m/s^2 -- gravity is light on this planet -} +namespace ExternalConstants { +// We use extern to ensure these have external linkage +extern constexpr double pi{3.14159}; +extern constexpr double avogadro{6.0221413e23}; +extern constexpr double myGravity{ + 9.2}; // m/s^2 -- gravity is light on this planet +} // namespace ExternalConstants diff --git a/src/core/string/CString.cpp b/src/core/string/CString.cpp index 4b315e3..56d7029 100644 --- a/src/core/string/CString.cpp +++ b/src/core/string/CString.cpp @@ -191,10 +191,15 @@ void run() { } // namespace NumberConversion } // namespace -struct CStringAutoRunner { - CStringAutoRunner() { - std::cout << "\n--- C String Example ---\n"; - +#include "ExampleRegistry.h" +#include "IExample.h" + +class CString : public IExample { + public: + std::string group() const override { return "core"; } + std::string name() const override { return "CString"; } + std::string description() const override { return "C String Example"; } + void execute() override { InitializeString::run(); CopyString::run(); ConcatString::run(); @@ -205,4 +210,4 @@ struct CStringAutoRunner { } }; -static CStringAutoRunner instance; +REGISTER_EXAMPLE(CString, "core", "CString"); diff --git a/src/main.cpp b/src/main.cpp index abcc68a..199bc1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,102 @@ #include +#include +#include +#include +#include "ExampleRegistry.h" #include "version.h" +int readChoice() { + int x; + while (!(std::cin >> x)) { + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + std::cout << "Invalid input. Try again: "; + } + // Clear leftover newline from input buffer + std::cin.ignore(std::numeric_limits::max(), '\n'); + return x; +} + +void runMenu() { + ExampleRegistry& registry = ExampleRegistry::instance(); + const auto& data = registry.getAll(); + + while (true) { + std::cout << "\n========================================\n"; + std::cout << " CPP LAB - Examples Menu \n"; + std::cout << "========================================\n"; + + if (data.empty()) { + std::cout << "No examples registered.\n"; + return; + } + + // Group + int gIndex = 1; + std::vector groups; + + for (const auto& [group, _] : data) { + std::cout << gIndex++ << ". " << group << "\n"; + groups.push_back(group); + } + std::cout << "0. quit\n"; + std::cout << "----------------------------------------\n"; + std::cout << "Enter choice: "; + + int gChoice = readChoice(); + if (gChoice == 0) { + std::cout << "End\n"; + break; + } + + if (gChoice < 1 || gChoice > groups.size()) { + std::cout << "Invalid group choice\n"; + continue; + } + + try { + // Sub-group + const auto& selectedGroup = groups[gChoice - 1]; + const auto& examples = data.at(selectedGroup); + + int eIndex = 1; + std::vector names; + + for (const auto& [name, _] : examples) { + std::cout << eIndex++ << ". " << name << "\n"; + names.push_back(name); + } + std::cout << "0. back\n"; + std::cout << "----------------------------------------\n"; + std::cout << "Enter choice: "; + + int eChoice = readChoice(); + if (eChoice == 0) { + continue; + } + + if (eChoice < 1 || eChoice > names.size()) { + std::cout << "Invalid example choice\n"; + continue; + } + + auto example = registry.create(selectedGroup, names[eChoice - 1]); + if (example != nullptr) { + std::cout << "\n--- Running Example [" << example->name() << "] [" + << example->description() << "]---\n\n"; + example->execute(); + std::cout << "\n--- Finished ---\n"; + std::cout << "Press any key to continue ...\n"; + std::cin.get(); + } + } catch (std::out_of_range& e) { + std::cout << "\nError" << e.what(); + std::cout << "\nInvalid example. Try again.\n"; + } + } +} + int main(int argc, char* argv[]) { std::cout << std::endl; if (__cplusplus == 202302L) @@ -21,5 +116,6 @@ int main(int argc, char* argv[]) { std::cout << "\n"; std::cout << APP_NAME << " v" << APP_VERSION << std::endl; std::cout << APP_DESCRIPTION << std::endl; + runMenu(); return 0; } \ No newline at end of file diff --git a/src/patterns/behavioral/ChainOfCommand.cpp b/src/patterns/behavioral/ChainOfCommand.cpp index c206939..a359d61 100644 --- a/src/patterns/behavioral/ChainOfCommand.cpp +++ b/src/patterns/behavioral/ChainOfCommand.cpp @@ -134,11 +134,16 @@ void run() { } // namespace -struct CoRAutoRunner { - CoRAutoRunner() { - std::cout << "\n--- CoR Pattern Example ---\n"; - CoR::run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class ChainOfResponsibilityExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "ChainOfResponsibility"; } + std::string description() const override { return "CoR Pattern Example"; } + void execute() override { CoR::run(); } }; -static CoRAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(ChainOfResponsibilityExample, "patterns", + "ChainOfResponsibility"); \ No newline at end of file diff --git a/src/patterns/behavioral/Command.cpp b/src/patterns/behavioral/Command.cpp index 8c63e6a..dc73396 100644 --- a/src/patterns/behavioral/Command.cpp +++ b/src/patterns/behavioral/Command.cpp @@ -125,11 +125,15 @@ void run() { } // namespace Command } // namespace -struct CommandAutoRunner { - CommandAutoRunner() { - std::cout << "\n--- Command Pattern Example ---\n"; - Command::run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class CommandExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Command"; } + std::string description() const override { return "Command Pattern Example"; } + void execute() override { Command::run(); } }; -static CommandAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(CommandExample, "patterns", "Command"); \ No newline at end of file diff --git a/src/patterns/behavioral/Iterator.cpp b/src/patterns/behavioral/Iterator.cpp index 7e39d80..0222e69 100644 --- a/src/patterns/behavioral/Iterator.cpp +++ b/src/patterns/behavioral/Iterator.cpp @@ -196,11 +196,17 @@ void run() { } // namespace Iterator } // namespace -struct IteratorAutoRunner { - IteratorAutoRunner() { - std::cout << "\n--- Iterator Pattern Example ---\n"; - Iterator::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class IteratorExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Iterator"; } + std::string description() const override { + return "Iterator Pattern Example"; } + void execute() override { Iterator::run(); } }; -static IteratorAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(IteratorExample, "patterns", "Iterator"); \ No newline at end of file diff --git a/src/patterns/behavioral/Mediator.cpp b/src/patterns/behavioral/Mediator.cpp index c556480..ec28195 100644 --- a/src/patterns/behavioral/Mediator.cpp +++ b/src/patterns/behavioral/Mediator.cpp @@ -162,11 +162,17 @@ void run() { } // namespace Mediator } // namespace -struct MediatorAutoRunner { - MediatorAutoRunner() { - std::cout << "\n--- Mediator Pattern Example ---\n"; - Mediator::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class MediatorExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Mediator"; } + std::string description() const override { + return "Mediator Pattern Example"; } + void execute() override { Mediator::run(); } }; -static MediatorAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(MediatorExample, "patterns", "Mediator"); \ No newline at end of file diff --git a/src/patterns/behavioral/Memento.cpp b/src/patterns/behavioral/Memento.cpp index 265041d..6f378c2 100644 --- a/src/patterns/behavioral/Memento.cpp +++ b/src/patterns/behavioral/Memento.cpp @@ -191,11 +191,17 @@ void run() { } // namespace Memento } // namespace -struct MementoAutoRunner { - MementoAutoRunner() { - std::cout << "\n--- Memento Pattern Example ---\n"; - Memento::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class MementoExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Memento"; } + std::string description() const override { + return "Memento Pattern Example "; } + void execute() override { Memento::run(); } }; -static MementoAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(MementoExample, "patterns", "Memento"); \ No newline at end of file diff --git a/src/patterns/behavioral/Observer.cpp b/src/patterns/behavioral/Observer.cpp index 33b2dbd..cf8a62f 100644 --- a/src/patterns/behavioral/Observer.cpp +++ b/src/patterns/behavioral/Observer.cpp @@ -175,11 +175,17 @@ void run() { } // namespace Observer } // namespace -struct ObserverAutoRunner { - ObserverAutoRunner() { - std::cout << "\n--- Observer Pattern Example ---\n"; - Observer::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class ObserverExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Observer"; } + std::string description() const override { + return "Observer Pattern Example"; } + void execute() override { Observer::run(); } }; -static ObserverAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(ObserverExample, "patterns", "Observer"); \ No newline at end of file diff --git a/src/patterns/behavioral/State.cpp b/src/patterns/behavioral/State.cpp index 171f114..a507cd5 100644 --- a/src/patterns/behavioral/State.cpp +++ b/src/patterns/behavioral/State.cpp @@ -132,11 +132,15 @@ void run() { } // namespace State } // namespace -struct StateAutoRunner { - StateAutoRunner() { - std::cout << "\n--- State Pattern Example ---\n"; - State::run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class StateExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "State"; } + std::string description() const override { return "State Pattern Example"; } + void execute() override { State::run(); } }; -static StateAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(StateExample, "patterns", "State"); \ No newline at end of file diff --git a/src/patterns/behavioral/Strategy.cpp b/src/patterns/behavioral/Strategy.cpp index 12d08be..e9b7084 100644 --- a/src/patterns/behavioral/Strategy.cpp +++ b/src/patterns/behavioral/Strategy.cpp @@ -101,11 +101,17 @@ void run() { } // namespace Strategy } // namespace -struct StrategyAutoRunner { - StrategyAutoRunner() { - std::cout << "\n--- Strategy Pattern Example ---\n"; - Strategy::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class StrategyExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Strategy"; } + std::string description() const override { + return "Strategy Pattern Example"; } + void execute() override { Strategy::run(); } }; -static StrategyAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(StrategyExample, "patterns", "Strategy"); \ No newline at end of file diff --git a/src/patterns/behavioral/TemplateMethod.cpp b/src/patterns/behavioral/TemplateMethod.cpp index 4fda119..5ce9852 100644 --- a/src/patterns/behavioral/TemplateMethod.cpp +++ b/src/patterns/behavioral/TemplateMethod.cpp @@ -103,11 +103,17 @@ void run() { } // namespace TemplateMethod } // namespace -struct TemplateMethodAutoRunner { - TemplateMethodAutoRunner() { - std::cout << "\n--- TemplateMethod Pattern Example ---\n"; - TemplateMethod::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class TemplateMethodExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "TemplateMethod"; } + std::string description() const override { + return "TemplateMethod Pattern Example"; } + void execute() override { TemplateMethod::run(); } }; -static TemplateMethodAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(TemplateMethodExample, "patterns", "TemplateMethod"); \ No newline at end of file diff --git a/src/patterns/behavioral/Visitor.cpp b/src/patterns/behavioral/Visitor.cpp index 3170963..54aff44 100644 --- a/src/patterns/behavioral/Visitor.cpp +++ b/src/patterns/behavioral/Visitor.cpp @@ -236,11 +236,15 @@ void run() { } // namespace Visitor } // namespace -struct VisitorAutoRunner { - VisitorAutoRunner() { - std::cout << "\n--- Visitor Pattern Example ---\n"; - Visitor::run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class VisitorExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Visitor"; } + std::string description() const override { return "Visitor Pattern Example"; } + void execute() override { Visitor::run(); } }; -static VisitorAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(VisitorExample, "patterns", "Visitor"); \ No newline at end of file diff --git a/src/patterns/creational/AbstractFactory.cpp b/src/patterns/creational/AbstractFactory.cpp index 0ed94b7..8b3b10e 100644 --- a/src/patterns/creational/AbstractFactory.cpp +++ b/src/patterns/creational/AbstractFactory.cpp @@ -163,11 +163,17 @@ void run() { } // namespace AbstractFactory } // namespace -struct AbstractFactoryAutoRunner { - AbstractFactoryAutoRunner() { - std::cout << "\n--- AbstractFactory Pattern Example ---\n"; - AbstractFactory::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class AbstractFactoryExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "AbstractFactory"; } + std::string description() const override { + return "AbstractFactory Pattern Example"; } + void execute() override { AbstractFactory::run(); } }; -static AbstractFactoryAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(AbstractFactoryExample, "patterns", "AbstractFactory"); \ No newline at end of file diff --git a/src/patterns/creational/Builder.cpp b/src/patterns/creational/Builder.cpp index b6b5a84..5c32374 100644 --- a/src/patterns/creational/Builder.cpp +++ b/src/patterns/creational/Builder.cpp @@ -161,11 +161,15 @@ void run() { } // namespace BuilderPattern } // namespace -struct BuilderAutoRunner { - BuilderAutoRunner() { - std::cout << "\n--- Builder Pattern Example ---\n"; - BuilderPattern::run(); - } +#include "ExampleRegistry.h" +#include "IExample.h" + +class BuilderExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Builder"; } + std::string description() const override { return "Builder Pattern Example"; } + void execute() override { BuilderPattern::run(); } }; -static BuilderAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(BuilderExample, "patterns", "Builder"); \ No newline at end of file diff --git a/src/patterns/creational/FactoryMethod.cpp b/src/patterns/creational/FactoryMethod.cpp index bb4a5ee..78962b4 100644 --- a/src/patterns/creational/FactoryMethod.cpp +++ b/src/patterns/creational/FactoryMethod.cpp @@ -130,11 +130,17 @@ void run() { } // namespace FactoryMethod } // namespace -struct FactoryMethodAutoRunner { - FactoryMethodAutoRunner() { - std::cout << "\n--- FactoryMethod Pattern Example ---\n"; - FactoryMethod::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class FactoryMethodExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "FactoryMethod"; } + std::string description() const override { + return "FactoryMethod Pattern Example"; } + void execute() override { FactoryMethod::run(); } }; -static FactoryMethodAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(FactoryMethodExample, "patterns", "FactoryMethod"); \ No newline at end of file diff --git a/src/patterns/creational/Prototype.cpp b/src/patterns/creational/Prototype.cpp index 8743fe3..1ec8a0a 100644 --- a/src/patterns/creational/Prototype.cpp +++ b/src/patterns/creational/Prototype.cpp @@ -117,11 +117,17 @@ void run() { } // namespace Prototy } // namespace -struct PrototypeAutoRunner { - PrototypeAutoRunner() { - std::cout << "\n--- Prototype Pattern Example ---\n"; - Prototy::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class PrototypeExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Prototype"; } + std::string description() const override { + return "Prototype Pattern Example"; } + void execute() override { Prototy::run(); } }; -static PrototypeAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(PrototypeExample, "patterns", "Prototype"); \ No newline at end of file diff --git a/src/patterns/creational/Singleton.cpp b/src/patterns/creational/Singleton.cpp index b062aad..953e629 100644 --- a/src/patterns/creational/Singleton.cpp +++ b/src/patterns/creational/Singleton.cpp @@ -70,11 +70,17 @@ void run() { } // namespace SingletonPattern } // namespace -struct SingletonAutoRunner { - SingletonAutoRunner() { - std::cout << "\n--- Singleton Pattern Example ---\n"; - SingletonPattern::run(); +#include "ExampleRegistry.h" +#include "IExample.h" + +class SingletonExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Singleton"; } + std::string description() const override { + return "Singleton Pattern Example"; } + void execute() override { SingletonPattern::run(); } }; -static SingletonAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(SingletonExample, "patterns", "Singleton"); \ No newline at end of file diff --git a/src/patterns/structural/Adapter.cpp b/src/patterns/structural/Adapter.cpp index 1b79389..98e35ee 100644 --- a/src/patterns/structural/Adapter.cpp +++ b/src/patterns/structural/Adapter.cpp @@ -141,12 +141,18 @@ void run() { } } // namespace CaseStudy -struct AdapterAutoRunner { - AdapterAutoRunner() { - std::cout << "\n--- Factory Pattern Example ---\n"; +#include "ExampleRegistry.h" +#include "IExample.h" + +class AdapterExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Adapter"; } + std::string description() const override { return "Factory Pattern Example"; } + void execute() override { AdapterPattern::run(); CaseStudy::run(); } }; -static AdapterAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(AdapterExample, "patterns", "Adapter"); \ No newline at end of file diff --git a/src/patterns/structural/Bridge.cpp b/src/patterns/structural/Bridge.cpp index 50076ba..234bfb0 100644 --- a/src/patterns/structural/Bridge.cpp +++ b/src/patterns/structural/Bridge.cpp @@ -12,6 +12,10 @@ // UML: docs/uml/patterns_structural_bridge.drawio.svg #include + +#include "ExampleRegistry.h" +#include "IExample.h" + namespace { namespace Problem { class Widget { @@ -166,13 +170,16 @@ void run() { } } // namespace BridgePattern -struct BridgeAutoRunner { - BridgeAutoRunner() { - std::cout << "\n--- Bridge Pattern Example ---\n"; +class BridgeExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Bridge"; } + std::string description() const override { return "Bridge Pattern Example"; } + void execute() override { Problem::run(); BridgePattern::run(); } }; -static BridgeAutoRunner instance; +REGISTER_EXAMPLE(BridgeExample, "patterns", "Bridge"); } // namespace \ No newline at end of file diff --git a/src/patterns/structural/Composite.cpp b/src/patterns/structural/Composite.cpp index 139741b..968bbc2 100644 --- a/src/patterns/structural/Composite.cpp +++ b/src/patterns/structural/Composite.cpp @@ -425,12 +425,20 @@ void run() { } // namespace -struct CompositeAutoRunner { - CompositeAutoRunner() { - std::cout << "\n--- Composite Pattern Example ---\n"; +#include "ExampleRegistry.h" +#include "IExample.h" + +class CompositeExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Composite"; } + std::string description() const override { + return "Composite Pattern Example"; + } + void execute() override { Problem::run(); CompositePattern::run(); } }; -static CompositeAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(CompositeExample, "patterns", "Composite"); \ No newline at end of file diff --git a/src/patterns/structural/Decorator.cpp b/src/patterns/structural/Decorator.cpp index 02f05b8..20e8b61 100644 --- a/src/patterns/structural/Decorator.cpp +++ b/src/patterns/structural/Decorator.cpp @@ -185,12 +185,20 @@ void run() { } // namespace -struct DecoratorAutoRunner { - DecoratorAutoRunner() { - std::cout << "\n--- Decorator Pattern Example ---\n"; +#include "ExampleRegistry.h" +#include "IExample.h" + +class DecoratorExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Decorator"; } + std::string description() const override { + return "Decorator Pattern Example"; + } + void execute() override { Problem::run(); DecoratorPattern::run(); } }; -static DecoratorAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(DecoratorExample, "patterns", "Decorator"); \ No newline at end of file diff --git a/src/patterns/structural/Facade.cpp b/src/patterns/structural/Facade.cpp index ce4db50..4fc7f54 100644 --- a/src/patterns/structural/Facade.cpp +++ b/src/patterns/structural/Facade.cpp @@ -209,12 +209,18 @@ void run() { } // namespace Facade } // namespace -struct FacadeAutoRunner { - FacadeAutoRunner() { - std::cout << "\n--- Facade Pattern Example ---\n"; +#include "ExampleRegistry.h" +#include "IExample.h" + +class FacadeExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Facade"; } + std::string description() const override { return "Facade Pattern Example"; } + void execute() override { Problem::run(); Facade::run(); } }; -static FacadeAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(FacadeExample, "patterns", "Facade"); \ No newline at end of file diff --git a/src/patterns/structural/Flyweight.cpp b/src/patterns/structural/Flyweight.cpp index efc0464..61aa2ad 100644 --- a/src/patterns/structural/Flyweight.cpp +++ b/src/patterns/structural/Flyweight.cpp @@ -327,12 +327,20 @@ void run() { } // namespace FlyweightPattern } // namespace -struct FlyweightAutoRunner { - FlyweightAutoRunner() { - std::cout << "\n--- Flyweight Pattern Example ---\n"; +#include "ExampleRegistry.h" +#include "IExample.h" + +class FlyweightExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Flyweight"; } + std::string description() const override { + return "Flyweight Pattern Example"; + } + void execute() override { Problem::run(); FlyweightPattern::run(); } }; -static FlyweightAutoRunner instance; \ No newline at end of file +REGISTER_EXAMPLE(FlyweightExample, "patterns", "Flyweight"); \ No newline at end of file diff --git a/src/patterns/structural/Proxy.cpp b/src/patterns/structural/Proxy.cpp index 2ce66f4..0589aff 100644 --- a/src/patterns/structural/Proxy.cpp +++ b/src/patterns/structural/Proxy.cpp @@ -15,6 +15,10 @@ // UML: docs/uml/patterns_structural_proxy.drawio.svg #include + +#include "ExampleRegistry.h" +#include "IExample.h" + namespace { namespace Problem { const std::string admin = "admin"; @@ -216,13 +220,16 @@ void run() { } } // namespace ProxyPattern -struct ProxyAutoRunner { - ProxyAutoRunner() { - std::cout << "\n--- Proxy Pattern Example ---\n"; +class ProxyExample : public IExample { + public: + std::string group() const override { return "patterns"; } + std::string name() const override { return "Proxy"; } + std::string description() const override { return "Proxy Pattern Example"; } + void execute() override { Problem::run(); ProxyPattern::run(); } }; -static ProxyAutoRunner instance; +REGISTER_EXAMPLE(ProxyExample, "patterns", "Proxy"); } // namespace