ctkSingleton.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. All rights reserved.
  5. Distributed under a BSD License. See LICENSE.txt file.
  6. This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the above copyright notice for more information.
  9. =========================================================================*/
  10. #ifndef __ctkSingleton_h
  11. #define __ctkSingleton_h
  12. //
  13. /// Singleton definition and declaration helpers
  14. //
  15. /// See http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
  16. /// and http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
  17. //
  18. /// Inspired from VTK/Utilities/kwsys/SystemTools class
  19. //
  20. //-----------------------------------------------------------------------------
  21. /// Should be included as a class protected member
  22. //
  23. #define CTK_SINGLETON_DECLARE(NAME) \
  24. static NAME* Instance; \
  25. static void classInitialize(); \
  26. static void classFinalize(); \
  27. friend class NAME##Initialize;
  28. //-----------------------------------------------------------------------------
  29. /// Help macro allowing to declare the utility class to make sure
  30. /// NAME is initialized before it is used.
  31. //
  32. /// Should be added at the bottom of the header file, after the class declaration
  33. //
  34. /// The instance (NAME##Initializer) will show up in any translation unit
  35. /// that uses NAME. It will make sure NAME is initialized before it is used.
  36. ///
  37. #define CTK_SINGLETON_DECLARE_INITIALIZER(EXPORT_DIRECTIVE,NAME) \
  38. class EXPORT_DIRECTIVE NAME##Initialize \
  39. { \
  40. public: \
  41. typedef NAME##Initialize Self; \
  42. \
  43. NAME##Initialize(); \
  44. ~NAME##Initialize(); \
  45. private: \
  46. static unsigned int Count; \
  47. }; \
  48. \
  49. static NAME##Initialize NAME##Initializer;
  50. //-----------------------------------------------------------------------------
  51. //
  52. /// Implementation of NAME##Initialize class.
  53. //
  54. /// Note: NAME##Initialize::Count and NAME::Instance Must NOT be initialized.
  55. /// Default initialization to zero is necessary.
  56. //
  57. #define CTK_SINGLETON_DEFINE_INITIALIZER(NAME) \
  58. NAME##Initialize::NAME##Initialize() \
  59. { \
  60. if(++Self::Count == 1) \
  61. { NAME::classInitialize(); } \
  62. } \
  63. \
  64. NAME##Initialize::~NAME##Initialize() \
  65. { \
  66. if(--Self::Count == 0) \
  67. { NAME::classFinalize(); } \
  68. } \
  69. \
  70. unsigned int NAME##Initialize::Count; \
  71. NAME* NAME::Instance;
  72. //----------------------------------------------------------------------------
  73. //
  74. /// This should be added at the end of the CXX file
  75. //
  76. #define CTK_SINGLETON_DEFINE(NAME) \
  77. void NAME::classInitialize() \
  78. { \
  79. Self::Instance = new NAME; \
  80. } \
  81. \
  82. void NAME::classFinalize() \
  83. { \
  84. delete Self::Instance; \
  85. } \
  86. \
  87. CTK_SINGLETON_DEFINE_INITIALIZER(NAME)
  88. //----------------------------------------------------------------------------
  89. //
  90. /// Helper macro
  91. //
  92. /// TODO Documentation
  93. //
  94. #define CTK_SINGLETON_DECLARE_PRIVATE(PUB) \
  95. PUB(const PUB&); \
  96. void operator=(const PUB&); \
  97. CTK_DECLARE_PRIVATE(PUB);
  98. #endif //__ctkSingleton_h