ctkSingleton.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) 2010 Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. #ifndef __ctkSingleton_h
  15. #define __ctkSingleton_h
  16. //
  17. /// Singleton definition and declaration helpers
  18. //
  19. /// See http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
  20. /// and http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
  21. //
  22. /// Inspired from VTK/Utilities/kwsys/SystemTools class
  23. //
  24. //-----------------------------------------------------------------------------
  25. /// Should be included as a class protected member
  26. //
  27. #define CTK_SINGLETON_DECLARE(NAME) \
  28. static NAME* Instance; \
  29. static void classInitialize(); \
  30. static void classFinalize(); \
  31. friend class NAME##Initialize;
  32. //-----------------------------------------------------------------------------
  33. /// Help macro allowing to declare the utility class to make sure
  34. /// NAME is initialized before it is used.
  35. //
  36. /// Should be added at the bottom of the header file, after the class declaration
  37. //
  38. /// The instance (NAME##Initializer) will show up in any translation unit
  39. /// that uses NAME. It will make sure NAME is initialized before it is used.
  40. ///
  41. #define CTK_SINGLETON_DECLARE_INITIALIZER(EXPORT_DIRECTIVE,NAME) \
  42. class EXPORT_DIRECTIVE NAME##Initialize \
  43. { \
  44. public: \
  45. typedef NAME##Initialize Self; \
  46. \
  47. NAME##Initialize(); \
  48. ~NAME##Initialize(); \
  49. private: \
  50. static unsigned int Count; \
  51. }; \
  52. \
  53. static NAME##Initialize NAME##Initializer;
  54. //-----------------------------------------------------------------------------
  55. //
  56. /// Implementation of NAME##Initialize class.
  57. //
  58. /// Note: NAME##Initialize::Count and NAME::Instance Must NOT be initialized.
  59. /// Default initialization to zero is necessary.
  60. //
  61. #define CTK_SINGLETON_DEFINE_INITIALIZER(NAME) \
  62. NAME##Initialize::NAME##Initialize() \
  63. { \
  64. if(++Self::Count == 1) \
  65. { NAME::classInitialize(); } \
  66. } \
  67. \
  68. NAME##Initialize::~NAME##Initialize() \
  69. { \
  70. if(--Self::Count == 0) \
  71. { NAME::classFinalize(); } \
  72. } \
  73. \
  74. unsigned int NAME##Initialize::Count; \
  75. NAME* NAME::Instance;
  76. //----------------------------------------------------------------------------
  77. //
  78. /// This should be added at the end of the CXX file
  79. //
  80. #define CTK_SINGLETON_DEFINE(NAME) \
  81. void NAME::classInitialize() \
  82. { \
  83. Self::Instance = new NAME; \
  84. } \
  85. \
  86. void NAME::classFinalize() \
  87. { \
  88. delete Self::Instance; \
  89. } \
  90. \
  91. CTK_SINGLETON_DEFINE_INITIALIZER(NAME)
  92. //----------------------------------------------------------------------------
  93. //
  94. /// Helper macro
  95. //
  96. /// TODO Documentation
  97. //
  98. #define CTK_SINGLETON_DECLARE_PRIVATE(PUB) \
  99. PUB(const PUB&); \
  100. void operator=(const PUB&); \
  101. CTK_DECLARE_PRIVATE(PUB);
  102. #endif //__ctkSingleton_h