diff --git a/include/Multiton.hpp b/include/Multiton.hpp new file mode 100644 index 0000000..5c680d1 --- /dev/null +++ b/include/Multiton.hpp @@ -0,0 +1,69 @@ +#ifndef MULTITON_H +#define MULTITON_H + +#include + +// http://stackoverflow.com/questions/2346091/c-templated-class-implementation-of-the-multiton-pattern + +/// @note Not thread-safe! Use some concurrent map! + +template class Multiton +{ +public: + + static T& getRef( const Key& key ) + { + return *getPtr(key); + } + + static T* getPtr( const Key& key ) + { + typename std::map::const_iterator it = m_instances.find(key); + + if ( it != m_instances.end() ) { + return (T*)(it->second); + } + + T* instance = new T; + m_instances[key] = instance; + return instance; + } + + static bool remove( const Key& key ) + { + typename std::map::const_iterator it = m_instances.find(key); + + if ( it == m_instances.end() ) { + return false; + } + + delete (*it).second; + m_instances.remove(it); + return true; + } + + static void destroy() + { + typename std::map::const_iterator it; + for ( it = m_instances.begin(); it != m_instances.end(); ++it ) { + delete (*it).second; + } + m_instances.clear(); + } + +protected: + + Multiton() {} + + virtual ~Multiton() {} + +private: + Multiton(const Multiton&) {} + Multiton& operator= (const Multiton&) { return *this; } + + static std::map m_instances; +}; + +template std::map Multiton::m_instances; + +#endif // MULTITON_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2f7f76a..297a3f7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,9 +16,10 @@ if(CXXTEST_FOUND) generated_main.cpp Fixture.hpp - test_Singleton.hpp - test_Singleton_meyers.hpp - test_Singleton_DCLP.hpp + test_Multiton.hpp +# test_Singleton.hpp +# test_Singleton_meyers.hpp +# test_Singleton_DCLP.hpp # test_Mutex.hpp # test_ScopedLock.hpp # test_ConditionalVariable.hpp diff --git a/test/test_Multiton.hpp b/test/test_Multiton.hpp new file mode 100644 index 0000000..decd5a8 --- /dev/null +++ b/test/test_Multiton.hpp @@ -0,0 +1,38 @@ +#include + +#include "Common.hpp" +#include "Fixture.hpp" +#include "Multiton.hpp" + + +class TestMultitonSuite : public CxxTest::TestSuite +{ + +private: + + class Dummy + { + public: + void sayHi() { LOG( Logger::FINEST, "Hi there!"); } + + }; + + class DummyMultiton : public Multiton + { + + }; + +public: + + void testBasic( void ) + { + TEST_HEADER; + + DummyMultiton::getRef("foobar").sayHi(); + DummyMultiton::getPtr("foobar")->sayHi(); + + DummyMultiton::destroy(); + } + + +};