File: itkSingleton.h

package info (click to toggle)
insighttoolkit5 5.4.3-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 704,384 kB
  • sloc: cpp: 783,592; ansic: 628,724; xml: 44,704; fortran: 34,250; python: 22,874; sh: 4,078; pascal: 2,636; lisp: 2,158; makefile: 464; yacc: 328; asm: 205; perl: 203; lex: 146; tcl: 132; javascript: 98; csh: 81
file content (159 lines) | stat: -rw-r--r-- 5,538 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         https://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkSingleton_h
#define itkSingleton_h

#include "itkMacro.h"
#include "itkSingletonMacro.h"
#include <map>
#include <functional>

#ifndef ITK_FUTURE_LEGACY_REMOVE
/** \brief A function which does nothing
 * \deprecated Preferably use the C++ `[[maybe_unused]]` attribute instead!
 *
 * This function is to be used to mark parameters as unused to suppress
 * compiler warning. It can be used when the parameter needs to be named
 * (i.e. itkNotUsed cannot be used) but is not always used.
 */
template <typename T>
[[deprecated("Preferably use the C++ `[[maybe_unused]]` attribute instead!")]] inline void
Unused(const T &){};
#endif

namespace itk
{
/** \class SingletonIndex
 * \brief Implementation detail.
 *
 * \ingroup ITKCommon
 */

class ITKCommon_EXPORT SingletonIndex
{
public:
  /** Standard class types. */
  using Self = SingletonIndex;

#ifndef ITK_LEGACY_REMOVE
  using SingletonData [[deprecated("The internal representation of the singleton data is private, and may not "
                                   "correspond with SingletonData anymore.")]] =
    std::map<std::string, std::tuple<void *, std::function<void(void *)>, std::function<void()>>>;
#endif

  // obtain a global registered in the singleton index under the
  // globalName, if unknown then nullptr will be returned.
  template <typename T>
  T *
  GetGlobalInstance(const char * globalName)
  {
    return static_cast<T *>(this->GetGlobalInstancePrivate(globalName));
  }


  // It is assumed that the global will remain valid until the start
  // of globals being destroyed.
  template <typename T>
  void
  SetGlobalInstance(const char * globalName, T * global, std::function<void()> deleteFunc)
  {
    this->SetGlobalInstancePrivate(globalName, GlobalObject{ global, std::move(deleteFunc) });
  }

#ifndef ITK_FUTURE_LEGACY_REMOVE
  template <typename T>
  [[deprecated("Prefer calling the SetGlobalInstance(globalName, global, deleteFunc) overload (without the unused func "
               "parameter)!")]] bool
  SetGlobalInstance(const char *                globalName,
                    T *                         global,
                    std::function<void(void *)> itkNotUsed(func),
                    std::function<void()>       deleteFunc)
  {
    this->SetGlobalInstance(globalName, global, std::move(deleteFunc));
    // Just returns true for backward compatibility (legacy only).
    return true;
  }
#endif

  /** Set/Get the pointer to GlobalSingleton.
   * Note that SetGlobalSingleton is not concurrent thread safe. */
  static Self *
  GetInstance();
  static void
  SetInstance(Self * instance);
  ~SingletonIndex();

private:
  // Internal struct to store the instance pointer and the delete function object of a global object.
  struct GlobalObject
  {
    void *                Instance{};
    std::function<void()> DeleteFunc{};
  };

  // may return nullptr if string is not registered already
  //
  // access something like a std::map<std::string, void *> or
  // registered globals, it may be possible to restrict the held
  // classes to be derived from itk::LightObject, so dynamic cast can
  // work, and could use some type of Holder<T> class for intrinsic types
  void *
  GetGlobalInstancePrivate(const char * globalName);

  // global is added or set to the singleton index under globalName
  void
  SetGlobalInstancePrivate(const char * globalName, GlobalObject globalObject);

  /** The static GlobalSingleton. This is initialized to nullptr as the first
   * stage of static initialization. It is then populated on the first call to
   * itk::Singleton::Modified() but it can be overridden with SetGlobalSingleton().
   * */
  std::map<std::string, GlobalObject> m_GlobalObjects;
  static Self *                       m_Instance;
  //  static SingletonIndexPrivate * m_GlobalSingleton;
};


// A wrapper for a global variable registered in the singleton index.
template <typename T>
T *
Singleton(const char * globalName, std::function<void()> deleteFunc)
{
  [[maybe_unused]] static SingletonIndex * singletonIndex = SingletonIndex::GetInstance();
  T *                                      instance = SingletonIndex::GetInstance()->GetGlobalInstance<T>(globalName);
  if (instance == nullptr)
  {
    instance = new T;
    SingletonIndex::GetInstance()->SetGlobalInstance<T>(globalName, instance, std::move(deleteFunc));
  }
  return instance;
}


#ifndef ITK_FUTURE_LEGACY_REMOVE
template <typename T>
[[deprecated("Prefer calling the Singleton(globalName, deleteFunc) overload (without the unused func parameter)!")]] T *
Singleton(const char * globalName, std::function<void(void *)> itkNotUsed(func), std::function<void()> deleteFunc)
{
  return Singleton<T>(globalName, std::move(deleteFunc));
}
#endif

} // end namespace itk

#endif