diff --git a/cpp/Platform.Collections.Methods/Polymorph.h b/cpp/Platform.Collections.Methods/Polymorph.h new file mode 100644 index 0000000..79b28b4 --- /dev/null +++ b/cpp/Platform.Collections.Methods/Polymorph.h @@ -0,0 +1,46 @@ +#pragma once + +namespace Platform::Interfaces +{ + /// + /// + /// Represents a base class for implementing the Curiously Recurring Template Pattern (CRTP). + /// This enables static polymorphism where derived classes can be accessed through + /// the base class interface without virtual function overhead. + /// + /// + /// Based on: https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern + /// + /// + /// The derived class type that inherits from this base class. + template + class Polymorph + { + protected: + /// + /// + /// Returns a reference to the derived class object. + /// This method enables static polymorphism by providing access to the + /// actual derived class implementation through a compile-time cast. + /// + /// + /// A reference to the derived class object. + constexpr TSelf& object() noexcept + { + return static_cast(*this); + } + + /// + /// + /// Returns a const reference to the derived class object. + /// This method enables static polymorphism by providing read-only access to the + /// actual derived class implementation through a compile-time cast. + /// + /// + /// A const reference to the derived class object. + constexpr const TSelf& object() const noexcept + { + return static_cast(*this); + } + }; +} \ No newline at end of file diff --git a/experiments/test_collections_crtp b/experiments/test_collections_crtp new file mode 100755 index 0000000..2830468 Binary files /dev/null and b/experiments/test_collections_crtp differ diff --git a/experiments/test_collections_crtp.cpp b/experiments/test_collections_crtp.cpp new file mode 100644 index 0000000..6806770 --- /dev/null +++ b/experiments/test_collections_crtp.cpp @@ -0,0 +1,67 @@ +#include +#include + +// Include our CRTP implementation +#include "../cpp/Platform.Collections.Methods/Polymorph.h" + +using namespace Platform::Interfaces; + +// Simulate the GenericCollectionMethodsBase pattern +template +class GenericCollectionMethodsBase : public Polymorph +{ +}; + +// Simulate a DoublyLinkedList methods class +template +class DoublyLinkedListMethodsBase : public GenericCollectionMethodsBase +{ +protected: + void IncrementSize() + { + this->object().SetSize(this->object().GetSize() + 1); + } + + void DecrementSize() + { + this->object().SetSize(this->object().GetSize() - 1); + } +}; + +// Concrete implementation that would be provided by user +class MyDoublyLinkedList : public DoublyLinkedListMethodsBase +{ +private: + int size = 0; + +public: + int GetSize() const { return size; } + void SetSize(int newSize) { size = newSize; } + + void TestIncrementDecrement() + { + std::cout << "Initial size: " << GetSize() << std::endl; + + IncrementSize(); + std::cout << "After increment: " << GetSize() << std::endl; + + IncrementSize(); + std::cout << "After second increment: " << GetSize() << std::endl; + + DecrementSize(); + std::cout << "After decrement: " << GetSize() << std::endl; + } +}; + +int main() +{ + std::cout << "Testing Collections CRTP pattern..." << std::endl; + + MyDoublyLinkedList list; + list.TestIncrementDecrement(); + + assert(list.GetSize() == 1); + std::cout << "Final size: " << list.GetSize() << " - Test passed!" << std::endl; + + return 0; +} \ No newline at end of file diff --git a/experiments/test_crtp b/experiments/test_crtp new file mode 100755 index 0000000..3a1e57d Binary files /dev/null and b/experiments/test_crtp differ diff --git a/experiments/test_crtp.cpp b/experiments/test_crtp.cpp new file mode 100644 index 0000000..3a45f7d --- /dev/null +++ b/experiments/test_crtp.cpp @@ -0,0 +1,75 @@ +#include +#include + +// Include our CRTP implementation +#include "../cpp/Platform.Collections.Methods/Polymorph.h" + +using namespace Platform::Interfaces; + +// Test class that uses CRTP like the collections classes do +template +class TestBase : public Polymorph +{ +public: + void DoSomething() + { + std::cout << "Base calling derived method: "; + this->object().Implementation(); + } + + int GetValue() + { + return this->object().GetValueImpl(); + } +}; + +// Derived class that implements the interface +class TestDerived : public TestBase +{ +public: + void Implementation() + { + std::cout << "TestDerived::Implementation() called!" << std::endl; + } + + int GetValueImpl() + { + return 42; + } +}; + +// Another derived class to test polymorphism +class AnotherDerived : public TestBase +{ +public: + void Implementation() + { + std::cout << "AnotherDerived::Implementation() called!" << std::endl; + } + + int GetValueImpl() + { + return 100; + } +}; + +int main() +{ + std::cout << "Testing CRTP (Curiously Recurring Template Pattern) implementation..." << std::endl; + + // Test TestDerived + TestDerived derived1; + derived1.DoSomething(); + assert(derived1.GetValue() == 42); + std::cout << "TestDerived value: " << derived1.GetValue() << std::endl; + + // Test AnotherDerived + AnotherDerived derived2; + derived2.DoSomething(); + assert(derived2.GetValue() == 100); + std::cout << "AnotherDerived value: " << derived2.GetValue() << std::endl; + + std::cout << "All tests passed! CRTP implementation is working correctly." << std::endl; + + return 0; +} \ No newline at end of file