Embedded Template Library 1.0
singleton.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2019 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_SINGLETON_INCLUDED
32#define ETL_SINGLETON_INCLUDED
33
37
38#include "platform.h"
39#include "utility.h"
40#include "error_handler.h"
41#include "file_error_numbers.h"
42#include "memory.h"
43
44namespace etl
45{
46 //*************************************************************************
48 //*************************************************************************
50 {
51 public:
52
53 singleton_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
54 : exception(reason_, file_name_, line_number_)
55 {
56 }
57 };
58
59 //*************************************************************************
61 //*************************************************************************
63 {
64 public:
65
66 singleton_not_created(string_type file_name_, numeric_type line_number_)
67 : singleton_exception(ETL_ERROR_TEXT("singleton:not created", ETL_SINGLETON_FILE_ID"A"), file_name_, line_number_)
68 {
69 }
70 };
71
72#if ETL_USING_CPP11 && !defined(ETL_SINGLETON_FORCE_CPP03_IMPLEMENTATION)
73 //*************************************************************************
76 //*************************************************************************
77 template<typename T>
78 class singleton
79 {
80 public:
81
82 using type = T;
83
84 //*************************************************************************
86 //*************************************************************************
87 template <typename... TArgs>
88 static void create(TArgs&&... args)
89 {
90 Data& data = get_data();
91
92 if (!data.valid)
93 {
94 T* p = data.storage.begin();
95 ::new (p) T(etl::forward<TArgs>(args)...);
96 data.valid = true;
97 }
98 }
99
100 //*************************************************************************
102 //*************************************************************************
103 static void destroy()
104 {
105 Data& data = get_data();
106
107 if (data.valid)
108 {
109 T* p = data.storage.begin();
110 p->~T();
111 data.valid = false;
112 }
113 }
114
115 //*************************************************************************
119 //*************************************************************************
120 static T& instance()
121 {
122 Data& data = get_data();
123
124 ETL_ASSERT(data.valid, ETL_ERROR(etl::singleton_not_created));
125
126 return *data.storage.begin();
127 }
128
129 //*************************************************************************
131 //*************************************************************************
132 static bool is_valid()
133 {
134 Data& data = get_data();
135
136 return data.valid;
137 }
138
139 private:
140
141 //*************************************************************************
143 //*************************************************************************
144 struct Data
145 {
146 Data()
147 : valid(false)
148 {
149 }
150
152 bool valid;
153 };
154
155 //*************************************************************************
157 //*************************************************************************
158 static Data& get_data()
159 {
160 static Data data;
161
162 return data;
163 }
164
165 // Disabled.
166 singleton() = delete;
167 singleton(const singleton&) = delete;
168 singleton& operator =(const singleton&) = delete;
169 };
170#else
171 //*************************************************************************
174 //*************************************************************************
175 template<typename T>
176 class singleton
177 {
178 public:
179
180 typedef T type;
181
182 //*************************************************************************
184 //*************************************************************************
185 static void create()
186 {
187 Data& data = get_data();
188
189 if (!data.valid)
190 {
191 T* p = data.storage.begin();
192 ::new (p) T();
193 data.valid = true;
194 }
195 }
196
197 //*************************************************************************
200 //*************************************************************************
201 template <typename T1>
202 static void create(const T1& p1)
203 {
204 Data& data = get_data();
205
206 if (!data.valid)
207 {
208 T* p = data.storage.begin();
209 ::new (p) T(p1);
210 data.valid = true;
211 }
212 }
213
214 //*************************************************************************
217 //*************************************************************************
218 template <typename T1, typename T2>
219 static void create(const T1& p1, const T2& p2)
220 {
221 Data& data = get_data();
222
223 if (!data.valid)
224 {
225 T* p = data.storage.begin();
226 ::new (p) T(p1, p2);
227 data.valid = true;
228 }
229 }
230
231 //*************************************************************************
234 //*************************************************************************
235 template <typename T1, typename T2, typename T3>
236 static void create(const T1& p1, const T2& p2, const T3& p3)
237 {
238 Data& data = get_data();
239
240 if (!data.valid)
241 {
242 T* p = data.storage.begin();
243 ::new (p) T(p1, p2, p3);
244 data.valid = true;
245 }
246 }
247
248 //*************************************************************************
251 //*************************************************************************
252 template <typename T1, typename T2, typename T3, typename T4>
253 static void create(const T1& p1, const T2& p2, const T3& p3, const T4& p4)
254 {
255 Data& data = get_data();
256
257 if (!data.valid)
258 {
259 T* p = data.storage.begin();
260 ::new (p) T(p1, p2, p3, p4);
261 data.valid = true;
262 }
263 }
264
265 //*************************************************************************
267 //*************************************************************************
268 static void destroy()
269 {
270 Data& data = get_data();
271
272 if (data.valid)
273 {
274 T* p = data.storage.begin();
275 p->~T();
276 data.valid = false;
277 }
278 }
279
280 //*************************************************************************
284 //*************************************************************************
285 static T& instance()
286 {
287 Data& data = get_data();
288
289 ETL_ASSERT(data.valid, ETL_ERROR(etl::singleton_not_created));
290
291 return *data.storage.begin();
292 }
293
294 //*************************************************************************
296 //*************************************************************************
297 static bool is_valid()
298 {
299 Data& data = get_data();
300
301 return data.valid;
302 }
303
304 private:
305
306 //*************************************************************************
308 //*************************************************************************
309 struct Data
310 {
311 Data()
312 : valid(false)
313 {
314 }
315
317 bool valid;
318 };
319
320 static Data& get_data()
321 {
322 static Data data;
323
324 return data;
325 }
326
327 // Disabled.
328 singleton();
329 singleton(const singleton&);
330 singleton& operator =(const singleton&);
331 };
332#endif
333}
334
335#endif
336
Base singleton error exception.
Definition: singleton.h:50
Singleton not created error exception.
Definition: singleton.h:63
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
Definition: exception.h:47
static void create(const T1 &p1, const T2 &p2, const T3 &p3)
Definition: singleton.h:236
static void create(const T1 &p1, const T2 &p2, const T3 &p3, const T4 &p4)
Definition: singleton.h:253
static void create()
Constructs the instance of the singleton type.
Definition: singleton.h:185
static bool is_valid()
Checks the validity of the singleton.
Definition: singleton.h:297
static void create(const T1 &p1)
Definition: singleton.h:202
static void destroy()
Destructs the instance of the singleton type.
Definition: singleton.h:268
static void create(const T1 &p1, const T2 &p2)
Definition: singleton.h:219
static T & instance()
Definition: singleton.h:285
Creates .
Definition: singleton.h:43
bitset_ext
Definition: absolute.h:38