Audacity 3.2.0
GlobalVariable.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file GlobalVariable.h
6
7 Paul Licameli
8
9 **********************************************************************/
10#ifndef __AUDACITY_GLOBAL_VARIABLE__
11#define __AUDACITY_GLOBAL_VARIABLE__
12
13#include <functional>
14#include <memory>
15#include <optional>
16#include <type_traits>
17#include <utility>
18
20
33template <typename Tag, typename Type, Type (*initializer)() = nullptr,
34 bool ScopedOnly = true>
36 struct dummy{ explicit dummy(){} };
37public:
39 using stored_type = Type;
40 using mutable_type = std::remove_const_t<Type>;
41
43 static stored_type& Get()
44 {
45 // Force generation of non-inline Assign, in case it needs dllexport linkage
47 return Instance();
48 }
49
51
53 [[nodiscard]]
54 static auto Set( std::conditional_t<ScopedOnly, dummy,
55 mutable_type> replacement) -> std::conditional_t<ScopedOnly, void,
57 {
58 if constexpr (!ScopedOnly)
59 return Assign(std::move(replacement));
60 }
61
63
70 class Scope
71 {
72 public:
73 explicit Scope(mutable_type value)
74 : m_previous{ Assign(std::move(value)) }
75 {}
76 Scope(Scope &&other) = default;
77 Scope &operator=(Scope &&other) = default;
79 {
80 if constexpr (ScopedOnly)
81 Assign(std::move(m_previous));
82 else if (m_previous)
83 Assign(std::move(*m_previous));
84 }
86 void Commit()
87 {
88 static_assert(!ScopedOnly);
89 m_previous.reset();
90 }
91 bool HasValue() const
92 {
93 if constexpr (ScopedOnly)
94 return true;
95 else
96 return m_previous.has_value();
97 }
98
99 private:
100 std::conditional_t<ScopedOnly, mutable_type, std::optional<mutable_type>>
102 };
103
117 struct Initializer { Initializer() { Instance(); } };
118
119private:
121 GlobalVariable() = delete;
122
125 {
126 static_assert(!std::is_reference_v<stored_type>);
127 if constexpr (initializer != nullptr) {
128 static mutable_type instance{ initializer() };
129 return instance;
130 }
131 else {
132 static mutable_type instance;
133 return instance;
134 }
135 }
136
137 static mutable_type Assign(mutable_type &&replacement)
138 {
139 auto &instance = Instance();
140 auto result = std::move(instance);
141 instance = std::move(replacement);
142 return result;
143 }
144};
145
147template<typename Tag, typename Signature, auto... Options>
149 : public GlobalVariable<Tag, const std::function<Signature>, Options...>
150{
151public:
152 using result_type = typename std::function<Signature>::result_type;
153
155
157 template<typename... Arguments>
158 static result_type Call(Arguments &&...arguments)
159 {
160 auto &fn = GlobalHook::Get();
161 if (fn)
162 return fn(std::forward<Arguments>(arguments)...);
163 else if constexpr (std::is_void_v<result_type>)
164 return;
165 else
166 return result_type{};
167 }
168};
169
170#endif
static const auto fn
Global function-valued variable, adding a convenient Call()
typename std::function< Signature >::result_type result_type
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
RAII guard for temporary installation of a value; movable.
std::conditional_t< ScopedOnly, mutable_type, std::optional< mutable_type > > m_previous
Scope(mutable_type value)
Scope & operator=(Scope &&other)=default
Scope(Scope &&other)=default
Class template to generate global variables.
GlobalVariable()=delete
Use static functions only. Don't directly construct this.
static mutable_type & Instance()
Generate the static variable.
std::remove_const_t< Type > mutable_type
static mutable_type Assign(mutable_type &&replacement)
static auto Set(std::conditional_t< ScopedOnly, dummy, mutable_type > replacement) -> std::conditional_t< ScopedOnly, void, mutable_type >
Move in a new value, move out and return the previous.
static stored_type & Get()
Get the installed value.
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:535
STL namespace.
Can guarantee that the global variable's lifetime encloses those of other objects of static duration.