libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
storage.h
Go to the documentation of this file.
1// Copyright 2023 owent
2
3#pragma once
4
5#include <libcopp/utils/config/libcopp_build_features.h>
10
12
13// clang-format off
14#include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
15// clang-format on
16#include <cstring>
17#include <functional>
18#include <memory>
19// clang-format off
20#include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
21// clang-format on
22
23LIBCOPP_COPP_NAMESPACE_BEGIN
24namespace future {
25// FUNCTION TEMPLATE make_unique
26template <class T, class... TARGS, typename std::enable_if<!std::is_array<T>::value, int>::type = 0>
27LIBCOPP_EXPLICIT_NODISCARD_ATTR std::unique_ptr<T> make_unique(TARGS &&...args) { // make a unique_ptr
28 return std::unique_ptr<T>(new T(std::forward<TARGS>(args)...));
29}
30
31template <class T, typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, int>::type = 0>
32LIBCOPP_EXPLICIT_NODISCARD_ATTR std::unique_ptr<T> make_unique(size_t sz) { // make a unique_ptr
33 using TELEM = typename std::remove_extent<T>::type;
34 return std::unique_ptr<T>(new TELEM[sz]());
35}
36
37template <class T, class... TARGS, typename std::enable_if<std::extent<T>::value != 0, int>::type = 0>
38void make_unique(TARGS &&...) = delete;
39
40template <class T>
41struct LIBCOPP_COPP_API_HEAD_ONLY small_object_optimize_storage_deleter {
42 LIBCOPP_UTIL_FORCEINLINE void operator()(T *) const noexcept {
43 // Do nothing
44 }
45 template <class U>
46 LIBCOPP_UTIL_FORCEINLINE void operator()(U *) const noexcept {
47 // Do nothing
48 }
49};
50
51template <class T>
52struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_ptr_selector;
53
54template <>
55struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_ptr_selector<void> {
56 using type = std::unique_ptr<void, small_object_optimize_storage_deleter<void> >;
57};
58
59template <class T>
60struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_ptr_selector {
61 using type = typename std::conditional<LIBCOPP_IS_TIRVIALLY_COPYABLE_V(T) && sizeof(T) < (sizeof(size_t) << 2),
63 std::unique_ptr<T, std::default_delete<T> > >::type;
64};
65
66template <class T>
67struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage_selector;
68
69template <>
70struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage_selector<void> {
71 using type = std::unique_ptr<void, small_object_optimize_storage_deleter<void> >;
72};
73
74template <class T>
75struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage_selector {
76 using type = typename std::conditional<LIBCOPP_IS_TIRVIALLY_COPYABLE_V(T) && sizeof(T) <= (sizeof(size_t) << 2),
78 LIBCOPP_COPP_NAMESPACE_ID::memory::default_strong_rc_ptr<T> >::type;
79};
80
81template <class T, class TPTR>
82struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_base;
83
84template <>
85struct LIBCOPP_COPP_API_HEAD_ONLY
86poll_storage_base<void, std::unique_ptr<void, small_object_optimize_storage_deleter<void> > > : public std::true_type {
87 using value_type = void;
88 using ptr_type = std::unique_ptr<void, small_object_optimize_storage_deleter<void> >;
90
91 LIBCOPP_UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) noexcept { out.reset(); }
92
93 template <class U, class UDELETOR,
94 typename std::enable_if<std::is_convertible<typename std::decay<U>::type, bool>::value, bool>::type = false>
96 std::unique_ptr<U, UDELETOR> &&in) noexcept {
97 if (in) {
98 out.reset(reinterpret_cast<void *>(&out));
99 } else {
100 out.reset();
101 }
102 }
103
104 template <class U,
105 typename std::enable_if<std::is_convertible<typename std::decay<U>::type, bool>::value, bool>::type = false>
106 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&in) noexcept {
107 if (in) {
108 out.reset(reinterpret_cast<void *>(&out));
109 } else {
110 out.reset();
111 }
112 }
113
115 if (in) {
116 out.reset(reinterpret_cast<void *>(&out));
117 } else {
118 out.reset();
119 }
120
121 in.reset();
122 }
123
124 LIBCOPP_UTIL_FORCEINLINE static void reset(storage_type &storage) noexcept { storage.reset(); }
126 if (!!l == !!r) {
127 return;
128 }
129
130 if (l) {
131 l.reset();
132 r.reset(reinterpret_cast<void *>(&r));
133 } else {
134 l.reset(reinterpret_cast<void *>(&l));
135 r.reset();
136 }
137 }
138
139 LIBCOPP_UTIL_FORCEINLINE static const ptr_type &unwrap(const storage_type &storage) noexcept { return storage; }
140 LIBCOPP_UTIL_FORCEINLINE static ptr_type &unwrap(storage_type &storage) noexcept { return storage; }
141};
142
143template <class T>
144struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_base<T, std::unique_ptr<T, small_object_optimize_storage_deleter<T> > >
145 : public std::true_type {
146 using value_type = T;
147 using ptr_type = std::unique_ptr<T, small_object_optimize_storage_deleter<T> >;
148 using storage_type = std::pair<T, ptr_type>;
149
151 memset(&out.first, 0, sizeof(out.first));
152 out.second.reset();
153 }
154
155 template <class U, class UDELETOR,
156 typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
157 std::is_convertible<typename std::decay<U>::type, T>::value,
158 bool>::type = false>
160 std::unique_ptr<U, UDELETOR> &&in) noexcept {
161 if (in) {
162 out.first = *in;
163 out.second.reset(&out.first);
164 in.reset();
165 } else {
166 memset(&out.first, 0, sizeof(out.first));
167 out.second.reset();
168 }
169 }
170
171 template <class U, typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
172 std::is_convertible<typename std::decay<U>::type, T>::value,
173 bool>::type = false>
174 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&in) noexcept {
175 out.first = in;
176 out.second.reset(&out.first);
177 }
178
179 template <class... U>
180 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&...in) noexcept {
181 out.first = value_type(std::forward<U>(in)...);
182 out.second.reset(&out.first);
183 }
184
186 std::is_nothrow_copy_assignable<value_type>::value) {
187 if (in.second) {
188 out.first = in.first;
189 out.second.reset(&out.first);
190 in.second.reset();
191 } else {
192 memset(&out.first, 0, sizeof(out.first));
193 out.second.reset();
194 }
195 }
196
197 LIBCOPP_UTIL_FORCEINLINE static void reset(storage_type &storage) noexcept { storage.second.reset(); }
199 value_type lv = l.first;
200 l.first = r.first;
201 r.first = lv;
202 if (!!l.second == !!r.second) {
203 return;
204 }
205
206 if (l.second) {
207 l.second.reset();
208 r.second.reset(&r.first);
209 } else {
210 l.second.reset(&l.first);
211 r.second.reset();
212 }
213 }
214
215 LIBCOPP_UTIL_FORCEINLINE static const ptr_type &unwrap(const storage_type &storage) noexcept {
216 return storage.second;
217 }
218 LIBCOPP_UTIL_FORCEINLINE static ptr_type &unwrap(storage_type &storage) noexcept { return storage.second; }
219};
220
221template <class T, class TPTR>
222struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_base : public std::false_type {
223 using value_type = T;
224 using ptr_type = TPTR;
226
227 LIBCOPP_UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) noexcept { out.reset(); }
228
229 template <class U, class UDELETOR,
230 typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value, bool>::type = false>
232 std::unique_ptr<U, UDELETOR> &&in) noexcept {
233 out = std::move(in);
234 }
235
236 template <class U, typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value &&
238 bool>::type = false>
240 storage_type &out, LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr<U> &&in) noexcept {
241 out = std::move(LIBCOPP_COPP_NAMESPACE_ID::memory::static_pointer_cast<typename ptr_type::element_type>(in));
242 }
243
244 template <class U, typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value &&
246 bool>::type = false>
247 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, ::std::shared_ptr<U> &&in) noexcept {
248 out = std::move(::std::static_pointer_cast<typename ptr_type::element_type>(in));
249 }
250
251 template <class... U>
252 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&...in) noexcept(
253 std::is_nothrow_constructible<value_type, U...>::value) {
254 out.reset(new value_type(std::forward<U>(in)...));
255 }
256
258 out = std::move(in);
259 }
260
261 LIBCOPP_UTIL_FORCEINLINE static void reset(storage_type &storage) noexcept { storage.reset(); }
262 LIBCOPP_UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) noexcept { std::swap(l, r); }
263
264 LIBCOPP_UTIL_FORCEINLINE static const ptr_type &unwrap(const storage_type &storage) noexcept { return storage; }
265 LIBCOPP_UTIL_FORCEINLINE static ptr_type &unwrap(storage_type &storage) noexcept { return storage; }
266};
267
268template <class T, class TPTR>
269struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage;
270
271template <class T>
272struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage<T, std::unique_ptr<T, small_object_optimize_storage_deleter<T> > >
273 : public std::true_type {
274 using value_type = T;
275 using ptr_type = std::unique_ptr<T, small_object_optimize_storage_deleter<T> >;
276 using storage_type = T;
277
278 LIBCOPP_UTIL_FORCEINLINE static bool is_shared_storage() noexcept { return false; }
280 // do nothing for trival copyable object
281 }
283 memset(&out, 0, sizeof(out));
284 }
285
286 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out) noexcept { construct_default_storage(out); }
287
288 template <class U, class UDELETOR,
289 typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
290 std::is_convertible<typename std::decay<U>::type, T>::value,
291 bool>::type = false>
292 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, std::unique_ptr<U, UDELETOR> &&in) noexcept(
293 std::is_nothrow_assignable<storage_type, U>::value) {
294 if (in) {
295 out = *in;
296 } else {
297 memset(&out, 0, sizeof(out));
298 }
299 }
300
301 template <class U, typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
302 std::is_convertible<typename std::decay<U>::type, T>::value,
303 bool>::type = false>
304 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&in) noexcept(
305 std::is_nothrow_assignable<storage_type, U>::value) {
306 out = in;
307 }
308
309 LIBCOPP_UTIL_FORCEINLINE static void clone_storage(storage_type &out, const storage_type &in) noexcept {
310 memcpy(&out, &in, sizeof(out));
311 }
312
314 memcpy(&out, &in, sizeof(out));
315 memset(&in, 0, sizeof(in));
316 }
317
319 storage_type lv = l;
320 l = r;
321 r = lv;
322 }
323
324 LIBCOPP_UTIL_FORCEINLINE static value_type *unwrap(storage_type &storage) noexcept { return &storage; }
325 LIBCOPP_UTIL_FORCEINLINE static const value_type *unwrap(const storage_type &storage) noexcept { return &storage; }
326 LIBCOPP_UTIL_FORCEINLINE static ptr_type clone_ptr(storage_type &storage) noexcept { return ptr_type(&storage); }
327};
328
329template <class T>
330struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage<T, LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr<T> >
331 : public std::false_type {
332 using value_type = T;
333 using ptr_type = LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr<T>;
335
336 LIBCOPP_UTIL_FORCEINLINE static bool is_shared_storage() noexcept { return true; }
337 LIBCOPP_UTIL_FORCEINLINE static void destroy_storage(storage_type &out) noexcept { out.reset(); }
338 LIBCOPP_UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) noexcept { out.reset(); }
339
340 template <class U, class UDELETOR,
341 typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value, bool>::type = false>
342 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, std::unique_ptr<U, UDELETOR> &&in) {
343 if (in) {
344 out = std::move(in);
345 } else {
346 out.reset();
347 }
348 }
349
350 template <class U,
351 typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value, bool>::type = false>
353 storage_type &out, LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr<U> &&in) noexcept {
354 if (in) {
355 out = LIBCOPP_COPP_NAMESPACE_ID::memory::static_pointer_cast<T>(in);
356 } else {
357 out.reset();
358 }
359 }
360
361 template <class... TARGS>
362 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, TARGS &&...in) noexcept(
363 std::is_nothrow_constructible<T, TARGS...>::value) {
364 out = LIBCOPP_COPP_NAMESPACE_ID::memory::make_strong_rc<T>(std::forward<TARGS>(in)...);
365 }
366
367 LIBCOPP_UTIL_FORCEINLINE static void clone_storage(storage_type &out, const storage_type &in) noexcept { out = in; }
369 out.swap(in);
370 in.reset();
371 }
372
373 LIBCOPP_UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) noexcept { l.swap(r); }
374
375 LIBCOPP_UTIL_FORCEINLINE static value_type *unwrap(storage_type &storage) noexcept { return storage.get(); }
376 LIBCOPP_UTIL_FORCEINLINE static const value_type *unwrap(const storage_type &storage) noexcept {
377 return storage.get();
378 }
379 LIBCOPP_UTIL_FORCEINLINE static ptr_type clone_ptr(storage_type &storage) noexcept { return storage; }
380};
381
382template <class T>
383struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage<T, ::std::shared_ptr<T> > : public std::false_type {
384 using value_type = T;
385 using ptr_type = ::std::shared_ptr<T>;
387
388 LIBCOPP_UTIL_FORCEINLINE static bool is_shared_storage() noexcept { return true; }
389 LIBCOPP_UTIL_FORCEINLINE static void destroy_storage(storage_type &out) noexcept { out.reset(); }
390 LIBCOPP_UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) noexcept { out.reset(); }
391
392 template <class U, class UDELETOR,
393 typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value, bool>::type = false>
394 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, std::unique_ptr<U, UDELETOR> &&in) {
395 if (in) {
396 out = std::move(in);
397 } else {
398 out.reset();
399 }
400 }
401
402 template <class U,
403 typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value, bool>::type = false>
404 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, ::std::shared_ptr<U> &&in) noexcept {
405 if (in) {
406 out = ::std::static_pointer_cast<T>(in);
407 } else {
408 out.reset();
409 }
410 }
411
412 template <class... TARGS>
413 LIBCOPP_UTIL_FORCEINLINE static void construct_storage(storage_type &out, TARGS &&...in) noexcept(
414 std::is_nothrow_constructible<T, TARGS...>::value) {
415 out = ::std::make_shared<T>(std::forward<TARGS>(in)...);
416 }
417
418 LIBCOPP_UTIL_FORCEINLINE static void clone_storage(storage_type &out, const storage_type &in) noexcept { out = in; }
420 out.swap(in);
421 in.reset();
422 }
423
424 LIBCOPP_UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) noexcept { l.swap(r); }
425
426 LIBCOPP_UTIL_FORCEINLINE static value_type *unwrap(storage_type &storage) noexcept { return storage.get(); }
427 LIBCOPP_UTIL_FORCEINLINE static const value_type *unwrap(const storage_type &storage) noexcept {
428 return storage.get();
429 }
430 LIBCOPP_UTIL_FORCEINLINE static ptr_type clone_ptr(storage_type &storage) noexcept { return storage; }
431};
432
433template <class T>
434struct default_compact_storage : public compact_storage<T, typename compact_storage_selector<T>::type> {
435 using type = compact_storage<T, typename compact_storage_selector<T>::type>;
436};
437
438template <class TSTORAGE, class... TARGS>
440 typename TSTORAGE::storage_type &out,
441 TARGS &&...args) noexcept(noexcept(TSTORAGE::construct_storage(out, std::forward<TARGS>(args)...))) {
442 TSTORAGE::construct_storage(out, std::forward<TARGS>(args)...);
443}
444
445template <class TSTORAGE, class... TARGS>
447 LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr<typename TSTORAGE::storage_type> &out,
448 TARGS &&...args) noexcept(noexcept(TSTORAGE::construct_storage(out,
449 LIBCOPP_COPP_NAMESPACE_ID::memory::make_strong_rc<
450 typename TSTORAGE::storage_type>(
451 std::forward<TARGS>(args)...)))) {
452 TSTORAGE::construct_storage(out, LIBCOPP_COPP_NAMESPACE_ID::memory::make_strong_rc<typename TSTORAGE::storage_type>(
453 std::forward<TARGS>(args)...));
454}
455
456template <class TSTORAGE, class... TARGS>
457LIBCOPP_UTIL_FORCEINLINE static void
458__make_result_value(::std::shared_ptr<typename TSTORAGE::storage_type> &out, TARGS &&...args) noexcept(noexcept(
459 TSTORAGE::construct_storage(out,
460 ::std::make_shared<typename TSTORAGE::storage_type>(std::forward<TARGS>(args)...)))) {
461 TSTORAGE::construct_storage(out, ::std::make_shared<typename TSTORAGE::storage_type>(std::forward<TARGS>(args)...));
462}
463
464template <class TOK, class TERR, bool is_all_trivial>
465class LIBCOPP_COPP_API_HEAD_ONLY result_base;
466
467template <class TOK, class TERR>
468class LIBCOPP_COPP_API_HEAD_ONLY result_base<TOK, TERR, true> {
469 public:
470 using success_type = TOK;
471 using error_type = TERR;
473 EN_RESULT_SUCCESS = 0,
474 EN_RESULT_ERROR = 1,
475 };
476
477 LIBCOPP_UTIL_FORCEINLINE bool is_success() const noexcept { return mode_ == EN_RESULT_SUCCESS; }
478 LIBCOPP_UTIL_FORCEINLINE bool is_error() const noexcept { return mode_ == EN_RESULT_ERROR; }
479
481 return is_success() ? &success_value_ : nullptr;
482 }
483 LIBCOPP_UTIL_FORCEINLINE success_type *get_success() noexcept { return is_success() ? &success_value_ : nullptr; }
484 LIBCOPP_UTIL_FORCEINLINE const error_type *get_error() const noexcept { return is_error() ? &error_value_ : nullptr; }
485 LIBCOPP_UTIL_FORCEINLINE error_type *get_error() noexcept { return is_error() ? &error_value_ : nullptr; }
486
487 private:
488 template <class UOK, class UERR>
489 friend class result_type;
490 template <class TRESULT, bool>
492
493 template <class TARGS>
494 LIBCOPP_UTIL_FORCEINLINE void construct_success(TARGS &&args) noexcept {
495 make_success_base(std::forward<TARGS>(args));
496 }
497
498 template <class TARGS>
499 LIBCOPP_UTIL_FORCEINLINE void construct_error(TARGS &&args) noexcept {
500 make_error_base(std::forward<TARGS>(args));
501 }
502
503 template <class TARGS>
504 LIBCOPP_UTIL_FORCEINLINE void make_success_base(TARGS &&args) noexcept {
505 success_value_ = args;
506 mode_ = EN_RESULT_SUCCESS;
507 }
508
509 template <class TARGS>
510 LIBCOPP_UTIL_FORCEINLINE void make_error_base(TARGS &&args) noexcept {
511 error_value_ = args;
512 mode_ = EN_RESULT_ERROR;
513 }
514
515 inline void swap(result_base &other) noexcept {
516 using std::swap;
517 if (is_success()) {
518 swap(success_value_, other.success_value_);
519 } else {
520 swap(error_value_, other.error_value_);
521 }
522 swap(mode_, other.mode_);
523 }
524
525 LIBCOPP_UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) noexcept { l.swap(r); }
526
527 private:
528 union {
531 };
533};
534
535template <class TOK, class TERR>
536class LIBCOPP_COPP_API_HEAD_ONLY result_base<TOK, TERR, false> {
537 public:
538 using success_type = TOK;
539 using error_type = TERR;
541 EN_RESULT_SUCCESS = 0,
542 EN_RESULT_ERROR = 1,
543 EN_RESULT_NONE = 2,
544 };
545
548 using success_value_type = typename success_storage_type::storage_type;
549 using error_value_type = typename error_storage_type::storage_type;
550
551 LIBCOPP_UTIL_FORCEINLINE bool is_success() const noexcept { return mode_ == EN_RESULT_SUCCESS; }
552 LIBCOPP_UTIL_FORCEINLINE bool is_error() const noexcept { return mode_ == EN_RESULT_ERROR; }
553
555 return is_success() ? success_storage_type::unwrap(success_value_) : nullptr;
556 }
558 return is_success() ? success_storage_type::unwrap(success_value_) : nullptr;
559 }
561 return is_error() ? error_storage_type::unwrap(error_value_) : nullptr;
562 }
564 return is_error() ? error_storage_type::unwrap(error_value_) : nullptr;
565 }
566
567 result_base() noexcept : mode_(EN_RESULT_NONE) {
568 success_storage_type::construct_default_storage(success_value_);
569 error_storage_type::construct_default_storage(error_value_);
570 }
571 ~result_base() { reset(); }
572
573 result_base(result_base &&other) noexcept : mode_(EN_RESULT_NONE) {
574 success_storage_type::construct_default_storage(success_value_);
575 error_storage_type::construct_default_storage(error_value_);
576
577 swap(other);
578 }
579
580 result_base &operator=(result_base &&other) noexcept {
581 swap(other);
582 other.reset();
583 return *this;
584 }
585
586 LIBCOPP_UTIL_FORCEINLINE void swap(result_base &other) noexcept {
587 using std::swap;
588 success_storage_type::swap(success_value_, other.success_value_);
589 error_storage_type::swap(error_value_, other.error_value_);
590 swap(mode_, other.mode_);
591 }
592
593 LIBCOPP_UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) noexcept { l.swap(r); }
594
595 private:
596 template <class UOK, class UERR>
597 friend class result_type;
598 template <class TRESULT, bool>
600
601 template <class... TARGS>
602 LIBCOPP_UTIL_FORCEINLINE void construct_success(TARGS &&...args) noexcept(noexcept(
603 success_storage_type::construct_storage(std::declval<success_value_type &>(), std::forward<TARGS>(args)...))) {
604 reset();
605 success_storage_type::construct_storage(success_value_, std::forward<TARGS>(args)...);
606 mode_ = EN_RESULT_SUCCESS;
607 }
608
609 template <class... TARGS>
610 LIBCOPP_UTIL_FORCEINLINE void construct_error(TARGS &&...args) noexcept(noexcept(
611 error_storage_type::construct_storage(std::declval<error_value_type &>(), std::forward<TARGS>(args)...))) {
612 reset();
613 error_storage_type::construct_storage(error_value_, std::forward<TARGS>(args)...);
614 mode_ = EN_RESULT_ERROR;
615 }
616
617 template <class... TARGS>
618 LIBCOPP_UTIL_FORCEINLINE void make_success_base(TARGS &&...args) noexcept(noexcept(
619 __make_result_value<success_storage_type>(std::declval<success_value_type &>(), std::forward<TARGS>(args)...))) {
620 reset();
621 __make_result_value<success_storage_type>(success_value_, std::forward<TARGS>(args)...);
622 mode_ = EN_RESULT_SUCCESS;
623 }
624
625 template <class... TARGS>
626 LIBCOPP_UTIL_FORCEINLINE void make_error_base(TARGS &&...args) noexcept(noexcept(
627 __make_result_value<error_storage_type>(std::declval<error_value_type &>(), std::forward<TARGS>(args)...))) {
628 reset();
629 __make_result_value<error_storage_type>(error_value_, std::forward<TARGS>(args)...);
630 mode_ = EN_RESULT_ERROR;
631 }
632
633 inline void reset() noexcept {
634 if (EN_RESULT_SUCCESS == mode_) {
635 success_storage_type::destroy_storage(success_value_);
636 } else if (EN_RESULT_ERROR == mode_) {
637 error_storage_type::destroy_storage(error_value_);
638 }
639
640 mode_ = EN_RESULT_NONE;
641 }
642
643 private:
644 template <class TSTORAGE, class... TARGS>
645 LIBCOPP_UTIL_FORCEINLINE static void make_object(typename TSTORAGE::storage_type &out, TARGS &&...args) noexcept(
646 noexcept(TSTORAGE::construct_storage(out, std::forward<TARGS>(args)...))) {
647 TSTORAGE::construct_storage(out, std::forward<TARGS>(args)...);
648 }
649
650 template <class TSTORAGE, class... TARGS>
652 LIBCOPP_COPP_NAMESPACE_ID::memory::default_strong_rc_ptr<typename TSTORAGE::storage_type> &out,
653 TARGS &&...args) noexcept(noexcept(TSTORAGE::construct_storage(out, LIBCOPP_COPP_NAMESPACE_ID::memory::
654 default_make_strong<
655 typename TSTORAGE::storage_type>(
656 std::forward<TARGS>(args)...)))) {
657 TSTORAGE::construct_storage(out,
658 LIBCOPP_COPP_NAMESPACE_ID::memory::default_make_strong<typename TSTORAGE::storage_type>(
659 std::forward<TARGS>(args)...));
660 }
661
665};
666
667template <class TRESULT, bool>
668struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper;
669
670template <class TRESULT>
671struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper<TRESULT, false> {
672 using type = std::unique_ptr<TRESULT>;
673
674 template <class... TARGS>
675 inline static type make_success(TARGS &&...args) noexcept(
676 noexcept(std::declval<TRESULT>().make_success_base(std::forward<TARGS>(args)...))) {
677 type ret = LIBCOPP_COPP_NAMESPACE_ID::future::make_unique<TRESULT>();
678 if (ret) {
679 ret->make_success_base(std::forward<TARGS>(args)...);
680 }
681
682 return ret;
683 }
684
685 template <class... TARGS>
686 inline static type make_error(TARGS &&...args) noexcept(
687 noexcept(std::declval<TRESULT>().make_error_base(std::forward<TARGS>(args)...))) {
688 type ret = LIBCOPP_COPP_NAMESPACE_ID::future::make_unique<TRESULT>();
689 if (ret) {
690 ret->make_error_base(std::forward<TARGS>(args)...);
691 }
692
693 return ret;
694 }
695};
696
697template <class TRESULT>
698struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper<TRESULT, true> {
699 using type = TRESULT;
700
701 template <class... TARGS>
702 LIBCOPP_UTIL_FORCEINLINE static type make_success(TARGS &&...args) noexcept(
703 noexcept(std::declval<TRESULT>().make_success_base(std::forward<TARGS>(args)...))) {
704 TRESULT ret;
705 ret.make_success_base(std::forward<TARGS>(args)...);
706 return ret;
707 }
708
709 template <class... TARGS>
710 LIBCOPP_UTIL_FORCEINLINE static type make_error(TARGS &&...args) noexcept(
711 noexcept(std::declval<TRESULT>().make_error_base(std::forward<TARGS>(args)...))) {
712 TRESULT ret;
713 ret.make_error_base(std::forward<TARGS>(args)...);
714 return ret;
715 }
716};
717
718template <class TOK, class TERR>
719class LIBCOPP_COPP_API_HEAD_ONLY result_type
720 : public result_base<TOK, TERR, default_compact_storage<TOK>::value && default_compact_storage<TERR>::value> {
721 public:
722 using base_type = result_base<TOK, TERR, default_compact_storage<TOK>::value && default_compact_storage<TERR>::value>;
724
725 private:
728
729 public:
730 using storage_type = typename _make_instance_type::type;
731
732 template <class... TARGS>
733 LIBCOPP_UTIL_FORCEINLINE static self_type create_success(TARGS &&...args) noexcept(
734 noexcept(std::declval<self_type>().construct_success(std::forward<TARGS>(args)...))) {
735 self_type ret;
736 ret.construct_success(std::forward<TARGS>(args)...);
737 return ret;
738 }
739
740 template <class... TARGS>
741 LIBCOPP_UTIL_FORCEINLINE static self_type create_error(TARGS &&...args) noexcept(
742 noexcept(std::declval<self_type>().construct_error(std::forward<TARGS>(args)...))) {
743 self_type ret;
744 ret.construct_error(std::forward<TARGS>(args)...);
745 return ret;
746 }
747
748 public:
749 template <class... TARGS>
750 LIBCOPP_UTIL_FORCEINLINE static storage_type make_success(TARGS &&...args) noexcept(
751 noexcept(_make_instance_type::make_success(std::forward<TARGS>(args)...))) {
752 return _make_instance_type::make_success(std::forward<TARGS>(args)...);
753 }
754
755 template <class... TARGS>
756 LIBCOPP_UTIL_FORCEINLINE static storage_type make_error(TARGS &&...args) noexcept(
757 noexcept(_make_instance_type::make_error(std::forward<TARGS>(args)...))) {
758 return _make_instance_type::make_error(std::forward<TARGS>(args)...);
759 }
760};
761} // namespace future
762LIBCOPP_COPP_NAMESPACE_END
LIBCOPP_UTIL_FORCEINLINE success_type * get_success() noexcept
Definition storage.h:557
LIBCOPP_UTIL_FORCEINLINE void make_error_base(TARGS &&...args) noexcept(noexcept(__make_result_value< error_storage_type >(std::declval< error_value_type & >(), std::forward< TARGS >(args)...)))
Definition storage.h:626
LIBCOPP_UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) noexcept
Definition storage.h:593
static LIBCOPP_UTIL_FORCEINLINE void make_object(typename TSTORAGE::storage_type &out, TARGS &&...args) noexcept(noexcept(TSTORAGE::construct_storage(out, std::forward< TARGS >(args)...)))
Definition storage.h:645
LIBCOPP_UTIL_FORCEINLINE bool is_success() const noexcept
Definition storage.h:551
typename success_storage_type::storage_type success_value_type
Definition storage.h:548
result_base & operator=(result_base &&other) noexcept
Definition storage.h:580
result_base(result_base &&other) noexcept
Definition storage.h:573
LIBCOPP_UTIL_FORCEINLINE void construct_success(TARGS &&...args) noexcept(noexcept(success_storage_type::construct_storage(std::declval< success_value_type & >(), std::forward< TARGS >(args)...)))
Definition storage.h:602
LIBCOPP_UTIL_FORCEINLINE const success_type * get_success() const noexcept
Definition storage.h:554
static LIBCOPP_UTIL_FORCEINLINE void make_object(LIBCOPP_COPP_NAMESPACE_ID::memory::default_strong_rc_ptr< typename TSTORAGE::storage_type > &out, TARGS &&...args) noexcept(noexcept(TSTORAGE::construct_storage(out, LIBCOPP_COPP_NAMESPACE_ID::memory::default_make_strong< typename TSTORAGE::storage_type >(std::forward< TARGS >(args)...))))
Definition storage.h:651
typename error_storage_type::storage_type error_value_type
Definition storage.h:549
typename default_compact_storage< success_type >::type success_storage_type
Definition storage.h:546
LIBCOPP_UTIL_FORCEINLINE void make_success_base(TARGS &&...args) noexcept(noexcept(__make_result_value< success_storage_type >(std::declval< success_value_type & >(), std::forward< TARGS >(args)...)))
Definition storage.h:618
LIBCOPP_UTIL_FORCEINLINE bool is_error() const noexcept
Definition storage.h:552
LIBCOPP_UTIL_FORCEINLINE void swap(result_base &other) noexcept
Definition storage.h:586
LIBCOPP_UTIL_FORCEINLINE error_type * get_error() noexcept
Definition storage.h:563
LIBCOPP_UTIL_FORCEINLINE void construct_error(TARGS &&...args) noexcept(noexcept(error_storage_type::construct_storage(std::declval< error_value_type & >(), std::forward< TARGS >(args)...)))
Definition storage.h:610
typename default_compact_storage< error_type >::type error_storage_type
Definition storage.h:547
LIBCOPP_UTIL_FORCEINLINE const error_type * get_error() const noexcept
Definition storage.h:560
LIBCOPP_UTIL_FORCEINLINE success_type * get_success() noexcept
Definition storage.h:483
LIBCOPP_UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) noexcept
Definition storage.h:525
LIBCOPP_UTIL_FORCEINLINE void make_success_base(TARGS &&args) noexcept
Definition storage.h:504
LIBCOPP_UTIL_FORCEINLINE bool is_error() const noexcept
Definition storage.h:478
LIBCOPP_UTIL_FORCEINLINE error_type * get_error() noexcept
Definition storage.h:485
void swap(result_base &other) noexcept
Definition storage.h:515
LIBCOPP_UTIL_FORCEINLINE void construct_error(TARGS &&args) noexcept
Definition storage.h:499
LIBCOPP_UTIL_FORCEINLINE const success_type * get_success() const noexcept
Definition storage.h:480
LIBCOPP_UTIL_FORCEINLINE void construct_success(TARGS &&args) noexcept
Definition storage.h:494
LIBCOPP_UTIL_FORCEINLINE const error_type * get_error() const noexcept
Definition storage.h:484
LIBCOPP_UTIL_FORCEINLINE bool is_success() const noexcept
Definition storage.h:477
LIBCOPP_UTIL_FORCEINLINE void make_error_base(TARGS &&args) noexcept
Definition storage.h:510
result_base< TOK, TERR, default_compact_storage< TOK >::value &&default_compact_storage< TERR >::value > base_type
Definition storage.h:722
static LIBCOPP_UTIL_FORCEINLINE storage_type make_error(TARGS &&...args) noexcept(noexcept(_make_instance_type::make_error(std::forward< TARGS >(args)...)))
Definition storage.h:756
_make_result_instance_helper< self_type, poll_storage_base< base_type, typename poll_storage_ptr_selector< base_type >::type >::value > _make_instance_type
Definition storage.h:727
typename _make_instance_type::type storage_type
Definition storage.h:730
static LIBCOPP_UTIL_FORCEINLINE storage_type make_success(TARGS &&...args) noexcept(noexcept(_make_instance_type::make_success(std::forward< TARGS >(args)...)))
Definition storage.h:750
static LIBCOPP_UTIL_FORCEINLINE self_type create_error(TARGS &&...args) noexcept(noexcept(std::declval< self_type >().construct_error(std::forward< TARGS >(args)...)))
Definition storage.h:741
static LIBCOPP_UTIL_FORCEINLINE self_type create_success(TARGS &&...args) noexcept(noexcept(std::declval< self_type >().construct_success(std::forward< TARGS >(args)...)))
Definition storage.h:733
A std::shared_ptr replacement that is more lightweight and do not use atomic operation for reference ...
Definition rc_ptr.h:791
#define LIBCOPP_UTIL_FORCEINLINE
#define LIBCOPP_EXPLICIT_NODISCARD_ATTR
nodiscard attribute usage: LIBCOPP_EXPLICIT_NODISCARD_ATTR int a; class LIBCOPP_EXPLICIT_NODISCARD_AT...
LIBCOPP_EXPLICIT_NODISCARD_ATTR std::unique_ptr< T > make_unique(TARGS &&...args)
Definition storage.h:27
static LIBCOPP_UTIL_FORCEINLINE void __make_result_value(typename TSTORAGE::storage_type &out, TARGS &&...args) noexcept(noexcept(TSTORAGE::construct_storage(out, std::forward< TARGS >(args)...)))
Definition storage.h:439
class LIBCOPP_COPP_API_HEAD_ONLY result_base
Definition storage.h:465
struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper
Definition storage.h:668
struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage
Definition storage.h:269
STL namespace.
LIBCOPP_COPP_API_HEAD_ONLY void swap(LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr< T > &a, LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr< T > &b) noexcept
Support std::swap for strong_rc_ptr.
Definition rc_ptr.h:1377
type_traits compatiable Licensed under the MIT licenses.
#define LIBCOPP_IS_TIRVIALLY_COPYABLE_V(X)
Definition type_traits.h:46
static type make_error(TARGS &&...args) noexcept(noexcept(std::declval< TRESULT >().make_error_base(std::forward< TARGS >(args)...)))
Definition storage.h:686
static type make_success(TARGS &&...args) noexcept(noexcept(std::declval< TRESULT >().make_success_base(std::forward< TARGS >(args)...)))
Definition storage.h:675
static LIBCOPP_UTIL_FORCEINLINE type make_success(TARGS &&...args) noexcept(noexcept(std::declval< TRESULT >().make_success_base(std::forward< TARGS >(args)...)))
Definition storage.h:702
static LIBCOPP_UTIL_FORCEINLINE type make_error(TARGS &&...args) noexcept(noexcept(std::declval< TRESULT >().make_error_base(std::forward< TARGS >(args)...)))
Definition storage.h:710
static LIBCOPP_UTIL_FORCEINLINE void clone_storage(storage_type &out, const storage_type &in) noexcept
Definition storage.h:367
static LIBCOPP_UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) noexcept
Definition storage.h:373
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in)
Definition storage.h:342
static LIBCOPP_UTIL_FORCEINLINE value_type * unwrap(storage_type &storage) noexcept
Definition storage.h:375
static LIBCOPP_UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) noexcept
Definition storage.h:368
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, TARGS &&...in) noexcept(std::is_nothrow_constructible< T, TARGS... >::value)
Definition storage.h:362
static LIBCOPP_UTIL_FORCEINLINE const value_type * unwrap(const storage_type &storage) noexcept
Definition storage.h:376
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr< U > &&in) noexcept
Definition storage.h:352
static LIBCOPP_UTIL_FORCEINLINE void construct_default_storage(storage_type &out) noexcept
Definition storage.h:338
LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr< T > ptr_type
Definition storage.h:333
static LIBCOPP_UTIL_FORCEINLINE void destroy_storage(storage_type &out) noexcept
Definition storage.h:337
static LIBCOPP_UTIL_FORCEINLINE ptr_type clone_ptr(storage_type &storage) noexcept
Definition storage.h:379
static LIBCOPP_UTIL_FORCEINLINE void clone_storage(storage_type &out, const storage_type &in) noexcept
Definition storage.h:418
static LIBCOPP_UTIL_FORCEINLINE ptr_type clone_ptr(storage_type &storage) noexcept
Definition storage.h:430
static LIBCOPP_UTIL_FORCEINLINE value_type * unwrap(storage_type &storage) noexcept
Definition storage.h:426
static LIBCOPP_UTIL_FORCEINLINE const value_type * unwrap(const storage_type &storage) noexcept
Definition storage.h:427
static LIBCOPP_UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) noexcept
Definition storage.h:419
static LIBCOPP_UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) noexcept
Definition storage.h:424
static LIBCOPP_UTIL_FORCEINLINE void construct_default_storage(storage_type &out) noexcept
Definition storage.h:390
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in)
Definition storage.h:394
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, TARGS &&...in) noexcept(std::is_nothrow_constructible< T, TARGS... >::value)
Definition storage.h:413
static LIBCOPP_UTIL_FORCEINLINE void destroy_storage(storage_type &out) noexcept
Definition storage.h:389
static LIBCOPP_UTIL_FORCEINLINE bool is_shared_storage() noexcept
Definition storage.h:388
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, ::std::shared_ptr< U > &&in) noexcept
Definition storage.h:404
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out) noexcept
Definition storage.h:286
static LIBCOPP_UTIL_FORCEINLINE const value_type * unwrap(const storage_type &storage) noexcept
Definition storage.h:325
static LIBCOPP_UTIL_FORCEINLINE value_type * unwrap(storage_type &storage) noexcept
Definition storage.h:324
static LIBCOPP_UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) noexcept
Definition storage.h:318
static LIBCOPP_UTIL_FORCEINLINE void destroy_storage(storage_type &) noexcept
Definition storage.h:279
static LIBCOPP_UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) noexcept
Definition storage.h:313
static LIBCOPP_UTIL_FORCEINLINE void construct_default_storage(storage_type &out) noexcept
Definition storage.h:282
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) noexcept(std::is_nothrow_assignable< storage_type, U >::value)
Definition storage.h:292
static LIBCOPP_UTIL_FORCEINLINE void clone_storage(storage_type &out, const storage_type &in) noexcept
Definition storage.h:309
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&in) noexcept(std::is_nothrow_assignable< storage_type, U >::value)
Definition storage.h:304
std::unique_ptr< T, small_object_optimize_storage_deleter< T > > ptr_type
Definition storage.h:275
static LIBCOPP_UTIL_FORCEINLINE ptr_type clone_ptr(storage_type &storage) noexcept
Definition storage.h:326
std::unique_ptr< void, small_object_optimize_storage_deleter< void > > type
Definition storage.h:71
typename std::conditional< LIBCOPP_IS_TIRVIALLY_COPYABLE_V(T) &&sizeof(T)<=(sizeof(size_t)<< 2), std::unique_ptr< T, small_object_optimize_storage_deleter< T > >, LIBCOPP_COPP_NAMESPACE_ID::memory::default_strong_rc_ptr< T > >::type type
Definition storage.h:78
compact_storage< T, typename compact_storage_selector< T >::type > type
Definition storage.h:435
static LIBCOPP_UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) noexcept(std::is_nothrow_copy_assignable< value_type >::value)
Definition storage.h:185
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&...in) noexcept
Definition storage.h:180
static LIBCOPP_UTIL_FORCEINLINE const ptr_type & unwrap(const storage_type &storage) noexcept
Definition storage.h:215
std::unique_ptr< T, small_object_optimize_storage_deleter< T > > ptr_type
Definition storage.h:147
static LIBCOPP_UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) noexcept
Definition storage.h:198
static LIBCOPP_UTIL_FORCEINLINE void construct_default_storage(storage_type &out) noexcept
Definition storage.h:150
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) noexcept
Definition storage.h:159
static LIBCOPP_UTIL_FORCEINLINE void reset(storage_type &storage) noexcept
Definition storage.h:197
static LIBCOPP_UTIL_FORCEINLINE ptr_type & unwrap(storage_type &storage) noexcept
Definition storage.h:218
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&in) noexcept
Definition storage.h:174
static LIBCOPP_UTIL_FORCEINLINE void reset(storage_type &storage) noexcept
Definition storage.h:124
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&in) noexcept
Definition storage.h:106
static LIBCOPP_UTIL_FORCEINLINE void construct_default_storage(storage_type &out) noexcept
Definition storage.h:91
static LIBCOPP_UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) noexcept
Definition storage.h:125
static LIBCOPP_UTIL_FORCEINLINE const ptr_type & unwrap(const storage_type &storage) noexcept
Definition storage.h:139
static LIBCOPP_UTIL_FORCEINLINE ptr_type & unwrap(storage_type &storage) noexcept
Definition storage.h:140
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) noexcept
Definition storage.h:95
std::unique_ptr< void, small_object_optimize_storage_deleter< void > > ptr_type
Definition storage.h:88
static LIBCOPP_UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) noexcept
Definition storage.h:114
static LIBCOPP_UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) noexcept
Definition storage.h:257
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) noexcept
Definition storage.h:231
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, LIBCOPP_COPP_NAMESPACE_ID::memory::strong_rc_ptr< U > &&in) noexcept
Definition storage.h:239
static LIBCOPP_UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) noexcept
Definition storage.h:262
static LIBCOPP_UTIL_FORCEINLINE const ptr_type & unwrap(const storage_type &storage) noexcept
Definition storage.h:264
static LIBCOPP_UTIL_FORCEINLINE void reset(storage_type &storage) noexcept
Definition storage.h:261
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&...in) noexcept(std::is_nothrow_constructible< value_type, U... >::value)
Definition storage.h:252
static LIBCOPP_UTIL_FORCEINLINE void construct_default_storage(storage_type &out) noexcept
Definition storage.h:227
static LIBCOPP_UTIL_FORCEINLINE ptr_type & unwrap(storage_type &storage) noexcept
Definition storage.h:265
static LIBCOPP_UTIL_FORCEINLINE void construct_storage(storage_type &out, ::std::shared_ptr< U > &&in) noexcept
Definition storage.h:247
std::unique_ptr< void, small_object_optimize_storage_deleter< void > > type
Definition storage.h:56
typename std::conditional< LIBCOPP_IS_TIRVIALLY_COPYABLE_V(T) &&sizeof(T)<(sizeof(size_t)<< 2), std::unique_ptr< T, small_object_optimize_storage_deleter< T > >, std::unique_ptr< T, std::default_delete< T > > >::type type
Definition storage.h:63
LIBCOPP_UTIL_FORCEINLINE void operator()(T *) const noexcept
Definition storage.h:42
LIBCOPP_UTIL_FORCEINLINE void operator()(U *) const noexcept
Definition storage.h:46