Mantid
Loading...
Searching...
No Matches
SingletonHolder.h
Go to the documentation of this file.
1#pragma once
2
4// The Loki Library
5// Copyright (c) 2001 by Andrei Alexandrescu
6// This code accompanies the book:
7// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
8// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
9// Permission to use, copy, modify, distribute and sell this software for any
10// purpose is hereby granted without fee, provided that the above copyright
11// notice appear in all copies and that both that copyright notice and this
12// permission notice appear in supporting documentation.
13// The author or Addison-Wesley Longman make no representations about the
14// suitability of this software for any purpose. It is provided "as is"
15// without express or implied warranty.
17
19// Simplified from the original code, to just work for simple singletons
20// Removed all the code relating to the creation/destruction, threading and
21// lifetime policies.
23
24#include "MantidKernel/DllConfig.h"
25#include <cassert>
26#include <cstdlib>
27#include <functional>
28#include <mutex>
29
30namespace Mantid {
31namespace Kernel {
32
34using SingletonDeleterFn = std::function<void()>;
35
38MANTID_KERNEL_DLL void deleteOnExit(const SingletonDeleterFn &func);
39
41template <typename T> class SingletonHolder {
42public:
43 using HeldType = T;
44
45 SingletonHolder() = delete;
46
47 static T &Instance();
48
49private:
50#ifndef NDEBUG
51 static bool destroyed;
52#endif
53};
54
55// Static field initializers
56#ifndef NDEBUG
57template <typename T> bool SingletonHolder<T>::destroyed = false;
58#endif
59
67template <typename T> struct CreateUsingNew {
70 static T *create() { return new T; }
73 static void destroy(T *p) { delete p; }
74};
75
83template <typename T>
84#if defined(_MSC_VER)
85__declspec(noinline)
86#endif
87 T &
88#if defined(__GNUC__) // covers clang too
89 __attribute__((noinline))
90#endif
92 // Initialiazing a local static is thread-safe in C++11
93 // The inline lambda call is used to create the singleton once
94 // and register an atexit function to delete it
95 static T *instance = []() {
96 auto local = CreateUsingNew<T>::create();
98#ifndef NDEBUG
99 destroyed = true;
100#endif
102 }));
103 return local;
104 }();
105#ifndef NDEBUG
106 assert(!destroyed);
107#endif
108 return *instance;
109}
110
111} // namespace Kernel
112} // namespace Mantid
Manage the lifetime of a class intended to be a singleton.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::function< void()> SingletonDeleterFn
Type of deleter function.
MANTID_KERNEL_DLL void deleteOnExit(const SingletonDeleterFn &func)
Register the given deleter function to be called at exit.
Helper class which provides the Collimation Length for SANS instruments.
Policy class controlling creation of the singleton Implementation classes should mark their default c...
static void destroy(T *p)
delete an object instantiated using Create
static T * create()
create an object using the new operator