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
34template <typename T>
35[[deprecated("Preferably use the C++ `[[maybe_unused]]` attribute instead!")]] inline void
36Unused(const T &){};
37#endif
38
39namespace itk
40{
47class ITKCommon_EXPORT SingletonIndex
48{
49public:
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 *
97 static void
98 SetInstance(Self * instance);
102private:
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.
134template <typename T>
135T *
136Singleton(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
150template <typename T>
151[[deprecated("Prefer calling the Singleton(globalName, deleteFunc) overload (without the unused func parameter)!")]] T *
152Singleton(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
Pixel-wise addition of two images.
Implementation detail.
Definition: itkSingleton.h:48
static Self * GetInstance()
void SetGlobalInstancePrivate(const char *globalName, GlobalObject globalObject)
static void SetInstance(Self *instance)
static Self * m_Instance
Definition: itkSingleton.h:128
void * GetGlobalInstancePrivate(const char *globalName)
T * GetGlobalInstance(const char *globalName)
Definition: itkSingleton.h:63
void SetGlobalInstance(const char *globalName, T *global, std::function< void()> deleteFunc)
Definition: itkSingleton.h:73
std::map< std::string, GlobalObject > m_GlobalObjects
Definition: itkSingleton.h:127
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
T * Singleton(const char *globalName, std::function< void()> deleteFunc)
Definition: itkSingleton.h:136