ITK  6.0.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 {}
38 #endif
39 
40 namespace itk
41 {
48 class ITKCommon_EXPORT SingletonIndex
49 {
50 public:
53 
54 #ifndef ITK_LEGACY_REMOVE
55  using SingletonData [[deprecated("The internal representation of the singleton data is private, and may not "
56  "correspond with SingletonData anymore.")]] =
57  std::map<std::string, std::tuple<void *, std::function<void(void *)>, std::function<void()>>>;
58 #endif
59 
60  // obtain a global registered in the singleton index under the
61  // globalName, if unknown then nullptr will be returned.
62  template <typename T>
63  T *
64  GetGlobalInstance(const char * globalName)
65  {
66  return static_cast<T *>(this->GetGlobalInstancePrivate(globalName));
67  }
68 
69 
70  // It is assumed that the global will remain valid until the start
71  // of globals being destroyed.
72  template <typename T>
73  void
74  SetGlobalInstance(const char * globalName, T * global, std::function<void()> deleteFunc)
75  {
76  this->SetGlobalInstancePrivate(globalName, GlobalObject{ global, std::move(deleteFunc) });
77  }
78 
79 #ifndef ITK_FUTURE_LEGACY_REMOVE
80  template <typename T>
81  ITK_FUTURE_DEPRECATED("Prefer calling the SetGlobalInstance(globalName, global, deleteFunc) overload (without the "
82  "unused func parameter)!")
83  bool SetGlobalInstance(const char * globalName,
84  T * global,
85  std::function<void(void *)> itkNotUsed(func),
86  std::function<void()> deleteFunc)
87  {
88  this->SetGlobalInstance(globalName, global, std::move(deleteFunc));
89  // Just returns true for backward compatibility (legacy only).
90  return true;
91  }
92 #endif
93 
96  static Self *
97  GetInstance();
98  static void
99  SetInstance(Self * instance);
100  ~SingletonIndex();
103 private:
104  // Internal struct to store the instance pointer and the delete function object of a global object.
106  {
107  void * Instance{};
108  std::function<void()> DeleteFunc{};
109  };
110 
111  // may return nullptr if string is not registered already
112  //
113  // access something like a std::map<std::string, void *> or
114  // registered globals, it may be possible to restrict the held
115  // classes to be derived from itk::LightObject, so dynamic cast can
116  // work, and could use some type of Holder<T> class for intrinsic types
117  void *
118  GetGlobalInstancePrivate(const char * globalName);
119 
120  // global is added or set to the singleton index under globalName
121  void
122  SetGlobalInstancePrivate(const char * globalName, GlobalObject globalObject);
123 
128  std::map<std::string, GlobalObject> m_GlobalObjects;
129  static Self * m_Instance;
130  // static SingletonIndexPrivate * m_GlobalSingleton;
131 };
132 
133 
134 // A wrapper for a global variable registered in the singleton index.
135 template <typename T>
136 T *
137 Singleton(const char * globalName, std::function<void()> deleteFunc)
138 {
139  [[maybe_unused]] static SingletonIndex * singletonIndex = SingletonIndex::GetInstance();
140  T * instance = SingletonIndex::GetInstance()->GetGlobalInstance<T>(globalName);
141  if (instance == nullptr)
142  {
143  instance = new T;
144  SingletonIndex::GetInstance()->SetGlobalInstance<T>(globalName, instance, std::move(deleteFunc));
145  }
146  return instance;
147 }
148 
149 
150 #ifndef ITK_FUTURE_LEGACY_REMOVE
151 template <typename T>
152 ITK_FUTURE_DEPRECATED(
153  "Prefer calling the Singleton(globalName, deleteFunc) overload (without the unused func parameter)!")
154 T * Singleton(const char * globalName, std::function<void(void *)> itkNotUsed(func), std::function<void()> deleteFunc)
155 {
156  return Singleton<T>(globalName, std::move(deleteFunc));
157 }
158 #endif
159 
160 } // end namespace itk
161 
162 #endif
itk::SingletonIndex::m_Instance
static Self * m_Instance
Definition: itkSingleton.h:129
itk::SingletonIndex::GlobalObject
Definition: itkSingleton.h:105
itk::SingletonIndex::m_GlobalObjects
std::map< std::string, GlobalObject > m_GlobalObjects
Definition: itkSingleton.h:128
itkSingletonMacro.h
itk::Singleton
T * Singleton(const char *globalName, std::function< void()> deleteFunc)
Definition: itkSingleton.h:137
itkMacro.h
itk::SingletonIndex::GetInstance
static Self * GetInstance()
itk::SingletonIndex
Implementation detail.
Definition: itkSingleton.h:48
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnatomicalOrientation.h:29
itk::SingletonIndex::GetGlobalInstance
T * GetGlobalInstance(const char *globalName)
Definition: itkSingleton.h:64
AddImageFilter
Definition: itkAddImageFilter.h:81
itk::SingletonIndex::SetGlobalInstance
void SetGlobalInstance(const char *globalName, T *global, std::function< void()> deleteFunc)
Definition: itkSingleton.h:74