[brlcad-commits] SF.net SVN: brlcad:[32985] rt^3/trunk/include/Utility/Singleton.h
Open Source Solid Modeling CAD
Brought to you by:
brlcad
From: <br...@us...> - 2008-10-17 17:06:29
|
Revision: 32985 http://brlcad.svn.sourceforge.net/brlcad/?rev=32985&view=rev Author: brlcad Date: 2008-10-17 17:06:08 +0000 (Fri, 17 Oct 2008) Log Message: ----------- revert to a version of the singleton template class that is more often used elsewhere for its simplicity. this version doesn't have threading support nor support non-new construction, but it does let you make something a singleton with three lines. Modified Paths: -------------- rt^3/trunk/include/Utility/Singleton.h Modified: rt^3/trunk/include/Utility/Singleton.h =================================================================== --- rt^3/trunk/include/Utility/Singleton.h 2008-10-17 16:31:13 UTC (rev 32984) +++ rt^3/trunk/include/Utility/Singleton.h 2008-10-17 17:06:08 UTC (rev 32985) @@ -1,139 +1,106 @@ #ifndef __SINGLETON_H__ #define __SINGLETON_H__ +/* system headers */ +#ifdef HAVE_ATEXIT +# ifdef HAVE_CSTDLIB +#include <cstdlib> +using std::atexit; +# else +#include <stdlib.h> +# endif +#endif + /* Singleton template class + * + * This template class pattern provides a traditional Singleton pattern. + * Allows you to designate a single-instance global class by inheriting + * off of the template class. + * + * Example: + * + * class Whatever : public Singleton<Whatever> ... + * + * The class will need to provide either a public or a protected friend + * constructor: + * + * friend class Singleton<Whatever>; + * + * The class will also need to initialize it's own instance in a single + * compilation unit (a .cxx file): + * + * // statically initialize the instance to nothing + * template <> + * Whatever* Singleton<Whatever>::_instance = 0; + * + * The class can easily be extended to support different allocation + * mechanisms or multithreading access. This implementation, however, + * only uses new/delete and is not thread safe. + * + * The Singleton will automatically get destroyed when the application + * terminates (via an atexit() hook) unless the inheriting class has an + * accessible destructor. */ - - -/** CreationPolicy using new and delete - */ template < typename T > -class CreateUsingNew { +class Singleton { - private: +private: - CreateUsingNew(CreateUsingNew const&) { } // unused - CreateUsingNew& operator=(CreateUsingNew const&) { return *this; } // usused - - protected: - - CreateUsingNew() { } // unused - ~CreateUsingNew() { } // unused - - static T* CreateInstance() { - return new T(); - } - - static void DestroyInstance(T* instance) { - delete instance; - instance = NULL; - } -}; - - -/** ThreadingModel that assumes single threaded access. - * basically does nothing, but it exposes the interface that needs to - * be implmented for a multi-threading model. - */ -class SingleThreaded { - - private: - - friend class LockThread; - SingleThreaded(SingleThreaded const&) { } - SingleThreaded& operator=(SingleThreaded const&) { return *this; } - - protected: - - SingleThreaded() { } - ~SingleThreaded() { } - - public: - - class LockThread { - - private: - - static void Lock() { } - static void Unlock() { } - - public: - - LockThread() { - Lock(); - } - ~LockThread() { - Unlock(); - } - }; -}; - - -/* ThreadingModel for multithreaded access is left as an exercise to the - * the needy. :P - */ - - -/** This template class implements a traditional singleton interface. - * You provide a class, a creation policy, and a threading model. Creation - * policies need to define CreateInstance() and DestroyInstance(). Threading - * model needs to define a default LockThread class. - */ -template < typename T, typename CreationPolicy = CreateUsingNew<T>, typename ThreadingModel = SingleThreaded > -class Singleton : public CreationPolicy, public ThreadingModel { - - private: - static T* _instance; +protected: + + // protection from instantiating a non-singleton Singleton + Singleton() { } + Singleton(T* instancePointer) { _instance = instancePointer; } Singleton(const Singleton &) { } // do not use Singleton& operator=(const Singleton&) { return *this; } // do not use + ~Singleton() { _instance = 0; } // do not delete static void destroy() { if ( _instance != 0 ) { - ThreadingModel::LockThread lock; - if ( _instance != 0 ) { - CreationPolicy::DestroyInstance(_instance); - _instance = 0; - } + delete(_instance); + _instance = 0; } } - protected: +public: - // protection from instantiating a non-singleton Singleton - Singleton() { } - ~Singleton() { _instance = 0; } // do not delete - - public: - /** returns a singleton */ - static T& instance() { + inline static T& instance() { if ( _instance == 0 ) { - ThreadingModel::LockThread lock; - if ( _instance == 0 ) { - _instance = CreationPolicy::CreateInstance(); - // destroy the singleton when the application terminates - std::atexit(Singleton::destroy); - } + _instance = new T; + // destroy the singleton when the application terminates +#ifdef HAVE_ATEXIT + atexit(Singleton::destroy); +#endif } - return *(Singleton::_instance); + return *Singleton::_instance; } + /** returns a singleton pointer + */ + inline static T* pInstance() { + if (_instance == 0) { + _instance = new T; +#ifdef HAVE_ATEXIT + atexit(Singleton::destroy); +#endif + } + return Singleton::_instance; + } + /** returns a const singleton reference */ - inline static const T& constInstance() { return instance(); } + inline static const T& constInstance() { return *instance(); } }; -// statically initialize the instance to nothing -template < typename T, typename CreationPolicy, typename ThreadingModel > -T* Singleton<T, CreationPolicy, ThreadingModel>::_instance = 0; - #endif /* __SINGLETON_H__ */ -// Local variables: *** -// mode:C++ *** + +// Local Variables: *** +// mode: C++ *** // tab-width: 8 *** // c-basic-offset: 2 *** // indent-tabs-mode: t *** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |