libcopp  2.2.0
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>
6 
10 
11 #include <libcopp/utils/features.h>
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 
23 LIBCOPP_COPP_NAMESPACE_BEGIN
24 namespace future {
25 // FUNCTION TEMPLATE make_unique
26 template <class T, class... TARGS, typename std::enable_if<!std::is_array<T>::value, int>::type = 0>
27 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 
31 template <class T, typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, int>::type = 0>
32 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 
37 template <class T, class... TARGS, typename std::enable_if<std::extent<T>::value != 0, int>::type = 0>
38 void make_unique(TARGS &&...) = delete;
39 
40 template <class T>
41 struct LIBCOPP_COPP_API_HEAD_ONLY small_object_optimize_storage_deleter {
42  UTIL_FORCEINLINE void operator()(T *) const LIBCOPP_MACRO_NOEXCEPT {
43  // Do nothing
44  }
45  template <class U>
46  UTIL_FORCEINLINE void operator()(U *) const LIBCOPP_MACRO_NOEXCEPT {
47  // Do nothing
48  }
49 };
50 
51 template <class T>
52 struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_ptr_selector;
53 
54 template <>
55 struct 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 
59 template <class T>
60 struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_ptr_selector {
61  using type = typename std::conditional<COPP_IS_TIRVIALLY_COPYABLE_V(T) && sizeof(T) < (sizeof(size_t) << 2),
62  std::unique_ptr<T, small_object_optimize_storage_deleter<T> >,
63  std::unique_ptr<T, std::default_delete<T> > >::type;
64 };
65 
66 template <class T>
67 struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage_selector;
68 
69 template <>
70 struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage_selector<void> {
71  using type = std::unique_ptr<void, small_object_optimize_storage_deleter<void> >;
72 };
73 
74 template <class T>
75 struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage_selector {
76  using type = typename std::conditional<COPP_IS_TIRVIALLY_COPYABLE_V(T) && sizeof(T) <= (sizeof(size_t) << 2),
77  std::unique_ptr<T, small_object_optimize_storage_deleter<T> >,
78  std::shared_ptr<T> >::type;
79 };
80 
81 template <class T, class TPTR>
82 struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_base;
83 
84 template <>
85 struct LIBCOPP_COPP_API_HEAD_ONLY
86  poll_storage_base<void, std::unique_ptr<void, small_object_optimize_storage_deleter<void> > >
87  : public std::true_type {
88  using value_type = void;
89  using ptr_type = std::unique_ptr<void, small_object_optimize_storage_deleter<void> >;
91 
92  UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT { out.reset(); }
93 
94  template <class U, class UDELETOR,
95  typename std::enable_if<std::is_convertible<typename std::decay<U>::type, bool>::value, bool>::type = false>
97  std::unique_ptr<U, UDELETOR> &&in) LIBCOPP_MACRO_NOEXCEPT {
98  if (in) {
99  out.reset(reinterpret_cast<void *>(&out));
100  } else {
101  out.reset();
102  }
103  }
104 
105  template <class U,
106  typename std::enable_if<std::is_convertible<typename std::decay<U>::type, bool>::value, bool>::type = false>
107  UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&in) LIBCOPP_MACRO_NOEXCEPT {
108  if (in) {
109  out.reset(reinterpret_cast<void *>(&out));
110  } else {
111  out.reset();
112  }
113  }
114 
115  UTIL_FORCEINLINE static void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT {
116  if (in) {
117  out.reset(reinterpret_cast<void *>(&out));
118  } else {
119  out.reset();
120  }
121 
122  in.reset();
123  }
124 
125  UTIL_FORCEINLINE static void reset(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { storage.reset(); }
126  UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT {
127  if (!!l == !!r) {
128  return;
129  }
130 
131  if (l) {
132  l.reset();
133  r.reset(reinterpret_cast<void *>(&r));
134  } else {
135  l.reset(reinterpret_cast<void *>(&l));
136  r.reset();
137  }
138  }
139 
140  UTIL_FORCEINLINE static const ptr_type &unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return storage; }
141  UTIL_FORCEINLINE static ptr_type &unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return storage; }
142 };
143 
144 template <class T>
145 struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_base<T, std::unique_ptr<T, small_object_optimize_storage_deleter<T> > >
146  : public std::true_type {
147  using value_type = T;
148  using ptr_type = std::unique_ptr<T, small_object_optimize_storage_deleter<T> >;
149  using storage_type = std::pair<T, ptr_type>;
150 
151  UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT {
152  memset(&out.first, 0, sizeof(out.first));
153  out.second.reset();
154  }
155 
156  template <class U, class UDELETOR,
157  typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
158  std::is_convertible<typename std::decay<U>::type, T>::value,
159  bool>::type = false>
161  std::unique_ptr<U, UDELETOR> &&in) LIBCOPP_MACRO_NOEXCEPT {
162  if (in) {
163  out.first = *in;
164  out.second.reset(&out.first);
165  in.reset();
166  } else {
167  memset(&out.first, 0, sizeof(out.first));
168  out.second.reset();
169  }
170  }
171 
172  template <class U, typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
173  std::is_convertible<typename std::decay<U>::type, T>::value,
174  bool>::type = false>
175  UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&in) LIBCOPP_MACRO_NOEXCEPT {
176  out.first = in;
177  out.second.reset(&out.first);
178  }
179 
180  template <class... U>
181  UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&...in) LIBCOPP_MACRO_NOEXCEPT {
182  out.first = value_type(std::forward<U>(in)...);
183  out.second.reset(&out.first);
184  }
185 
186  UTIL_FORCEINLINE static void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT {
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  UTIL_FORCEINLINE static void reset(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { storage.second.reset(); }
198  UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT {
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  UTIL_FORCEINLINE static const ptr_type &unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT {
216  return storage.second;
217  }
218  UTIL_FORCEINLINE static ptr_type &unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return storage.second; }
219 };
220 
221 template <class T, class TPTR>
222 struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_base : public std::false_type {
223  using value_type = T;
224  using ptr_type = TPTR;
226 
227  UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) LIBCOPP_MACRO_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) LIBCOPP_MACRO_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>
239  UTIL_FORCEINLINE static void construct_storage(storage_type &out, std::shared_ptr<U> &&in) LIBCOPP_MACRO_NOEXCEPT {
240  out = std::move(std::static_pointer_cast<typename ptr_type::element_type>(in));
241  }
242 
243  template <class... U>
244  UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&...in) LIBCOPP_MACRO_NOEXCEPT {
245  out.reset(new value_type(std::forward<U>(in)...));
246  }
247 
248  UTIL_FORCEINLINE static void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT {
249  out = std::move(in);
250  }
251 
252  UTIL_FORCEINLINE static void reset(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { storage.reset(); }
253  UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT { std::swap(l, r); }
254 
255  UTIL_FORCEINLINE static const ptr_type &unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return storage; }
256  UTIL_FORCEINLINE static ptr_type &unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return storage; }
257 };
258 
259 template <class T, class TPTR>
260 struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage;
261 
262 template <class T>
263 struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage<T, std::unique_ptr<T, small_object_optimize_storage_deleter<T> > >
264  : public std::true_type {
265  using value_type = T;
266  using ptr_type = std::unique_ptr<T, small_object_optimize_storage_deleter<T> >;
267  using storage_type = T;
268 
269  UTIL_FORCEINLINE static bool is_shared_storage() LIBCOPP_MACRO_NOEXCEPT { return false; }
271  // do nothing for trival copyable object
272  }
273  UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT {
274  memset(&out, 0, sizeof(out));
275  }
276 
277  UTIL_FORCEINLINE static void construct_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT {
278  construct_default_storage(out);
279  }
280 
281  template <class U, class UDELETOR,
282  typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
283  std::is_convertible<typename std::decay<U>::type, T>::value,
284  bool>::type = false>
286  std::unique_ptr<U, UDELETOR> &&in) LIBCOPP_MACRO_NOEXCEPT {
287  if (in) {
288  out = *in;
289  } else {
290  memset(&out, 0, sizeof(out));
291  }
292  }
293 
294  template <class U, typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value ||
295  std::is_convertible<typename std::decay<U>::type, T>::value,
296  bool>::type = false>
297  UTIL_FORCEINLINE static void construct_storage(storage_type &out, U &&in) LIBCOPP_MACRO_NOEXCEPT {
298  out = in;
299  }
300 
301  UTIL_FORCEINLINE static void clone_storage(storage_type &out, const storage_type &in) LIBCOPP_MACRO_NOEXCEPT {
302  memcpy(&out, &in, sizeof(out));
303  }
304 
305  UTIL_FORCEINLINE static void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT {
306  memcpy(&out, &in, sizeof(out));
307  memset(&in, 0, sizeof(in));
308  }
309 
310  UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT {
311  storage_type lv = l;
312  l = r;
313  r = lv;
314  }
315 
316  UTIL_FORCEINLINE static value_type *unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return &storage; }
317  UTIL_FORCEINLINE static const value_type *unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT {
318  return &storage;
319  }
320  UTIL_FORCEINLINE static ptr_type clone_ptr(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT {
321  return ptr_type(&storage);
322  }
323 };
324 
325 template <class T>
326 struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage<T, std::shared_ptr<T> > : public std::false_type {
327  using value_type = T;
328  using ptr_type = std::shared_ptr<T>;
330 
331  UTIL_FORCEINLINE static bool is_shared_storage() LIBCOPP_MACRO_NOEXCEPT { return true; }
332  UTIL_FORCEINLINE static void destroy_storage(storage_type &out) { out.reset(); }
333  UTIL_FORCEINLINE static void construct_default_storage(storage_type &out) { out.reset(); }
334 
335  template <class U, class UDELETOR,
336  typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value, bool>::type = false>
337  UTIL_FORCEINLINE static void construct_storage(storage_type &out, std::unique_ptr<U, UDELETOR> &&in) {
338  if (in) {
339  out = std::move(in);
340  } else {
341  out.reset();
342  }
343  }
344 
345  template <class U,
346  typename std::enable_if<std::is_base_of<T, typename std::decay<U>::type>::value, bool>::type = false>
347  UTIL_FORCEINLINE static void construct_storage(storage_type &out, std::shared_ptr<U> &&in) {
348  if (in) {
349  out = std::static_pointer_cast<T>(in);
350  } else {
351  out.reset();
352  }
353  }
354 
355  template <class... TARGS>
356  UTIL_FORCEINLINE static void construct_storage(storage_type &out, TARGS &&...in) {
357  out = std::make_shared<T>(std::forward<TARGS>(in)...);
358  }
359 
360  UTIL_FORCEINLINE static void clone_storage(storage_type &out, const storage_type &in) { out = in; }
361  UTIL_FORCEINLINE static void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT {
362  out.swap(in);
363  in.reset();
364  }
365 
366  UTIL_FORCEINLINE static void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT { l.swap(r); }
367 
368  UTIL_FORCEINLINE static value_type *unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return storage.get(); }
369  UTIL_FORCEINLINE static const value_type *unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT {
370  return storage.get();
371  }
372  UTIL_FORCEINLINE static ptr_type clone_ptr(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT { return storage; }
373 };
374 
375 template <class T>
376 struct default_compact_storage : public compact_storage<T, typename compact_storage_selector<T>::type> {
377  using type = compact_storage<T, typename compact_storage_selector<T>::type>;
378 };
379 
380 template <class TOK, class TERR, bool is_all_trivial>
381 class LIBCOPP_COPP_API_HEAD_ONLY result_base;
382 
383 template <class TOK, class TERR>
384 class LIBCOPP_COPP_API_HEAD_ONLY result_base<TOK, TERR, true> {
385  public:
386  using success_type = TOK;
387  using error_type = TERR;
388  enum mode_type {
389  EN_RESULT_SUCCESS = 0,
390  EN_RESULT_ERROR = 1,
391  };
392 
393  UTIL_FORCEINLINE bool is_success() const LIBCOPP_MACRO_NOEXCEPT { return mode_ == EN_RESULT_SUCCESS; }
394  UTIL_FORCEINLINE bool is_error() const LIBCOPP_MACRO_NOEXCEPT { return mode_ == EN_RESULT_ERROR; }
395 
396  UTIL_FORCEINLINE const success_type *get_success() const LIBCOPP_MACRO_NOEXCEPT {
397  return is_success() ? &success_data_ : nullptr;
398  }
399  UTIL_FORCEINLINE success_type *get_success() LIBCOPP_MACRO_NOEXCEPT {
400  return is_success() ? &success_data_ : nullptr;
401  }
402  UTIL_FORCEINLINE const error_type *get_error() const LIBCOPP_MACRO_NOEXCEPT {
403  return is_error() ? &error_data_ : nullptr;
404  }
405  UTIL_FORCEINLINE error_type *get_error() LIBCOPP_MACRO_NOEXCEPT { return is_error() ? &error_data_ : nullptr; }
406 
407  private:
408  template <class UOK, class UERR>
409  friend class result_type;
410  template <class TRESULT, bool>
412 
413  template <class TARGS>
414  UTIL_FORCEINLINE void construct_success(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT {
415  make_success_base(std::forward<TARGS>(args));
416  }
417 
418  template <class TARGS>
419  UTIL_FORCEINLINE void construct_error(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT {
420  make_error_base(std::forward<TARGS>(args));
421  }
422 
423  template <class TARGS>
424  UTIL_FORCEINLINE void make_success_base(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT {
425  success_data_ = args;
426  mode_ = EN_RESULT_SUCCESS;
427  }
428 
429  template <class TARGS>
430  UTIL_FORCEINLINE void make_error_base(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT {
431  error_data_ = args;
432  mode_ = EN_RESULT_ERROR;
433  }
434 
435  inline void swap(result_base &other) LIBCOPP_MACRO_NOEXCEPT {
436  using std::swap;
437  if (is_success()) {
438  swap(success_data_, other.success_data_);
439  } else {
440  swap(error_data_, other.error_data_);
441  }
442  swap(mode_, other.mode_);
443  }
444 
445  UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) LIBCOPP_MACRO_NOEXCEPT { l.swap(r); }
446 
447  private:
448  union {
451  };
453 };
454 
455 template <class TOK, class TERR>
456 class LIBCOPP_COPP_API_HEAD_ONLY result_base<TOK, TERR, false> {
457  public:
458  using success_type = TOK;
459  using error_type = TERR;
460  enum mode_type {
461  EN_RESULT_SUCCESS = 0,
462  EN_RESULT_ERROR = 1,
463  EN_RESULT_NONE = 2,
464  };
465 
466  UTIL_FORCEINLINE bool is_success() const LIBCOPP_MACRO_NOEXCEPT { return mode_ == EN_RESULT_SUCCESS; }
467  UTIL_FORCEINLINE bool is_error() const LIBCOPP_MACRO_NOEXCEPT { return mode_ == EN_RESULT_ERROR; }
468 
469  UTIL_FORCEINLINE const success_type *get_success() const LIBCOPP_MACRO_NOEXCEPT {
470  return is_success() ? success_storage_type::unwrap(success_data_) : nullptr;
471  }
472  UTIL_FORCEINLINE success_type *get_success() LIBCOPP_MACRO_NOEXCEPT {
473  return is_success() ? success_storage_type::unwrap(success_data_) : nullptr;
474  }
475  UTIL_FORCEINLINE const error_type *get_error() const LIBCOPP_MACRO_NOEXCEPT {
476  return is_error() ? error_storage_type::unwrap(error_data_) : nullptr;
477  }
478  UTIL_FORCEINLINE error_type *get_error() LIBCOPP_MACRO_NOEXCEPT {
479  return is_error() ? error_storage_type::unwrap(error_data_) : nullptr;
480  }
481 
482  result_base() : mode_(EN_RESULT_NONE) {
483  success_storage_type::construct_default_storage(success_data_);
484  error_storage_type::construct_default_storage(error_data_);
485  }
486  ~result_base() { reset(); }
487 
488  result_base(result_base &&other) : mode_(EN_RESULT_NONE) {
489  success_storage_type::construct_default_storage(success_data_);
490  error_storage_type::construct_default_storage(error_data_);
491 
492  swap(other);
493  }
494 
496  swap(other);
497  other.reset();
498  return *this;
499  }
500 
501  UTIL_FORCEINLINE void swap(result_base &other) LIBCOPP_MACRO_NOEXCEPT {
502  using std::swap;
503  success_storage_type::swap(success_data_, other.success_data_);
504  error_storage_type::swap(error_data_, other.error_data_);
505  swap(mode_, other.mode_);
506  }
507 
508  UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) LIBCOPP_MACRO_NOEXCEPT { l.swap(r); }
509 
510  private:
511  template <class UOK, class UERR>
512  friend class result_type;
513  template <class TRESULT, bool>
515 
516  template <class... TARGS>
517  UTIL_FORCEINLINE void construct_success(TARGS &&...args) {
518  reset();
519  success_storage_type::construct_storage(success_data_, std::forward<TARGS>(args)...);
520  mode_ = EN_RESULT_SUCCESS;
521  }
522 
523  template <class... TARGS>
524  UTIL_FORCEINLINE void construct_error(TARGS &&...args) {
525  reset();
526  error_storage_type::construct_storage(error_data_, std::forward<TARGS>(args)...);
527  mode_ = EN_RESULT_ERROR;
528  }
529 
530  template <class... TARGS>
531  UTIL_FORCEINLINE void make_success_base(TARGS &&...args) {
532  reset();
533  make_object<success_storage_type>(success_data_, std::forward<TARGS>(args)...);
534  mode_ = EN_RESULT_SUCCESS;
535  }
536 
537  template <class... TARGS>
538  UTIL_FORCEINLINE void make_error_base(TARGS &&...args) {
539  reset();
540  make_object<error_storage_type>(error_data_, std::forward<TARGS>(args)...);
541  mode_ = EN_RESULT_ERROR;
542  }
543 
544  inline void reset() {
545  if (EN_RESULT_SUCCESS == mode_) {
546  success_storage_type::destroy_storage(success_data_);
547  } else if (EN_RESULT_ERROR == mode_) {
548  error_storage_type::destroy_storage(error_data_);
549  }
550 
551  mode_ = EN_RESULT_NONE;
552  }
553 
554  private:
555  template <class TSTORAGE, class... TARGS>
556  UTIL_FORCEINLINE static void make_object(typename TSTORAGE::storage_type &out, TARGS &&...args) {
557  TSTORAGE::construct_storage(out, std::forward<TARGS>(args)...);
558  }
559 
560  template <class TSTORAGE, class... TARGS>
561  UTIL_FORCEINLINE static void make_object(std::shared_ptr<typename TSTORAGE::storage_type> &out, TARGS &&...args) {
562  TSTORAGE::construct_storage(out, std::make_shared<typename TSTORAGE::storage_type>(std::forward<TARGS>(args)...));
563  }
564 
567 
568  typename success_storage_type::storage_type success_data_;
569  typename error_storage_type::storage_type error_data_;
571 };
572 
573 template <class TRESULT, bool>
574 struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper;
575 
576 template <class TRESULT>
577 struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper<TRESULT, false> {
578  using type = std::unique_ptr<TRESULT>;
579 
580  template <class... TARGS>
581  inline static type make_success(TARGS &&...args) {
582  type ret = LIBCOPP_COPP_NAMESPACE_ID::future::make_unique<TRESULT>();
583  if (ret) {
584  ret->make_success_base(std::forward<TARGS>(args)...);
585  }
586 
587  return ret;
588  }
589 
590  template <class... TARGS>
591  inline static type make_error(TARGS &&...args) {
592  type ret = LIBCOPP_COPP_NAMESPACE_ID::future::make_unique<TRESULT>();
593  if (ret) {
594  ret->make_error_base(std::forward<TARGS>(args)...);
595  }
596 
597  return ret;
598  }
599 };
600 
601 template <class TRESULT>
602 struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper<TRESULT, true> {
603  using type = TRESULT;
604 
605  template <class... TARGS>
606  UTIL_FORCEINLINE static type make_success(TARGS &&...args) {
607  TRESULT ret;
608  ret.make_success_base(std::forward<TARGS>(args)...);
609  return ret;
610  }
611 
612  template <class... TARGS>
613  UTIL_FORCEINLINE static type make_error(TARGS &&...args) {
614  TRESULT ret;
615  ret.make_error_base(std::forward<TARGS>(args)...);
616  return ret;
617  }
618 };
619 
620 template <class TOK, class TERR>
621 class LIBCOPP_COPP_API_HEAD_ONLY result_type
622  : public result_base<TOK, TERR, default_compact_storage<TOK>::value && default_compact_storage<TERR>::value> {
623  public:
624  using base_type = result_base<TOK, TERR, default_compact_storage<TOK>::value && default_compact_storage<TERR>::value>;
626 
627  private:
630 
631  public:
632  using storage_type = typename _make_instance_type::type;
633 
634  template <class... TARGS>
635  UTIL_FORCEINLINE static self_type create_success(TARGS &&...args) {
636  self_type ret;
637  ret.construct_success(std::forward<TARGS>(args)...);
638  return ret;
639  }
640 
641  template <class... TARGS>
642  UTIL_FORCEINLINE static self_type create_error(TARGS &&...args) {
643  self_type ret;
644  ret.construct_error(std::forward<TARGS>(args)...);
645  return ret;
646  }
647 
648  public:
649  template <class... TARGS>
650  UTIL_FORCEINLINE static storage_type make_success(TARGS &&...args) {
651  return _make_instance_type::make_success(std::forward<TARGS>(args)...);
652  }
653 
654  template <class... TARGS>
655  UTIL_FORCEINLINE static storage_type make_error(TARGS &&...args) {
656  return _make_instance_type::make_error(std::forward<TARGS>(args)...);
657  }
658 };
659 } // namespace future
660 LIBCOPP_COPP_NAMESPACE_END
UTIL_FORCEINLINE const error_type * get_error() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:475
UTIL_FORCEINLINE bool is_error() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:467
UTIL_FORCEINLINE void swap(result_base &other) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:501
UTIL_FORCEINLINE const success_type * get_success() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:469
UTIL_FORCEINLINE success_type * get_success() LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:472
UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:508
success_storage_type::storage_type success_data_
Definition: storage.h:568
UTIL_FORCEINLINE void make_error_base(TARGS &&...args)
Definition: storage.h:538
UTIL_FORCEINLINE error_type * get_error() LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:478
UTIL_FORCEINLINE void make_success_base(TARGS &&...args)
Definition: storage.h:531
static UTIL_FORCEINLINE void make_object(std::shared_ptr< typename TSTORAGE::storage_type > &out, TARGS &&...args)
Definition: storage.h:561
static UTIL_FORCEINLINE void make_object(typename TSTORAGE::storage_type &out, TARGS &&...args)
Definition: storage.h:556
result_base & operator=(result_base &&other)
Definition: storage.h:495
UTIL_FORCEINLINE void construct_error(TARGS &&...args)
Definition: storage.h:524
error_storage_type::storage_type error_data_
Definition: storage.h:569
typename default_compact_storage< success_type >::type success_storage_type
Definition: storage.h:565
typename default_compact_storage< error_type >::type error_storage_type
Definition: storage.h:566
UTIL_FORCEINLINE bool is_success() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:466
result_base(result_base &&other)
Definition: storage.h:488
UTIL_FORCEINLINE void construct_success(TARGS &&...args)
Definition: storage.h:517
UTIL_FORCEINLINE const error_type * get_error() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:402
UTIL_FORCEINLINE success_type * get_success() LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:399
UTIL_FORCEINLINE void construct_error(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:419
UTIL_FORCEINLINE bool is_error() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:394
UTIL_FORCEINLINE error_type * get_error() LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:405
UTIL_FORCEINLINE friend void swap(result_base &l, result_base &r) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:445
UTIL_FORCEINLINE void make_success_base(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:424
void swap(result_base &other) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:435
UTIL_FORCEINLINE void make_error_base(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:430
UTIL_FORCEINLINE void construct_success(TARGS &&args) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:414
UTIL_FORCEINLINE const success_type * get_success() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:396
UTIL_FORCEINLINE bool is_success() const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:393
result_base< TOK, TERR, default_compact_storage< TOK >::value &&default_compact_storage< TERR >::value > base_type
Definition: storage.h:624
static UTIL_FORCEINLINE self_type create_success(TARGS &&...args)
Definition: storage.h:635
_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:629
typename _make_instance_type::type storage_type
Definition: storage.h:632
static UTIL_FORCEINLINE storage_type make_success(TARGS &&...args)
Definition: storage.h:650
static UTIL_FORCEINLINE self_type create_error(TARGS &&...args)
Definition: storage.h:642
static UTIL_FORCEINLINE storage_type make_error(TARGS &&...args)
Definition: storage.h:655
#define UTIL_FORCEINLINE
导入继承关系约束 Licensed under the MIT licenses.
#define EXPLICIT_NODISCARD_ATTR
nodiscard, 标记禁止忽略返回值 usage: EXPLICIT_NODISCARD_ATTR int a; class EXPLICIT_NODISCARD_ATTR a; EXPLICIT_...
Definition: future.h:18
EXPLICIT_NODISCARD_ATTR std::unique_ptr< T > make_unique(TARGS &&...args)
Definition: storage.h:27
class LIBCOPP_COPP_API_HEAD_ONLY result_base
Definition: storage.h:381
struct LIBCOPP_COPP_API_HEAD_ONLY poll_storage_ptr_selector
Definition: storage.h:52
struct LIBCOPP_COPP_API_HEAD_ONLY _make_result_instance_helper
Definition: storage.h:574
struct LIBCOPP_COPP_API_HEAD_ONLY compact_storage
Definition: storage.h:260
std::shared_ptr< cli::cmd_option_value > value_type
Definition: cmd_option.h:50
void swap(intrusive_ptr< T > &lhs, intrusive_ptr< T > &rhs)
static UTIL_FORCEINLINE type make_error(TARGS &&...args)
Definition: storage.h:613
static UTIL_FORCEINLINE type make_success(TARGS &&...args)
Definition: storage.h:606
static UTIL_FORCEINLINE void construct_default_storage(storage_type &out)
Definition: storage.h:333
static UTIL_FORCEINLINE void clone_storage(storage_type &out, const storage_type &in)
Definition: storage.h:360
static UTIL_FORCEINLINE value_type * unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:368
static UTIL_FORCEINLINE void construct_storage(storage_type &out, TARGS &&...in)
Definition: storage.h:356
static UTIL_FORCEINLINE bool is_shared_storage() LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:331
static UTIL_FORCEINLINE void destroy_storage(storage_type &out)
Definition: storage.h:332
static UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:361
static UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in)
Definition: storage.h:337
static UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:366
static UTIL_FORCEINLINE ptr_type clone_ptr(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:372
static UTIL_FORCEINLINE void construct_storage(storage_type &out, std::shared_ptr< U > &&in)
Definition: storage.h:347
static UTIL_FORCEINLINE const value_type * unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:369
static UTIL_FORCEINLINE void clone_storage(storage_type &out, const storage_type &in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:301
static UTIL_FORCEINLINE ptr_type clone_ptr(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:320
static UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:297
static UTIL_FORCEINLINE void construct_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:277
static UTIL_FORCEINLINE value_type * unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:316
static UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:285
static UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:310
static UTIL_FORCEINLINE const value_type * unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:317
static UTIL_FORCEINLINE void construct_default_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:273
static UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:305
std::unique_ptr< T, small_object_optimize_storage_deleter< T > > ptr_type
Definition: storage.h:266
std::unique_ptr< void, small_object_optimize_storage_deleter< void > > type
Definition: storage.h:71
typename std::conditional< COPP_IS_TIRVIALLY_COPYABLE_V(T) &&sizeof(T)<=(sizeof(size_t)<< 2), std::unique_ptr< T, small_object_optimize_storage_deleter< T > >, std::shared_ptr< T > >::type type
Definition: storage.h:78
compact_storage< T, typename compact_storage_selector< T >::type > type
Definition: storage.h:377
std::unique_ptr< T, small_object_optimize_storage_deleter< T > > ptr_type
Definition: storage.h:148
static UTIL_FORCEINLINE void construct_default_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:151
static UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:175
static UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&...in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:181
static UTIL_FORCEINLINE void reset(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:197
static UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:160
static UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:186
static UTIL_FORCEINLINE ptr_type & unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:218
static UTIL_FORCEINLINE const ptr_type & unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:215
static UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:198
static UTIL_FORCEINLINE const ptr_type & unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:140
static UTIL_FORCEINLINE ptr_type & unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:141
static UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:126
static UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:115
static UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:96
static UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:107
std::unique_ptr< void, small_object_optimize_storage_deleter< void > > ptr_type
Definition: storage.h:89
static UTIL_FORCEINLINE void reset(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:125
static UTIL_FORCEINLINE void construct_default_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:92
static UTIL_FORCEINLINE void reset(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:252
static UTIL_FORCEINLINE ptr_type & unwrap(storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:256
static UTIL_FORCEINLINE void construct_storage(storage_type &out, U &&...in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:244
static UTIL_FORCEINLINE void construct_storage(storage_type &out, std::unique_ptr< U, UDELETOR > &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:231
static UTIL_FORCEINLINE const ptr_type & unwrap(const storage_type &storage) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:255
static UTIL_FORCEINLINE void move_storage(storage_type &out, storage_type &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:248
static UTIL_FORCEINLINE void swap(storage_type &l, storage_type &r) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:253
static UTIL_FORCEINLINE void construct_default_storage(storage_type &out) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:227
static UTIL_FORCEINLINE void construct_storage(storage_type &out, std::shared_ptr< U > &&in) LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:239
std::unique_ptr< void, small_object_optimize_storage_deleter< void > > type
Definition: storage.h:56
typename std::conditional< COPP_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
UTIL_FORCEINLINE void operator()(T *) const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:42
UTIL_FORCEINLINE void operator()(U *) const LIBCOPP_MACRO_NOEXCEPT
Definition: storage.h:46
type_traits compatiable Licensed under the MIT licenses.
#define COPP_IS_TIRVIALLY_COPYABLE_V(X)
Definition: type_traits.h:43