diff --git a/CHANGES b/CHANGES index 35cd616332159dc095a773f69cd07b04db8bbc76..eeed46df590eb4c2c06b2ba0aa27d4ebb845d27d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ -SFLphone (0.4.1-rc1) / 2005-08-11 +SFLphone (0.4.1-pre2) / now + * rearranged utilspp use + +SFLphone (0.4.1-pre1) / 2005-08-11 * Use libeXosip2 * Add blink notification for voice-message * Add scrolling text diff --git a/ChangeLog b/ChangeLog index 6c8da483939ca9e2c1481ac5146ffd7e29974f3e..0c1ca314672f716d631f67937cd774f368368fd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Jean-Philippe Barette-LaPierre (28 April 2005) version 0.4.1-pre1 +- Manager has now a LifetimeLibrary policy. +- Utilspp has been rearranged. + Laurielle LEA (10 August 2005) version 0.4 - Add blink notification for voice-message - Cleanup code diff --git a/DEPS b/DEPS index 130885e7bf59d9875f1f8023af1770074a2503ae..32fe7cbef72cc87b84fa635f2676a57d256b83f7 100644 --- a/DEPS +++ b/DEPS @@ -2,4 +2,4 @@ PortAudio: http://portaudio.com/archives/pa_snapshot_v19.tar.gz Common C++ 2 1.3.6: http://sourceforge.net/projects/cplusplus/ ccRTP 1.3.0: http://sourceforge.net/projects/cplusplus/ libosip 2.2.1: http://savannah.gnu.org/projects/osip/ -libeXosip2-1.9.1-pre15: http://www.antisip.com/download/ +libeXosip2-1.9.1-pre15: http://www.antisip.com/download/ \ No newline at end of file diff --git a/INSTALL b/INSTALL index 56b077d6a0b8773b014bd4381cc09abb17fff351..c493b7b3cc2773b38455b642cfdab4fa1116a73b 100644 --- a/INSTALL +++ b/INSTALL @@ -1,6 +1,7 @@ Installation Instructions ************************* + Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. diff --git a/Makefile.am b/Makefile.am index ba8bfe76493e5e8a814b5799e81b65734b8c1f9a..ae923b4923d285d9ebb21607cf23f81ff40dd634 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,2 @@ -SUBDIRS = stund src skins rings pixmaps utilspp - +SUBDIRS = utilspp stund src skins rings pixmaps diff --git a/configure.ac b/configure.ac index af89e4594f345c9404d6e0a8858ede2be1196a61..58a5fd5da47ab960515d34f245bc67e0538b47d9 100644 --- a/configure.ac +++ b/configure.ac @@ -137,11 +137,12 @@ src/audio/pacpp/source/Makefile \ src/audio/pacpp/source/portaudiocpp/Makefile \ src/gui/Makefile \ src/gui/qt/Makefile \ +utilspp/Makefile \ +utilspp/singleton/Makefile \ stund/Makefile \ pixmaps/Makefile \ skins/Makefile \ skins/emetal/Makefile \ skins/metal/Makefile \ rings/Makefile \ -utilspp/Makefile \ ) diff --git a/src/Makefile.am b/src/Makefile.am index e1e586c066bdfc2eebfd1f0372f8a5fd2103fe0b..812de8c0920cef2474964f1b6a0ecbfe930ed620 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,8 +36,8 @@ sflphone_SOURCES = \ sflphone_CXXFLAGS = -DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" -sflphone_LDFLAGS = $(QT_LDFLAGS) $(X_LDFLAGS) -sflphone_LDADD = gui/libguiframework.la audio/libaudio.la ../stund/libstun.la -lpthread $(LIBQT) $(SFLPHONE_LIBS) +sflphone_LDFLAGS = $(QT_LDFLAGS) $(X_LDFLAGS) -static +sflphone_LDADD = gui/libguiframework.la audio/libaudio.la ../stund/libstun.la ../utilspp/libutilspp.la -lpthread $(LIBQT) $(SFLPHONE_LIBS) KDE_CXXFLAGS = $(USE_EXCEPTIONS) AM_CPPFLAGS = $(QT_INCLUDES) $(X_INCLUDES) -Iaudio/pacpp/include $(libccext2_CFLAGS) $(libccgnu2_CFLAGS) $(portaudio_CFLAGS) diff --git a/src/audio/audiocodec.cpp b/src/audio/audiocodec.cpp index dcc6f748249890ebea9277cfa21f0b4b8905da02..146b0cd137fbe145a8718bcac9478f9d3cf892d5 100644 --- a/src/audio/audiocodec.cpp +++ b/src/audio/audiocodec.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <string.h> #include <iostream> #include <string> diff --git a/src/main.cpp b/src/main.cpp index e23dd3dacd7184e50c883749f0a790c264b42e25..7dfd6d2c9a620406ea09d5d54e05556ddc1b2441 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,22 +36,29 @@ int main (int argc, char **argv) { + int exit_code; Config::setTree(new ConfigurationTree()); GuiFramework *GUI; #if defined(GUI_QT) - QApplication a(argc, argv); - Manager::instance().initConfigFile(); - GUI = new QtGUIMainWindow (0, 0 , - Qt::WDestructiveClose | - Qt::WStyle_Customize | - Qt::WStyle_NoBorder); - Manager::instance().setGui(GUI); - Manager::instance().init(); - - a.setMainWidget((QtGUIMainWindow*)GUI); - return a.exec(); + { + utilspp::LifetimeLibraryGuard< utilspp::LifetimeLibrarySingleton > guard(); + (void)guard; + QApplication a(argc, argv); + Manager::instance().initConfigFile(); + GUI = new QtGUIMainWindow (0, 0 , + Qt::WDestructiveClose | + Qt::WStyle_Customize | + Qt::WStyle_NoBorder); + Manager::instance().setGui(GUI); + Manager::instance().init(); + + a.setMainWidget((QtGUIMainWindow*)GUI); + exit_code = a.exec(); + } #endif + + return exit_code; } diff --git a/src/manager.h b/src/manager.h index eb0a0cffd4fd747c9cd0d9799a6625f70eed5651..fc65002818971587e9a6c2436148c06d62fe0e75 100644 --- a/src/manager.h +++ b/src/manager.h @@ -21,12 +21,14 @@ #ifndef SFLPHONE_MANAGER_H #define SFLPHONE_MANAGER_H -#include "utilspp/singleton_holder.hpp" +#include "utilspp/Singleton.hpp" #include "managerimpl.h" -typedef utilspp::singleton_holder< ManagerImpl > Manager; - +typedef utilspp::SingletonHolder< ManagerImpl, + utilspp::CreationUsingNew, + utilspp::LifetimeLibrary, + utilspp::ThreadingSingle > Manager; #endif diff --git a/utilspp/utilspp/Makefile.am b/utilspp/utilspp/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..dda27b48f841b9d5e9c0f2f80e9c679ff8b7ea15 --- /dev/null +++ b/utilspp/utilspp/Makefile.am @@ -0,0 +1,30 @@ +SUBDIRS = singleton + +lib_LTLIBRARIES=libutilspp.la + +libutilspp_la_SOURCES = \ + NonCopyable.hpp \ + NullType.hpp \ + Singleton.hpp \ + SmartPtr.hpp \ + ThreadingFactoryMutex.hpp \ + ThreadingSingle.hpp \ + TypeList.hpp \ + TypeTrait.hpp + +pkginclude_HEADERS = \ + NonCopyable.hpp \ + NullType.hpp \ + Singleton.hpp \ + SmartPtr.hpp \ + ThreadingFactoryMutex.hpp \ + ThreadingSingle.hpp \ + TypeList.hpp \ + TypeTrait.hpp + +pkgincludedir=$(includedir)/utilspp + +libutilspp_la_LIBADD = ./singleton/libsingleton.la + + + diff --git a/utilspp/utilspp/NonCopyable.hpp b/utilspp/utilspp/NonCopyable.hpp new file mode 100644 index 0000000000000000000000000000000000000000..eb5443129393b24f22cc0f223401d65bee763602 --- /dev/null +++ b/utilspp/utilspp/NonCopyable.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_NONCOPYABLE_HPP +#define UTILSPP_NONCOPYABLE_HPP + +namespace utilspp +{ + class NonCopyable + { + public: + NonCopyable() + {} + + private: + NonCopyable(const NonCopyable& r) + {} + }; +}; + +#endif diff --git a/utilspp/utilspp/NullType.hpp b/utilspp/utilspp/NullType.hpp new file mode 100644 index 0000000000000000000000000000000000000000..819026474bef06b73aad5a6a5fccc192c952a8fd --- /dev/null +++ b/utilspp/utilspp/NullType.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_NULLTYPE_HPP +#define UTILSPP_NULLTYPE_HPP + +namespace utilspp +{ + struct NullType; +}; + +#endif diff --git a/utilspp/utilspp/Singleton.hpp b/utilspp/utilspp/Singleton.hpp new file mode 100644 index 0000000000000000000000000000000000000000..52fe364689f0af18168a1c61c2da0e2ba9970900 --- /dev/null +++ b/utilspp/utilspp/Singleton.hpp @@ -0,0 +1,3 @@ +#include "ThreadingSingle.hpp" +#include "singleton/SingletonHolder.hpp" +#include "singleton/LifetimeLibrary.hpp" diff --git a/utilspp/utilspp/SmartPtr.hpp b/utilspp/utilspp/SmartPtr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..43c400be97b389b20e213fa11055ec873cd874a2 --- /dev/null +++ b/utilspp/utilspp/SmartPtr.hpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_SMARTPTR_HPP +#define UTILSPP_SMARTPTR_HPP + +#include <stdexcept> +#include "NonCopyable.hpp" + +#define NULL_BODY_ERROR "the smart pointer contain a NULL pointer" + +namespace utilspp +{ + + template < typename Type = unsigned int > + class FastCount + { + public: + FastCount(Type count = 1) : mCount(count) + {} + + FastCount &operator++() + { + mCount++; + return *this; + } + + FastCount &operator--() + { + mCount--; + return *this; + } + + operator Type() + { + return mCount; + } + + Type useCount() + { + return mCount; + } + + private: + Type mCount; + }; + + + template < typename ContentType, typename CountPolicy = FastCount > + class CountingBody : public utilspp::NonCopyable + { + public: + CountingBody(ContentType *body) : mBody(body) + {} + + void inc() + { + ++mCount; + } + + void dec() + { + --mCount; + if (mCount <= 0) { + delete this; + } + } + + ContentType *get() + { + return mBody; + } + + protected: + ~CountingBody() + { + if (mBody != NULL) { + delete mBody; + mBody = NULL; + } + } + + private: + CountPolicy mCount; + ContentType *mBody; + }; + + + template < typename ContentType, typename CountingBodyPolicy = CountingBody> + class SharedPtr + { + public: + SharedPtr() : mContent(new CountingPolicy< ContentType >(NULL)) + {} + + explicit SharedPtr(ContentType *content) : mContent(new CountingBodyPolicy< ContentType >(content)) + {} + + ~SharedPtr() + { + mContent->dec(); + } + + SharedPtr(const SharedPtr &other) : mContent(other.mContent) + { + mContent->inc(); + } + + SharedPtr& operator=(const SharedPtr &other) + { + if(mContent->get() != other.mContent->get()) { + mContent->dec(); + mContent = other.mContent; + mContent->inc(); + } + return ( *this ); + } + + SharedPtr& operator=(ContentType *content) + { + mContent--; + mContent = new CountingBodyPolicy< ContentType >(content); + } + + bool operator==(const SharedPtr &other) const + { + return (mContent->get() == other.mContent->get()); + } + + bool operator!=(const SharedPtr &other) const + { + return (mContent->get() != other.mContent->get()); + } + + bool operator<(const SharedPtr &other) const + { + return (mContent->get() < other.mContent->get()); + } + + operator ContentType*() + { + return mContent->get(); + } + + ContentType& operator*() + { + if(mContent->get() == NULL) { + throw std::runtime_error(NULL_BODY_ERROR); + } + return *mContent->get(); + } + + ContentType* operator->() + { + if(mContent->get() == NULL) { + throw std::runtime_error(NULL_BODY_ERROR); + } + return mContent->get(); + } + + private: + CountingBodyPolicy * mContent; + }; +}; + +#endif diff --git a/utilspp/utilspp/ThreadingFactoryMutex.hpp b/utilspp/utilspp/ThreadingFactoryMutex.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5bd6225f29f58342919ec2489d09cd2079ff478f --- /dev/null +++ b/utilspp/utilspp/ThreadingFactoryMutex.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef THREADING_FACTORY_MUTEX_HPP +#define THREADING_FACTORY_MUTEX_HPP + +namespace utilspp +{ + template < typename T > + struct ThreadingFactoryMutex + { + struct lock + { + lock(); + lock( const T & ); + }; + + typedef T VolatileType; + }; +}; + +#include "ThreadingFactoryMutex.inl" + +#endif diff --git a/utilspp/utilspp/ThreadingFactoryMutex.inl b/utilspp/utilspp/ThreadingFactoryMutex.inl new file mode 100644 index 0000000000000000000000000000000000000000..c9a9f62fbdb9ab4b40e6f5fab2c91e25f60db302 --- /dev/null +++ b/utilspp/utilspp/ThreadingFactoryMutex.inl @@ -0,0 +1,37 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef THREADING_FACTORY_MUTEX_INL +#define THREADING_FACTORY_MUTEX_INL + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock() +{}; + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock( const T & ) +{}; + +#endif \ No newline at end of file diff --git a/utilspp/utilspp/ThreadingSingle.hpp b/utilspp/utilspp/ThreadingSingle.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bbab15b5c46ad8651c31be092d351338c33dd110 --- /dev/null +++ b/utilspp/utilspp/ThreadingSingle.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLE_THREADED_HPP +#define SINGLE_THREADED_HPP + +#include "NullType.hpp" + +namespace utilspp +{ + template < typename T = utilspp::NullType > + struct ThreadingSingle + { + struct mutex + { + void lock(); + void unlock(); + }; + + struct lock + { + lock(); + lock( mutex &m ); + }; + + typedef T VolatileType; + }; +}; + +#include "ThreadingSingle.inl" + +#endif diff --git a/utilspp/utilspp/ThreadingSingle.inl b/utilspp/utilspp/ThreadingSingle.inl new file mode 100644 index 0000000000000000000000000000000000000000..fcb395ba2081b99d361fca85deb46cbbc07d5580 --- /dev/null +++ b/utilspp/utilspp/ThreadingSingle.inl @@ -0,0 +1,50 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLE_THREADED_INL +#define SINGLE_THREADED_INL + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock() +{}; + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock( + utilspp::ThreadingSingle< T >::mutex & ) +{} + +template< typename T > +inline +void +utilspp::ThreadingSingle< T >::mutex::lock() +{}; + +template< typename T > +inline +void +utilspp::ThreadingSingle< T >::mutex::unlock() +{}; + +#endif diff --git a/utilspp/utilspp/TypeList.hpp b/utilspp/utilspp/TypeList.hpp new file mode 100644 index 0000000000000000000000000000000000000000..677ed46928a5fabc31d042d0eb72ab7d7e25a427 --- /dev/null +++ b/utilspp/utilspp/TypeList.hpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef TYPE_LIST_HPP +#define TYPE_LIST_HPP + +#include "NullType.hpp" + +namespace utilspp +{ + namespace tl + { + template< class T, class U > + struct TypeList + { + typedef T head; + typedef U tail; + }; + + //Calculating length of TypeLists + template< class TList > + struct length; + + template<> + struct length< NullType > + { + enum { value = 0 }; + }; + + template< class T, class U > + struct length< TypeList< T, U > > + { + enum { value = 1 + length< U >::value }; + }; + + //Indexed access + template< class TList, unsigned int index > + struct TypeAt; + + template< class THead, class TTail > + struct TypeAt< TypeList< THead, TTail >, 0 > + { + typedef head result; + } + + template< class THead, class TTail, unsigned int i > + struct TypeAt< TypeList< THead, TTail >, i > + { + typedef typename TypeAt< TTail, i - 1 >::result result; + }; + + //Searching TypeLists + template< class TList, class T > + struct index_of; + + template< class T > + struct index_of< NullType, T > + { + enum { value = -1 }; + }; + + template< class TTail, class T > + struct index_of< TypeList< T, TTail >, T > + { + enum { value = 0 }; + }; + + template< class THead, class TTail, class T > + struct index_of< TypeList< THead, TTail >, T > + { + private: + enum { temp = index_of< TTail, T >::value > }; + + public: + enum { value = temp == -1 ? -1 : 1 + temp }; + }; + + //Appending to TypeLists + template< class TList, class T > + struct append; + + template <> + struct append< NullType, NullType > + { + typedef NullType result; + }; + + template< class T > + struct append< NullType, T > + { + typedef TYPELIST_1( T ) result; + }; + + template< class THead, class TTail > + struct append< NullType, NullType, TypeList< THead, TTail > > + { + typedef TypeList< THead, TTail > result; + }; + + template < class THead, class TTail, class T > + struct append< TypeList< THead, TTail >, T > + { + typedef TypeList< THead, typename append< TTail, T >::result > + result; + }; + + //Erasing a type from a TypeList + template< class TList, class T > + struct erase; + + template< class T > + struct erase< NullType, T > + { + typedef NullType result; + }; + + template< class T, class TTail > + struct erase< TypeList< T, TTail >, T > + { + typedef TTail result; + }; + + template< class THead, class TTail, class T > + struct erase< TypeList< THead, TTail >, T > + { + typedef TypeList< THead, typename erase< TTail, T >::result > + result; + }; + }; +}; + +#define TYPELIST_1( T1 ) ::utilspp::TypeList< T1, ::utilspp::NullType > +#define TYPE_LIST_2( T1, T2 ) ::utilspp::TypeList< T1, TYPE_LIST_1( T2 ) > +#define TYPE_LIST_3( T1, T2, T3 ) ::utilspp::TypeList< T1, TYPE_LIST_2( T2, T3 ) > +#define TYPE_LIST_4( T1, T2, T3, T4 ) ::utilspp::TypeList< T1, TYPE_LIST_3( T2, T3, T4 ) > +#define TYPE_LIST_5( T1, T2, T3, T4, T5 ) \ +::utilspp::TypeList< T1, TYPE_LIST_4( T2, T3, T4, T5 ) > +#define TYPE_LIST_6( T1, T2, T3, T4, T5, T6 ) \ +::utilspp::TypeList< T1, TYPE_LIST_5( T2, T3, T4, T5, T6 ) > +#define TYPE_LIST_7( T1, T2, T3, T4, T5, T6, T7 ) \ +::utilspp::TypeList< T1, TYPE_LIST_6( T2, T3, T4, T5, T6, T7 ) > +#define TYPE_LIST_8( T1, T2, T3, T4, T5, T6, T7, T8 ) \ +::utilspp::TypeList< T1, TYPE_LIST_7( T2, T3, T4, T5, T6, T7, T8 ) > +#define TYPE_LIST_9( T1, T2, T3, T4, T5, T6, T7, T8, T9 ) \ +::utilspp::TypeList< T1, TYPE_LIST_8( T2, T3, T4, T5, T6, T7, T8, T9 ) > +#define TYPE_LIST_10( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 ) \ +::utilspp::TypeList< T1, TYPE_LIST_9( T2, T3, T4, T5, T6, T7, T8, T9, T10 ) > + +#endif + diff --git a/utilspp/utilspp/TypeTrait.hpp b/utilspp/utilspp/TypeTrait.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2c30f300099bdfbdf746a651e1f03851a8c61901 --- /dev/null +++ b/utilspp/utilspp/TypeTrait.hpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_TYPETRAIT_HPP +#define UTILSPP_TYPETRAIT_HPP + +#include "NullType.hpp" + +namespace utilspp +{ + template< typename T > + class TypeTrait + { + private: + template< typename U > + struct unreference + { + typedef U type; + }; + + template< typename U > + struct unreference< U & > + { + typedef U type; + }; + + template< typename U > + struct unconst + { + typedef U type; + }; + + template< typename U > + struct unconst< const U > + { + typedef U type; + }; + + public: + typedef typename unreference< T >::type NonReference; + typedef typename unconst< T >::type NonConst; + typedef typename unconst< unreference< T >::type >::type NonParam; + }; + + template< class T > + struct PointerOnMemberFunction + { + typedef ::utilspp::NullType ClassType; + typedef ::utilspp::NullType ReturnType; + typedef ::utilspp::NullType ParamType; + }; + + template< typename V, typename W, typename R > + struct PointerOnMemberFunction< W(V::*)(R) > + { + typedef V ClassType; + typedef W ReturnType; + typedef R ParamType; + }; + + template< typename T > + struct PointerOnFunction + { + typedef utilspp::NullType ReturnType; + typedef utilspp::NullType Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V > + struct PointerOnFunction< V(*)() > + { + typedef V ReturnType; + typedef utilspp::NullType Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V, typename W > + struct PointerOnFunction< V(*)(W) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V, typename W, typename X > + struct PointerOnFunction< V(*)(W, X) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V, typename W, typename X, typename Y > + struct PointerOnFunction< V(*)(W, X, Y) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V, typename W, typename X, typename Y, typename Z > + struct PointerOnFunction< V(*)(W, X, Y, Z) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A > + struct PointerOnFunction< V(*)(W, X, Y, Z, A) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef utilspp::NullType Param7Type; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + }; + +}; + +#endif diff --git a/utilspp/utilspp/singleton/CreationStatic.hpp b/utilspp/utilspp/singleton/CreationStatic.hpp new file mode 100644 index 0000000000000000000000000000000000000000..27570f5308802c89614944ae3ab97b7fafdf7c8f --- /dev/null +++ b/utilspp/utilspp/singleton/CreationStatic.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_STATIC_HPP +#define CREATION_STATIC_HPP + +/** + * This class is a creation policy for the utilspp::singleton_holder. The + * policy is creating the singleton by a static memory. The constructor is + * called the first time we call the utilspp::creation_static::create() + * function. + * + * Note don't use this class because it's not complete, and at this time it's + * not REALY complyant with the lifetime policy. + */ +namespace utilspp +{ + template< typename T > + class CreationStatic + { + public: + static T* create(); + static void destroy( T* obj ); + }; +}; + +#include "CreationStatic.inl" + +#endif diff --git a/utilspp/utilspp/singleton/CreationStatic.inl b/utilspp/utilspp/singleton/CreationStatic.inl new file mode 100644 index 0000000000000000000000000000000000000000..9572e5eca75f2d2e054cb7ea12d68a2cb33677b4 --- /dev/null +++ b/utilspp/utilspp/singleton/CreationStatic.inl @@ -0,0 +1,43 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_STATIC_INL +#define CREATION_STATIC_INL + +template< typename T > +T* +utilspp::CreationStatic::create() +{ + static T mObj; + return new(&mObj) T; +}; + +template< typename T > +void +utilspp::CreationStatic::destroy( T* obj ) +{ + obj->~T(); +} + + +#endif \ No newline at end of file diff --git a/utilspp/utilspp/singleton/CreationUsingNew.hpp b/utilspp/utilspp/singleton/CreationUsingNew.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5055db5b8ff0866159e9ad488312cee6e9a900c5 --- /dev/null +++ b/utilspp/utilspp/singleton/CreationUsingNew.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_USING_NEW_HPP +#define CREATION_USING_NEW_HPP + +/** + * This class is a creation policy for the utilspp::singleton_holder. The + * policy is creating the singleton by a "new" call. + */ +namespace utilspp +{ + template< typename T > + struct CreationUsingNew + { + static T *create(); + static void destroy( T *obj ); + }; +}; + +#include "CreationUsingNew.inl" + +#endif diff --git a/utilspp/utilspp/singleton/CreationUsingNew.inl b/utilspp/utilspp/singleton/CreationUsingNew.inl new file mode 100644 index 0000000000000000000000000000000000000000..adb66ede9ee12036dbcc41f9469475378190a8b3 --- /dev/null +++ b/utilspp/utilspp/singleton/CreationUsingNew.inl @@ -0,0 +1,42 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_USING_NEW_INL +#define CREATION_USING_NEW_INL + +template< typename T > +T * +utilspp::CreationUsingNew< T >::create() +{ + return new T; +} + +template< typename T > +void +utilspp::CreationUsingNew< T >::destroy( T *obj ) +{ + delete obj; +} + + +#endif diff --git a/utilspp/utilspp/singleton/LifetimeDefault.hpp b/utilspp/utilspp/singleton/LifetimeDefault.hpp new file mode 100644 index 0000000000000000000000000000000000000000..82bd9c30d42eb8b8c1768c2c39a7ca1d5071e495 --- /dev/null +++ b/utilspp/utilspp/singleton/LifetimeDefault.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_DEFAULT_HPP +#define LIFETIME_DEFAULT_HPP + +#include <stdexcept> +#include <cstdlib> + +namespace utilspp +{ + template< typename T > + class LifetimeDefault + { + public: + static void scheduleDestruction( T *obj, void (*func)() ); + static void onDeadReference(); + }; +}; + + +#endif diff --git a/utilspp/utilspp/singleton/LifetimeDefault.inl b/utilspp/utilspp/singleton/LifetimeDefault.inl new file mode 100644 index 0000000000000000000000000000000000000000..a8e63f9fc43ede97e653513d336327ca93e242a7 --- /dev/null +++ b/utilspp/utilspp/singleton/LifetimeDefault.inl @@ -0,0 +1,42 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_DEFAULT_INL +#define LIFETIME_DEFAULT_INL + +template< typename T > +void +utilspp::LifetimeDefault< T >::scheduleDestruction( T *, void (*func)() ) +{ + std::atexit(func); +} + +template< typename T > +void +utilspp::LifetimeDefault< T >::onDeadReference() +{ + throw std::logic_error( "Dead reference detected" ); +} + + +#endif diff --git a/utilspp/utilspp/singleton/LifetimeLibrary.cpp b/utilspp/utilspp/singleton/LifetimeLibrary.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e58932ebde4692b55b67fdce9b569bea80b5b5bc --- /dev/null +++ b/utilspp/utilspp/singleton/LifetimeLibrary.cpp @@ -0,0 +1,72 @@ +#include "SingletonHolder.hpp" +#include "LifetimeLibrary.hpp" + +utilspp::LifetimeLibraryImpl::LifetimeLibraryImpl() + : + mTrackerArray( NULL ), + mNbElements( 0 ) +{} + +utilspp::LifetimeLibraryImpl::~LifetimeLibraryImpl() +{ + terminate(); +} + +void +utilspp::LifetimeLibraryImpl::add( utilspp::PrivateMembers::LifetimeTracker *tracker ) +{ + utilspp::PrivateMembers::TrackerArray newArray = static_cast< + utilspp::PrivateMembers::TrackerArray >(std::realloc(mTrackerArray, + mNbElements + 1)); + if( newArray == NULL ) + { + throw std::bad_alloc(); + } + + mTrackerArray = newArray; + + utilspp::PrivateMembers::TrackerArray pos = + std::upper_bound(mTrackerArray, + mTrackerArray + mNbElements, + tracker, + &utilspp::PrivateMembers::LifetimeTracker::compare); + std::copy_backward(pos, + mTrackerArray + mNbElements, + mTrackerArray + mNbElements + 1); + + *pos = tracker; + mNbElements++; +}; + +void +utilspp::LifetimeLibraryImpl::terminate() +{ + //The number of elements MUST always be equal or over zero. + assert( mNbElements >= 0 ); + + while( mNbElements > 0 ) + { + //At this point the mTrackerArray MUST not be NULL. + assert( mTrackerArray != NULL ); + + //Pick the element at the top of the stack. + utilspp::PrivateMembers::LifetimeTracker* top = + mTrackerArray[mNbElements - 1]; + + //Remove that object off the stack. + //Don't check errors-realloc with less memory, cause that can't fail. + mTrackerArray = + static_cast< utilspp::PrivateMembers::TrackerArray > + (std::realloc(mTrackerArray, --mNbElements)); + + //Destroy the element. + delete top; + } +} + +unsigned int +utilspp::getLongevity( utilspp::LifetimeLibraryImpl * ) +{ + return 0; +} + diff --git a/utilspp/utilspp/singleton/LifetimeLibrary.hpp b/utilspp/utilspp/singleton/LifetimeLibrary.hpp new file mode 100644 index 0000000000000000000000000000000000000000..80fba716ab70484e4cd5525be39e9e08cf40a276 --- /dev/null +++ b/utilspp/utilspp/singleton/LifetimeLibrary.hpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_LIBRARY_HPP +#define LIFETIME_LIBRARY_HPP + +#include <cassert> + +#include "PrivateMembers.hpp" +#include "CreationUsingNew.hpp" + +namespace utilspp +{ + + template< typename T > + unsigned int getLongevity( T *p ); + + /** + * Assigns an object a longevity. Ensures ordered destructions of objects + * registered thusly during the exit sequence of the application. + */ + template< typename T, typename TDestroyer > + void setLibraryLongevity( + T *obj, + unsigned int longevity, + TDestroyer d = utilspp::PrivateMembers::Deleter< T >::deleteObject + ); + + /** + * This class is a lifetime policy for the singleton. This + * class allow you to terminate the singleton explicitly. + * You can terminate by calling: + * + * LifetimeLibrarySingleton::instance().terminate() + * + * This singleton use the utilspp::LifetimeWithLongevity policy. + */ + template< typename T > + struct LifetimeLibrary + { + static void scheduleDestruction( T *obj, void (*func)() ); + static void onDeadReference(); + }; + + class LifetimeLibraryImpl + { + public: + LifetimeLibraryImpl(); + ~LifetimeLibraryImpl(); + + void add( utilspp::PrivateMembers::LifetimeTracker *tracker ); + void terminate(); + + private: + utilspp::PrivateMembers::TrackerArray mTrackerArray; + int mNbElements; + }; + + unsigned int getLongevity( utilspp::LifetimeLibraryImpl *p ); + + typedef utilspp::SingletonHolder< + utilspp::LifetimeLibraryImpl, + utilspp::CreationUsingNew, + utilspp::LifetimeWithLongevity + > LifetimeLibrarySingleton; + + /** + * This class will ensure that + * + * LifetimeLibraryImpl::terminate() + * + * is called. + */ + template< typename T = utilspp::LifetimeLibrarySingleton > + class LifetimeLibraryGuard + { + public: + ~LifetimeLibraryGuard(); + }; +}; + +#include "LifetimeLibrary.inl" + +#endif diff --git a/utilspp/utilspp/singleton/LifetimeLibrary.inl b/utilspp/utilspp/singleton/LifetimeLibrary.inl new file mode 100644 index 0000000000000000000000000000000000000000..b7ab8e6d66d2bb38719e8b0b6d163636f33bcdbd --- /dev/null +++ b/utilspp/utilspp/singleton/LifetimeLibrary.inl @@ -0,0 +1,33 @@ +template< typename T, typename TDestroyer > +void +utilspp::setLibraryLongevity( T *obj, unsigned int longevity, TDestroyer d ) +{ + using namespace utilspp::PrivateMembers; + + LifetimeTracker *p = new ConcreteLifetimeTracker< T, TDestroyer >( + obj, longevity, d); + + utilspp::LifetimeLibrarySingleton::instance().add( p ); +}; + +template< typename T > +void +utilspp::LifetimeLibrary< T >::scheduleDestruction( T *obj, void (*func)() ) +{ + utilspp::PrivateMembers::adapter<T> adapter = { func }; + utilspp::setLibraryLongevity( obj, getLongevity( obj ), adapter ); +} + +template< typename T > +void +utilspp::LifetimeLibrary< T >::onDeadReference() +{ + throw std::logic_error("Dead reference detected"); +} + +template< typename T > +utilspp::LifetimeLibraryGuard< T >::~LifetimeLibraryGuard() +{ + T::instance().terminate(); +} + diff --git a/utilspp/utilspp/singleton/LifetimeWithLongevity.hpp b/utilspp/utilspp/singleton/LifetimeWithLongevity.hpp new file mode 100644 index 0000000000000000000000000000000000000000..888475126411719da68a0d7043ef358eac7b79da --- /dev/null +++ b/utilspp/utilspp/singleton/LifetimeWithLongevity.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_WITH_LONGEVITY_HPP +#define LIFETIME_WITH_LONGEVITY_HPP + +#include <cassert> + +#include "PrivateMembers.hpp" + +namespace utilspp +{ + + template< typename T > + unsigned int getLongevity( T *p ); + + /** + * Assigns an object a longevity. Ensures ordered destructions of objects + * registered thusly during the exit sequence of the application. + */ + template< typename T, typename TDestroyer > + void setLongevity(T *obj, + unsigned int longevity, + TDestroyer d = utilspp::PrivateMembers::Deleter< T >::deleteObject); + + template< typename T > + struct LifetimeWithLongevity + { + static void scheduleDestruction( T *obj, void (*func)() ); + static void onDeadReference(); + }; +}; + +#include "LifetimeWithLongevity.inl" + +#endif diff --git a/utilspp/utilspp/singleton/LifetimeWithLongevity.inl b/utilspp/utilspp/singleton/LifetimeWithLongevity.inl new file mode 100644 index 0000000000000000000000000000000000000000..aaaf0ebfb5befbf0b528e247ccc0b2157576f499 --- /dev/null +++ b/utilspp/utilspp/singleton/LifetimeWithLongevity.inl @@ -0,0 +1,56 @@ +template< typename T, typename TDestroyer > +void +utilspp::setLongevity( T *obj, unsigned int longevity, TDestroyer d ) +{ + using namespace utilspp::PrivateMembers; + + TrackerArray newArray = static_cast< TrackerArray >( + std::realloc(mTrackerArray, mNbElements + 1)); + if( newArray == NULL ) + { + throw std::bad_alloc(); + } + + LifetimeTracker *p = + new ConcreteLifetimeTracker< T, TDestroyer >(obj, longevity, d); + + mTrackerArray = newArray; + + TrackerArray pos = std::upper_bound( + mTrackerArray, + mTrackerArray + mNbElements, + p, + &LifetimeTracker::compare); + std::copy_backward( + pos, + mTrackerArray + mNbElements, + mTrackerArray + mNbElements + 1); + + *pos = p; + mNbElements++; + std::atexit( &atExitFunc ); +}; + +template< typename T > +void +utilspp::LifetimeWithLongevity< T >::scheduleDestruction( T *obj, void (*func)() ) +{ + utilspp::PrivateMembers::adapter<T> adapter = { func }; + utilspp::setLongevity( obj, getLongevity( obj ), adapter ); +} + +template< typename T > +void +utilspp::LifetimeWithLongevity< T >::onDeadReference() +{ + throw std::logic_error("Dead reference detected"); +} + +template< typename T > +unsigned int +utilspp::getLongevity( T * ) +{ + return 1000; +} + + diff --git a/utilspp/utilspp/singleton/Makefile.am b/utilspp/utilspp/singleton/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..4992bcdb0828c418766df9824ada0dfc24c3c92c --- /dev/null +++ b/utilspp/utilspp/singleton/Makefile.am @@ -0,0 +1,22 @@ +noinst_LTLIBRARIES = libsingleton.la + +libsingleton_la_SOURCES = \ + CreationStatic.hpp \ + CreationUsingNew.hpp \ + LifetimeDefault.hpp \ + LifetimeLibrary.cpp LifetimeLibrary.hpp LifetimeLibrary.inl \ + LifetimeWithLongevity.hpp LifetimeWithLongevity.inl \ + PrivateMembers.cpp PrivateMembers.hpp PrivateMembers.inl \ + SingletonHolder.hpp SingletonHolder.inl + +pkginclude_HEADERS = \ + CreationStatic.hpp \ + CreationUsingNew.hpp \ + LifetimeDefault.hpp \ + LifetimeLibrary.hpp LifetimeLibrary.inl \ + LifetimeWithLongevity.hpp LifetimeWithLongevity.inl \ + PrivateMembers.hpp PrivateMembers.inl \ + SingletonHolder.hpp SingletonHolder.inl + +pkgincludedir=$(includedir)/utilspp/singleton + diff --git a/utilspp/utilspp/singleton/PrivateMembers.cpp b/utilspp/utilspp/singleton/PrivateMembers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..901c9bcc1de5cca25b5d5d2d7b3c2ee93df7c04b --- /dev/null +++ b/utilspp/utilspp/singleton/PrivateMembers.cpp @@ -0,0 +1,46 @@ +#include <cstdlib> + +#include "PrivateMembers.hpp" + +utilspp::PrivateMembers::TrackerArray + utilspp::PrivateMembers::mTrackerArray = NULL; + +int utilspp::PrivateMembers::mNbElements = 0; + +utilspp::PrivateMembers::LifetimeTracker::LifetimeTracker( unsigned int + longevity ) +: +mLongevity( longevity ) +{} + +utilspp::PrivateMembers::LifetimeTracker::~LifetimeTracker() +{} + +bool +utilspp::PrivateMembers::LifetimeTracker::compare( + const LifetimeTracker *l, + const LifetimeTracker *r + ) +{ + return l->mLongevity < r->mLongevity; +} + +void +utilspp::PrivateMembers::atExitFunc() +{ + assert((mTrackerArray != NULL) && + (mNbElements > 0)); + + //Pick the element at the top of the stack. + LifetimeTracker* top = mTrackerArray[mNbElements - 1]; + + //Remove that object off the stack. + //Don't check errors-realloc with less memory, cause that can't fail. + mTrackerArray = static_cast< + utilspp::PrivateMembers::TrackerArray >(std::realloc(mTrackerArray, + --mNbElements)); + + //Destroy the element. + delete top; +} + diff --git a/utilspp/utilspp/singleton/PrivateMembers.hpp b/utilspp/utilspp/singleton/PrivateMembers.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b1fb8cd22e7b9d7356a9e57fa735c1e4f0ff91e8 --- /dev/null +++ b/utilspp/utilspp/singleton/PrivateMembers.hpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PRIVATE_MEMBERS_HPP +#define PRIVATE_MEMBERS_HPP + +#include <cassert> + +namespace utilspp +{ + namespace PrivateMembers + { + /** + * Helper class for utils::setLongevity + */ + class LifetimeTracker + { + public: + LifetimeTracker( unsigned int longevity ); + virtual ~LifetimeTracker(); + static bool compare( + const LifetimeTracker *l, + const LifetimeTracker *r + ); + + private: + unsigned int mLongevity; + }; + + typedef LifetimeTracker** TrackerArray; + + extern TrackerArray mTrackerArray; + extern int mNbElements; + + /** + * Helper class for Destroyer + */ + template< typename T > + struct Deleter + { + void deleteObject( T *obj ); + }; + + /** + * Concrete lifetime tracker for objects of type T + */ + template< typename T, typename TDestroyer > + class ConcreteLifetimeTracker : public LifetimeTracker + { + public: + ConcreteLifetimeTracker(T *obj, unsigned int longevity, TDestroyer d); + + ~ConcreteLifetimeTracker(); + + private: + T* mTracked; + TDestroyer mDestroyer; + }; + + void atExitFunc(); + + template <class T> + struct adapter + { + void operator()(T*); + void (*mFunc)(); + }; + }; +}; + +#include "PrivateMembers.inl" + +#endif diff --git a/utilspp/utilspp/singleton/PrivateMembers.inl b/utilspp/utilspp/singleton/PrivateMembers.inl new file mode 100644 index 0000000000000000000000000000000000000000..8f3609416cd2e78a4995ab0594b62c0a73729237 --- /dev/null +++ b/utilspp/utilspp/singleton/PrivateMembers.inl @@ -0,0 +1,30 @@ + +template< typename T > +void +utilspp::PrivateMembers::Deleter< T >::deleteObject( T *obj ) +{ + delete obj; +} + +template< typename T, typename TDestroyer > +utilspp::PrivateMembers::ConcreteLifetimeTracker< T, TDestroyer >::ConcreteLifetimeTracker( + T *obj, unsigned int longevity, TDestroyer d) +: LifetimeTracker( longevity ) +, mTracked( obj ) +, mDestroyer( d ) +{} + +template< typename T, typename TDestroyer > +utilspp::PrivateMembers::ConcreteLifetimeTracker< T, TDestroyer >::~ConcreteLifetimeTracker() +{ + mDestroyer( mTracked ); +} + + +template < typename T > +void +utilspp::PrivateMembers::adapter< T >::operator()(T*) +{ + return (*mFunc)(); +} + diff --git a/utilspp/utilspp/singleton/SingletonHolder.hpp b/utilspp/utilspp/singleton/SingletonHolder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d773cd8c42532536b2e5210c008173f4ec0ed172 --- /dev/null +++ b/utilspp/utilspp/singleton/SingletonHolder.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLETON_HOLDER_HPP +#define SINGLETON_HOLDER_HPP + +#include <cassert> + +#include "CreationUsingNew.hpp" +#include "LifetimeDefault.hpp" +#include "LifetimeWithLongevity.hpp" +#include "../ThreadingSingle.hpp" + +namespace utilspp +{ + template + < class T, + template < class > class CreationPolicy = utilspp::CreationUsingNew, + template < class > class LifetimePolicy = utilspp::LifetimeDefault, + template < class > class ThreadingModel = utilspp::ThreadingSingle > + class SingletonHolder + { + public: + //the accessor method. + static T& instance(); + static void makeInstance(); + static void terminate(); + + protected: + //protected to be sure that nobody may create one by himself. + SingletonHolder(); + + private: + static void destroySingleton(); + + private: + typedef typename ThreadingModel< T * >::VolatileType InstanceType; + static InstanceType mInstance; + static bool mDestroyed; + }; + +} + +#include "SingletonHolder.inl" + +#endif diff --git a/utilspp/utilspp/singleton/SingletonHolder.inl b/utilspp/utilspp/singleton/SingletonHolder.inl new file mode 100644 index 0000000000000000000000000000000000000000..84f27bea9feb7ea73475d31fd5903df56b5c72a8 --- /dev/null +++ b/utilspp/utilspp/singleton/SingletonHolder.inl @@ -0,0 +1,126 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLETON_HOLDER_INL +#define SINGLETON_HOLDER_INL + +template +< +class T, +template < class > class CreationPolicy, +template < class > class LifetimePolicy, +template < class > class ThreadingModel +> +T& +utilspp::SingletonHolder +< +T, +CreationPolicy, +LifetimePolicy, +ThreadingModel +> +::instance() +{ + if ( mInstance == NULL ) + { + makeInstance(); + } + + return ( *mInstance ); +}; + +template +< +class T, +template < class > class CreationPolicy, +template < class > class LifetimePolicy, +template < class > class ThreadingModel +> +void +utilspp::SingletonHolder +< +T, +CreationPolicy, +LifetimePolicy, +ThreadingModel +>::makeInstance() +{ + if ( mInstance == NULL ) + { + typename ThreadingModel< T >::lock guard; + (void)guard; + + if ( mInstance == NULL ) { + if ( mDestroyed ) + { + LifetimePolicy< T >::onDeadReference(); + mDestroyed = false; + } + + mInstance = CreationPolicy< T >::create(); + LifetimePolicy< T >::scheduleDestruction( mInstance, &destroySingleton ); + } + } +} + +template +< +class T, +template < class > class CreationPolicy, +template < class > class LifetimePolicy, +template < class > class ThreadingModel +> +void +utilspp::SingletonHolder +< +T, +CreationPolicy, +LifetimePolicy, +ThreadingModel +> +::destroySingleton() +{ + assert( !mDestroyed ); + CreationPolicy< T >::destroy( mInstance ); + mInstance = NULL; + mDestroyed = true; +} + +template < class T, +template < class > class C, +template < class > class L, +template < class > class M +> +typename utilspp::SingletonHolder< T, C, L, M>::InstanceType +utilspp::SingletonHolder< T, C, L, M >::mInstance; + +template +< +class T, +template < class > class C, +template < class > class L, +template < class > class M +> +bool utilspp::SingletonHolder< T, C, L, M >::mDestroyed; + +#endif