ITK  5.4.0
Insight Toolkit
itkSingleton.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright NumFOCUS
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * https://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkSingleton_h
19 #define itkSingleton_h
20 
21 #include "itkMacro.h"
22 #include "itkSingletonMacro.h"
23 #include <map>
24 #include <functional>
25 
26 #ifndef ITK_FUTURE_LEGACY_REMOVE
27 
34 template <typename T>
35 [[deprecated("Preferably use the C++ `[[maybe_unused]]` attribute instead!")]] inline void
36 Unused(const T &){};
37 #endif
38 
39 namespace itk
40 {
47 class ITKCommon_EXPORT SingletonIndex
48 {
49 public:
52 
53 #ifndef ITK_LEGACY_REMOVE
54  using SingletonData [[deprecated("The internal representation of the singleton data is private, and may not "
55  "correspond with SingletonData anymore.")]] =
56  std::map<std::string, std::tuple<void *, std::function<void(void *)>, std::function<void()>>>;
57 #endif
58 
59  // obtain a global registered in the singleton index under the
60  // globalName, if unknown then nullptr will be returned.
61  template <typename T>
62  T *
63  GetGlobalInstance(const char * globalName)
64  {
65  return static_cast<T *>(this->GetGlobalInstancePrivate(globalName));
66  }
67 
68 
69  // It is assumed that the global will remain valid until the start
70  // of globals being destroyed.
71  template <typename T>
72  void
73  SetGlobalInstance(const char * globalName, T * global, std::function<void()> deleteFunc)
74  {
75  this->SetGlobalInstancePrivate(globalName, GlobalObject{ global, std::move(deleteFunc) });
76  }
77 
78 #ifndef ITK_FUTURE_LEGACY_REMOVE
79  template <typename T>
80  [[deprecated("Prefer calling the SetGlobalInstance(globalName, global, deleteFunc) overload (without the unused func "
81  "parameter)!")]] bool
82  SetGlobalInstance(const char * globalName,
83  T * global,
84  std::function<void(void *)> itkNotUsed(func),
85  std::function<void()> deleteFunc)
86  {
87  this->SetGlobalInstance(globalName, global, std::move(deleteFunc));
88  // Just returns true for backward compatibility (legacy only).
89  return true;
90  }
91 #endif
92 
95  static Self *
96  GetInstance();
97  static void
98  SetInstance(Self * instance);
99  ~SingletonIndex();
102 private:
103  // Internal struct to store the instance pointer and the delete function object of a global object.
105  {
106  void * Instance{};
107  std::function<void()> DeleteFunc{};
108  };
109 
110  // may return nullptr if string is not registered already
111  //
112  // access something like a std::map<std::string, void *> or
113  // registered globals, it may be possible to restrict the held
114  // classes to be derived from itk::LightObject, so dynamic cast can
115  // work, and could use some type of Holder<T> class for intrinsic types
116  void *
117  GetGlobalInstancePrivate(const char * globalName);
118 
119  // global is added or set to the singleton index under globalName
120  void
121  SetGlobalInstancePrivate(const char * globalName, GlobalObject globalObject);
122 
127  std::map<std::string, GlobalObject> m_GlobalObjects;
128  static Self * m_Instance;
129  // static SingletonIndexPrivate * m_GlobalSingleton;
130 };
131 
132 
133 // A wrapper for a global variable registered in the singleton index.
134 template <typename T>
135 T *
136 Singleton(const char * globalName, std::function<void()> deleteFunc)
137 {
138  [[maybe_unused]] static SingletonIndex * singletonIndex = SingletonIndex::GetInstance();
139  T * instance = SingletonIndex::GetInstance()->GetGlobalInstance<T>(globalName);
140  if (instance == nullptr)
141  {
142  instance = new T;
143  SingletonIndex::GetInstance()->SetGlobalInstance<T>(globalName, instance, std::move(deleteFunc));
144  }
145  return instance;
146 }
147 
148 
149 #ifndef ITK_FUTURE_LEGACY_REMOVE
150 template <typename T>
151 [[deprecated("Prefer calling the Singleton(globalName, deleteFunc) overload (without the unused func parameter)!")]] T *
152 Singleton(const char * globalName, std::function<void(void *)> itkNotUsed(func), std::function<void()> deleteFunc)
153 {
154  return Singleton<T>(globalName, std::move(deleteFunc));
155 }
156 #endif
157 
158 } // end namespace itk
159 
160 #endif
itk::SingletonIndex::m_Instance
static Self * m_Instance
Definition: itkSingleton.h:128
itk::SingletonIndex::GlobalObject
Definition: itkSingleton.h:104
itk::SingletonIndex::m_GlobalObjects
std::map< std::string, GlobalObject > m_GlobalObjects
Definition: itkSingleton.h:127
itkSingletonMacro.h
itk::Singleton
T * Singleton(const char *globalName, std::function< void()> deleteFunc)
Definition: itkSingleton.h:136
itkMacro.h
itk::SingletonIndex::GetInstance
static Self * GetInstance()
itk::SingletonIndex
Implementation detail.
Definition: itkSingleton.h:47
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnnulusOperator.h:24
itk::SingletonIndex::GetGlobalInstance
T * GetGlobalInstance(const char *globalName)
Definition: itkSingleton.h:63
AddImageFilter
Definition: itkAddImageFilter.h:81
itk::SingletonIndex::SetGlobalInstance
void SetGlobalInstance(const char *globalName, T *global, std::function< void()> deleteFunc)
Definition: itkSingleton.h:73