123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /*=========================================================================
- Library: CTK
- Copyright (c) Kitware Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0.txt
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- =========================================================================*/
- #ifndef __ctkSingleton_h
- #define __ctkSingleton_h
- //
- /// \ingroup Core
- /// @{
- /// Singleton definition and declaration helpers
- //
- /// See http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
- /// and http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
- //
- /// Inspired from VTK/Utilities/kwsys/SystemTools class
- //
- //-----------------------------------------------------------------------------
- /// Should be included as a class protected member
- #define CTK_SINGLETON_DECLARE(NAME) \
- static NAME* Instance; \
- static void classInitialize(); \
- static void classFinalize(); \
- friend class NAME##Initialize; \
- typedef NAME Self;
-
- //-----------------------------------------------------------------------------
- /// Help macro allowing to declare the utility class to make sure
- /// NAME is initialized before it is used.
- //
- /// Should be added at the bottom of the header file, after the class declaration
- //
- /// The instance (NAME##%Initializer) will show up in any translation unit
- /// that uses NAME. It will make sure NAME is initialized before it is used.
- ///
- #define CTK_SINGLETON_DECLARE_INITIALIZER(EXPORT_DIRECTIVE,NAME) \
- class EXPORT_DIRECTIVE NAME##Initialize \
- { \
- public: \
- typedef NAME##Initialize Self; \
- \
- NAME##Initialize(); \
- ~NAME##Initialize(); \
- private: \
- static unsigned int Count; \
- }; \
- \
- static NAME##Initialize NAME##Initializer;
- //-----------------------------------------------------------------------------
- //
- /// Implementation of %NAME##%Initialize class.
- //
- /// Note: NAME##%Initialize::%Count and NAME::%Instance Must NOT be initialized.
- /// Default initialization to zero is necessary.
- //
- #define CTK_SINGLETON_DEFINE_INITIALIZER(NAME) \
- NAME##Initialize::NAME##Initialize() \
- { \
- if(++Self::Count == 1) \
- { NAME::classInitialize(); } \
- } \
- \
- NAME##Initialize::~NAME##Initialize() \
- { \
- if(--Self::Count == 0) \
- { NAME::classFinalize(); } \
- } \
- \
- unsigned int NAME##Initialize::Count; \
- NAME* NAME::Instance;
- //----------------------------------------------------------------------------
- //
- /// This should be added at the end of the CPP file
- //
- #define CTK_SINGLETON_DEFINE(NAME) \
- void NAME::classInitialize() \
- { \
- Self::Instance = new NAME; \
- } \
- \
- void NAME::classFinalize() \
- { \
- delete Self::Instance; \
- } \
- \
- CTK_SINGLETON_DEFINE_INITIALIZER(NAME)
- ///@}
- #endif //__ctkSingleton_h
|