Skip to content

Commit a16a413

Browse files
authored
ofSingleton: tracking upstream (more symmetry/readability) (#7669)
#changelog #core
1 parent cb9281f commit a16a413

3 files changed

Lines changed: 69 additions & 59 deletions

File tree

libs/openFrameworks/utils/ofRandomEngine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <random>
55
#include <glm/glm.hpp>
66

7-
#include "ofSingleton.hpp"
7+
#include "ofSingleton.h"
88
#include "ofMath.h"
99

1010
namespace of::random
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#ifndef OF_SINGLETON_H_
2+
#define OF_SINGLETON_H_
3+
4+
// atomic C++17 DCLP CRTP singleton adapted by burton@artificiel.org from
5+
// https://github.com/jimmy-park/singleton/blob/main/include/singleton_dclp.hpp (as of df5e4a2)
6+
7+
#include <atomic>
8+
#include <cassert>
9+
#include <shared_mutex>
10+
#include <utility>
11+
12+
namespace of::utils {
13+
14+
template <typename Derived>
15+
class Singleton {
16+
public:
17+
template <typename... Args>
18+
static void construct(Args &&... args) {
19+
struct Dummy : public Derived {
20+
using Derived::Derived;
21+
void prohibit_construct_from_derived() const override { }
22+
};
23+
24+
using Instance = Dummy;
25+
if (!instance_.load(std::memory_order_acquire)) {
26+
std::lock_guard lock { mutex_ };
27+
if (!instance_.load(std::memory_order_relaxed)) {
28+
instance_.store(new Instance { std::forward<Args>(args)... }, std::memory_order_release);
29+
}
30+
}
31+
}
32+
33+
static void destruct() {
34+
if (instance_.load(std::memory_order_acquire)) {
35+
std::lock_guard lock { mutex_ };
36+
if (auto * the_instance = instance_.load(std::memory_order_relaxed); the_instance) {
37+
delete the_instance;
38+
instance_.store(nullptr, std::memory_order_release);
39+
}
40+
}
41+
}
42+
43+
static Derived * instance() {
44+
auto * the_instance = instance_.load(std::memory_order_acquire);
45+
if (!the_instance) {
46+
std::shared_lock lock { mutex_ };
47+
the_instance = instance_.load(std::memory_order_relaxed);
48+
assert(the_instance);
49+
}
50+
return the_instance;
51+
}
52+
53+
protected:
54+
Singleton() = default;
55+
Singleton(const Singleton &) = delete;
56+
Singleton(Singleton &&) noexcept = delete;
57+
Singleton & operator=(const Singleton &) = delete;
58+
Singleton & operator=(Singleton &&) noexcept = delete;
59+
virtual ~Singleton() = default;
60+
61+
private:
62+
virtual void prohibit_construct_from_derived() const = 0;
63+
inline static std::atomic<Derived *> instance_ { nullptr };
64+
inline static std::shared_mutex mutex_;
65+
};
66+
67+
} // end namespace of::utils
68+
#endif // OF_SINGLETON_H_

libs/openFrameworks/utils/ofSingleton.hpp

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)