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
34template <typename T>
35[[deprecated("Preferably use the C++ `[[maybe_unused]]` attribute instead!")]] inline void
36Unused(const T &)
37{}
38#endif
39
40namespace itk
41{
48class ITKCommon_EXPORT SingletonIndex
49{
50public:
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 [[deprecated("Prefer calling the SetGlobalInstance(globalName, global, deleteFunc) overload (without the unused func "
82 "parameter)!")]] bool
83 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 *
98 static void
99 SetInstance(Self * instance);
103private:
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.
135template <typename T>
136T *
137Singleton(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
151template <typename T>
152[[deprecated("Prefer calling the Singleton(globalName, deleteFunc) overload (without the unused func parameter)!")]] T *
153Singleton(const char * globalName, std::function<void(void *)> itkNotUsed(func), std::function<void()> deleteFunc)
154{
155 return Singleton<T>(globalName, std::move(deleteFunc));
156}
157#endif
158
159} // end namespace itk
160
161#endif
Pixel-wise addition of two images.
Implementation detail.
Definition: itkSingleton.h:49
static Self * GetInstance()
void SetGlobalInstancePrivate(const char *globalName, GlobalObject globalObject)
static void SetInstance(Self *instance)
static Self * m_Instance
Definition: itkSingleton.h:129
void * GetGlobalInstancePrivate(const char *globalName)
T * GetGlobalInstance(const char *globalName)
Definition: itkSingleton.h:64
void SetGlobalInstance(const char *globalName, T *global, std::function< void()> deleteFunc)
Definition: itkSingleton.h:74
std::map< std::string, GlobalObject > m_GlobalObjects
Definition: itkSingleton.h:128
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
T * Singleton(const char *globalName, std::function< void()> deleteFunc)
Definition: itkSingleton.h:137