ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Optional.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include <cassert>
11 #include <functional>
12 #include <initializer_list>
13 #include <stdexcept>
14 #include <string>
15 #include <type_traits>
16 #include <utility>
17 
18 #include "CVCoreLib.h"
19 
20 #define TR2_OPTIONAL_REQUIRES(...) \
21  typename std::enable_if<__VA_ARGS__::value, bool>::type = false
22 
23 namespace cloudViewer {
24 namespace utility {
25 
26 struct in_place_t {
27  explicit in_place_t() = default;
28 };
29 
30 template <std::size_t I>
32  explicit in_place_index_t() = default;
33 };
34 
35 template <typename T>
37  explicit in_place_type_t() = default;
38 };
39 
40 constexpr in_place_t in_place{};
41 
42 // 20.5.4, optional for object types
43 template <class T>
44 class optional;
45 
46 // 20.5.5, optional for lvalue reference types
47 template <class T>
48 class optional<T&>;
49 
50 // workaround: std utility functions aren't constexpr yet
51 template <class T>
52 inline constexpr T&& constexpr_forward(
53  typename std::remove_reference<T>::type& t) noexcept {
54  return static_cast<T&&>(t);
55 }
56 
57 template <class T>
58 inline constexpr T&& constexpr_forward(
59  typename std::remove_reference<T>::type&& t) noexcept {
60  static_assert(!std::is_lvalue_reference<T>::value, "!!");
61  return static_cast<T&&>(t);
62 }
63 
64 template <class T>
65 inline constexpr typename std::remove_reference<T>::type&& constexpr_move(
66  T&& t) noexcept {
67  return static_cast<typename std::remove_reference<T>::type&&>(t);
68 }
69 
70 #if defined NDEBUG
71 #define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
72 #else
73 #define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) \
74  ((CHECK) ? (EXPR) : ([] { assert(!#CHECK); }(), (EXPR)))
75 #endif
76 
77 #if defined(__CUDA_ARCH__)
78 #define TR2_OPTIONAL_HOST_CONSTEXPR
79 #else
80 #define TR2_OPTIONAL_HOST_CONSTEXPR constexpr
81 #endif
82 
83 namespace detail_ {
84 
85 // VS doesn't handle constexpr well, so we need to skip these stuff.
86 #if (defined _MSC_VER)
87 template <typename T>
88 T* static_addressof(T& ref) {
89  return std::addressof(ref);
90 }
91 #else
92 // static_addressof: a constexpr version of addressof
93 template <typename T>
95  template <class X>
96  constexpr static bool has_overload(...) {
97  return false;
98  }
99 
100  template <class X, size_t S = sizeof(std::declval<X&>().operator&())>
101  constexpr static bool has_overload(bool) {
102  return true;
103  }
104 
105  constexpr static bool value = has_overload<T>(true);
106 };
107 
108 template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
109 constexpr T* static_addressof(T& ref) {
110  return &ref;
111 }
112 
113 template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
114 T* static_addressof(T& ref) {
115  return std::addressof(ref);
116 }
117 #endif
118 
119 // the call to convert<A>(b) has return type A and converts b to type A iff b
120 // decltype(b) is implicitly convertible to A
121 template <class U>
122 constexpr U convert(U v) {
123  return v;
124 }
125 
126 } // namespace detail_
127 
128 constexpr struct trivial_init_t {
130 
131 // 20.5.7, Disengaged state indicator
132 struct nullopt_t {
133  struct init {};
134  constexpr explicit nullopt_t(init) {}
135 };
137 
138 // 20.5.8, class bad_optional_access
139 class bad_optional_access : public std::logic_error {
140 public:
141  explicit bad_optional_access(const std::string& what_arg)
142  : logic_error{what_arg} {}
143  explicit bad_optional_access(const char* what_arg)
144  : logic_error{what_arg} {}
145 };
146 
147 template <class T>
148 union storage_t {
149  unsigned char dummy_;
151 
152  constexpr storage_t(trivial_init_t) noexcept : dummy_() {};
153 
154  template <class... Args>
155  constexpr storage_t(Args&&... args)
156  : value_(constexpr_forward<Args>(args)...) {}
157 
159 };
160 
161 template <class T>
163  unsigned char dummy_;
165 
166  constexpr constexpr_storage_t(trivial_init_t) noexcept : dummy_() {};
167 
168  template <class... Args>
169  constexpr constexpr_storage_t(Args&&... args)
170  : value_(constexpr_forward<Args>(args)...) {}
171 
172  ~constexpr_storage_t() = default;
173 };
174 
175 template <class T>
177  bool init_;
179 
180  constexpr optional_base() noexcept
181  : init_(false), storage_(trivial_init) {};
182 
183  explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
184 
185  explicit constexpr optional_base(T&& v)
186  : init_(true), storage_(constexpr_move(v)) {}
187 
188  template <class... Args>
189  explicit optional_base(in_place_t, Args&&... args)
190  : init_(true), storage_(constexpr_forward<Args>(args)...) {}
191 
192  template <class U,
193  class... Args,
195  std::is_constructible<T, std::initializer_list<U>>)>
197  std::initializer_list<U> il,
198  Args&&... args)
199  : init_(true), storage_(il, std::forward<Args>(args)...) {}
200 
202  if (init_) storage_.value_.T::~T();
203  }
204 };
205 
206 template <class T>
208  bool init_;
210 
211  constexpr constexpr_optional_base() noexcept
212  : init_(false), storage_(trivial_init) {};
213 
214  explicit constexpr constexpr_optional_base(const T& v)
215  : init_(true), storage_(v) {}
216 
217  explicit constexpr constexpr_optional_base(T&& v)
218  : init_(true), storage_(constexpr_move(v)) {}
219 
220  template <class... Args>
221  explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
222  : init_(true), storage_(constexpr_forward<Args>(args)...) {}
223 
224  template <class U,
225  class... Args,
227  std::is_constructible<T, std::initializer_list<U>>)>
229  std::initializer_list<U> il,
230  Args&&... args)
231  : init_(true), storage_(il, std::forward<Args>(args)...) {}
232 
234 };
235 
236 template <class T>
237 using OptionalBase = typename std::conditional<
238  std::is_trivially_destructible<T>::value, // if possible
239  constexpr_optional_base<typename std::remove_const<
240  T>::type>, // use base with trivial destructor
242 
243 template <class T>
244 class optional : private OptionalBase<T> {
245  template <class U> // re-declaration for nvcc on Windows.
246  using OptionalBase = typename std::conditional<
247  std::is_trivially_destructible<U>::value, // if possible
248  constexpr_optional_base<typename std::remove_const<
249  U>::type>, // use base with trivial destructor
251 
252  static_assert(!std::is_same<typename std::decay<T>::type, nullopt_t>::value,
253  "bad T");
254  static_assert(
255  !std::is_same<typename std::decay<T>::type, in_place_t>::value,
256  "bad T");
257 
258  constexpr bool initialized() const noexcept {
259  return OptionalBase<T>::init_;
260  }
261  typename std::remove_const<T>::type* dataptr() {
262  return std::addressof(OptionalBase<T>::storage_.value_);
263  }
264  constexpr const T* dataptr() const {
265  return detail_::static_addressof(OptionalBase<T>::storage_.value_);
266  }
267 
268  constexpr const T& contained_val() const& {
269  return OptionalBase<T>::storage_.value_;
270  }
271  constexpr T&& contained_val() && {
272  return std::move(OptionalBase<T>::storage_.value_);
273  }
274  constexpr T& contained_val() & { return OptionalBase<T>::storage_.value_; }
275 
276  void clear() noexcept {
277  if (initialized()) dataptr()->~T();
278  OptionalBase<T>::init_ = false;
279  }
280 
281  template <class... Args>
282  void initialize(Args&&... args) noexcept(
283  noexcept(T(std::forward<Args>(args)...))) {
284  assert(!OptionalBase<T>::init_);
285  ::new (static_cast<void*>(dataptr())) T(std::forward<Args>(args)...);
286  OptionalBase<T>::init_ = true;
287  }
288 
289  template <class U, class... Args>
290  void initialize(std::initializer_list<U> il, Args&&... args) noexcept(
291  noexcept(T(il, std::forward<Args>(args)...))) {
292  assert(!OptionalBase<T>::init_);
293  ::new (static_cast<void*>(dataptr()))
294  T(il, std::forward<Args>(args)...);
295  OptionalBase<T>::init_ = true;
296  }
297 
298 public:
299  typedef T value_type;
300 
301  // 20.5.5.1, constructors
302  constexpr optional() noexcept : OptionalBase<T>() {};
303  constexpr optional(nullopt_t) noexcept : OptionalBase<T>() {};
304 
305  optional(const optional& rhs) : OptionalBase<T>() {
306  if (rhs.initialized()) {
307  ::new (static_cast<void*>(dataptr())) T(*rhs);
308  OptionalBase<T>::init_ = true;
309  }
310  }
311 
312  optional(optional&& rhs) noexcept(
313  std::is_nothrow_move_constructible<T>::value)
314  : OptionalBase<T>() {
315  if (rhs.initialized()) {
316  ::new (static_cast<void*>(dataptr())) T(std::move(*rhs));
317  OptionalBase<T>::init_ = true;
318  }
319  }
320 
321  // see https://github.com/akrzemi1/Optional/issues/16
322  // and https://en.cppreference.com/w/cpp/utility/optional/optional,
323  // in constructor 8, the std::optional spec can allow initialization
324  // of optionals from convertible type U
325  //
326  // 8 - implicit move construct from value
327  template <typename U = T,
328  TR2_OPTIONAL_REQUIRES(std::is_constructible<T, U&&>::value &&
329  !std::is_same<typename std::decay<U>::type,
330  in_place_t>::value &&
331  !std::is_same<typename std::decay<U>::type,
332  optional<T>>::value &&
333  std::is_convertible<U&&, T>)>
334  constexpr optional(U&& u) : OptionalBase<T>(std::forward<U>(u)) {}
335 
336  // 8 - explicit move construct from value
337  template <typename U = T,
338  TR2_OPTIONAL_REQUIRES(std::is_constructible<T, U&&>::value &&
339  !std::is_same<typename std::decay<U>::type,
340  in_place_t>::value &&
341  !std::is_same<typename std::decay<U>::type,
342  optional<T>>::value &&
343  !std::is_convertible<U&&, T>)>
344  explicit constexpr optional(U&& u) : OptionalBase<T>(std::forward<U>(u)) {}
345 
346  template <class... Args>
347  explicit constexpr optional(in_place_t, Args&&... args)
348  : OptionalBase<T>(in_place_t{}, constexpr_forward<Args>(args)...) {}
349 
350  template <class U,
351  class... Args,
353  std::is_constructible<T, std::initializer_list<U>>)>
354  constexpr explicit optional(in_place_t,
355  std::initializer_list<U> il,
356  Args&&... args)
357  : OptionalBase<T>(in_place_t{}, il, constexpr_forward<Args>(args)...) {}
358 
359  // 20.5.4.2, Destructor
360  ~optional() = default;
361 
362  // 20.5.4.3, assignment
364  clear();
365  return *this;
366  }
367 
368  optional& operator=(const optional& rhs) {
369  if (initialized() == true && rhs.initialized() == false)
370  clear();
371  else if (initialized() == false && rhs.initialized() == true)
372  initialize(*rhs);
373  else if (initialized() == true && rhs.initialized() == true)
374  contained_val() = *rhs;
375  return *this;
376  }
377 
378  optional& operator=(optional&& rhs) noexcept(
379  std::is_nothrow_move_assignable<T>::value &&
380  std::is_nothrow_move_constructible<T>::value) {
381  if (initialized() == true && rhs.initialized() == false)
382  clear();
383  else if (initialized() == false && rhs.initialized() == true)
384  initialize(std::move(*rhs));
385  else if (initialized() == true && rhs.initialized() == true)
386  contained_val() = std::move(*rhs);
387  return *this;
388  }
389 
390  template <class U = T>
391  auto operator=(U&& v) ->
392  typename std::enable_if<
393  std::is_constructible<T, U>::value &&
396  (std::is_scalar<T>::value ||
398  T>::value) &&
399  std::is_assignable<T&, U>::value,
400  optional&>::type {
401  if (initialized()) {
402  contained_val() = std::forward<U>(v);
403  } else {
404  initialize(std::forward<U>(v));
405  }
406  return *this;
407  }
408 
409  template <class... Args>
410  void emplace(Args&&... args) {
411  clear();
412  initialize(std::forward<Args>(args)...);
413  }
414 
415  template <class U, class... Args>
416  void emplace(std::initializer_list<U> il, Args&&... args) {
417  clear();
418  initialize<U, Args...>(il, std::forward<Args>(args)...);
419  }
420 
421  // 20.5.4.4, Swap
422  void swap(optional<T>& rhs) noexcept(
423  std::is_nothrow_move_constructible<T>::value &&
424  noexcept(std::swap(std::declval<T&>(), std::declval<T&>()))) {
425  if (initialized() == true && rhs.initialized() == false) {
426  rhs.initialize(std::move(**this));
427  clear();
428  } else if (initialized() == false && rhs.initialized() == true) {
429  initialize(std::move(*rhs));
430  rhs.clear();
431  } else if (initialized() == true && rhs.initialized() == true) {
432  using std::swap;
433  swap(**this, *rhs);
434  }
435  }
436 
437  // 20.5.4.5, Observers
438 
439  explicit constexpr operator bool() const noexcept { return initialized(); }
440  constexpr bool has_value() const noexcept { return initialized(); }
441 
443  return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
444  }
445 
447  assert(initialized());
448  return dataptr();
449  }
450 
452  return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
453  }
454 
456  assert(initialized());
457  return contained_val();
458  }
459 
461  assert(initialized());
462  return constexpr_move(contained_val());
463  }
464 
465  TR2_OPTIONAL_HOST_CONSTEXPR T const& value() const& {
466  return initialized()
467  ? contained_val()
468  : (throw bad_optional_access("bad optional access"),
469  contained_val());
470  }
471 
473  return initialized()
474  ? contained_val()
475  : (throw bad_optional_access("bad optional access"),
476  contained_val());
477  }
478 
480  if (!initialized()) throw bad_optional_access("bad optional access");
481  return std::move(contained_val());
482  }
483 
484  template <class V>
485  constexpr T value_or(V&& v) const& {
486  return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
487  }
488 
489  template <class V>
490  constexpr T value_or(V&& v) && {
491  return *this ? constexpr_move(
492  const_cast<optional<T>&>(*this).contained_val())
493  : detail_::convert<T>(constexpr_forward<V>(v));
494  }
495 
496  // 20.6.3.6, modifiers
497  void reset() noexcept { clear(); }
498 };
499 
500 // XXX: please refrain from using optional<T&>, since it is being against with
501 // the optional standard in c++ 17, see the debate and the details here:
502 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3406#rationale.refs
503 // if you need it, consider using optional<std::reference_wrapper<T>> or *
504 // pointer
505 //
506 // we leave the implementation here in case we want to reconsider using it in
507 // the future if it becomes a definitely necessary case.
508 template <class T>
509 class optional<T&> {
510  // add this assert to prevent user from using optional reference as
511  // indicated above
512  static_assert(sizeof(T) == 0,
513  "optional references is ill-formed, \
514  consider use optional of a std::reference_wrapper of type T to \
515  hold a reference if you really need to");
516 
517  static_assert(!std::is_same<T, nullopt_t>::value, "bad T");
518  static_assert(!std::is_same<T, in_place_t>::value, "bad T");
519  T* ref;
520 
521 public:
522  // 20.5.5.1, construction/destruction
523  constexpr optional() noexcept : ref(nullptr) {}
524 
525  constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
526 
527  template <typename U = T>
528  constexpr optional(U& u) noexcept : ref(detail_::static_addressof(u)) {}
529 
530  template <typename U = T>
531  optional(U&&) = delete;
532 
533  constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
534 
535  explicit constexpr optional(in_place_t, T& v) noexcept
536  : ref(detail_::static_addressof(v)) {}
537 
538  explicit optional(in_place_t, T&&) = delete;
539 
540  ~optional() = default;
541 
542  // 20.5.5.2, mutation
544  ref = nullptr;
545  return *this;
546  }
547 
548  // optional& operator=(const optional& rhs) noexcept {
549  // ref = rhs.ref;
550  // return *this;
551  // }
552 
553  // optional& operator=(optional&& rhs) noexcept {
554  // ref = rhs.ref;
555  // return *this;
556  // }
557 
558  template <typename U>
559  auto operator=(U&& rhs) noexcept ->
561  optional<T&>>::value,
562  optional&>::type {
563  ref = rhs.ref;
564  return *this;
565  }
566 
567  template <typename U>
568  auto operator=(U&& rhs) noexcept ->
570  optional<T&>>::value,
571  optional&>::type = delete;
572 
573  void emplace(T& v) noexcept { ref = detail_::static_addressof(v); }
574 
575  void emplace(T&&) = delete;
576 
577  void swap(optional<T&>& rhs) noexcept { std::swap(ref, rhs.ref); }
578 
579  // 20.5.5.3, observers
581  return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
582  }
583 
585  return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
586  }
587 
588  constexpr T& value() const {
589  return ref ? *ref
590  : (throw bad_optional_access("bad optional access"), *ref);
591  }
592 
593  explicit constexpr operator bool() const noexcept { return ref != nullptr; }
594 
595  constexpr bool has_value() const noexcept { return ref != nullptr; }
596 
597  template <class V>
598  constexpr typename std::decay<T>::type value_or(V&& v) const {
599  return *this ? **this
601  constexpr_forward<V>(v));
602  }
603 
604  // x.x.x.x, modifiers
605  void reset() noexcept { ref = nullptr; }
606 };
607 
608 template <class T>
609 class optional<T&&> {
610  static_assert(sizeof(T) == 0, "optional rvalue references disallowed");
611 };
612 
613 // 20.5.8, Relational operators
614 template <class T>
615 constexpr bool operator==(const optional<T>& x, const optional<T>& y) {
616  return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
617 }
618 
619 template <class T>
620 constexpr bool operator!=(const optional<T>& x, const optional<T>& y) {
621  return !(x == y);
622 }
623 
624 template <class T>
625 constexpr bool operator<(const optional<T>& x, const optional<T>& y) {
626  return (!y) ? false : (!x) ? true : *x < *y;
627 }
628 
629 template <class T>
630 constexpr bool operator>(const optional<T>& x, const optional<T>& y) {
631  return (y < x);
632 }
633 
634 template <class T>
635 constexpr bool operator<=(const optional<T>& x, const optional<T>& y) {
636  return !(y < x);
637 }
638 
639 template <class T>
640 constexpr bool operator>=(const optional<T>& x, const optional<T>& y) {
641  return !(x < y);
642 }
643 
644 // 20.5.9, Comparison with nullopt
645 template <class T>
646 constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept {
647  return (!x);
648 }
649 
650 template <class T>
651 constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept {
652  return (!x);
653 }
654 
655 template <class T>
656 constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept {
657  return bool(x);
658 }
659 
660 template <class T>
661 constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept {
662  return bool(x);
663 }
664 
665 template <class T>
666 constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
667  return false;
668 }
669 
670 template <class T>
671 constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept {
672  return bool(x);
673 }
674 
675 template <class T>
676 constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept {
677  return (!x);
678 }
679 
680 template <class T>
681 constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
682  return true;
683 }
684 
685 template <class T>
686 constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept {
687  return bool(x);
688 }
689 
690 template <class T>
691 constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
692  return false;
693 }
694 
695 template <class T>
696 constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
697  return true;
698 }
699 
700 template <class T>
701 constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept {
702  return (!x);
703 }
704 
705 // 20.5.10, Comparison with T
706 template <class T>
707 constexpr bool operator==(const optional<T>& x, const T& v) {
708  return bool(x) ? *x == v : false;
709 }
710 
711 template <class T>
712 constexpr bool operator==(const T& v, const optional<T>& x) {
713  return bool(x) ? v == *x : false;
714 }
715 
716 template <class T>
717 constexpr bool operator!=(const optional<T>& x, const T& v) {
718  return bool(x) ? *x != v : true;
719 }
720 
721 template <class T>
722 constexpr bool operator!=(const T& v, const optional<T>& x) {
723  return bool(x) ? v != *x : true;
724 }
725 
726 template <class T>
727 constexpr bool operator<(const optional<T>& x, const T& v) {
728  return bool(x) ? *x < v : true;
729 }
730 
731 template <class T>
732 constexpr bool operator>(const T& v, const optional<T>& x) {
733  return bool(x) ? v > *x : true;
734 }
735 
736 template <class T>
737 constexpr bool operator>(const optional<T>& x, const T& v) {
738  return bool(x) ? *x > v : false;
739 }
740 
741 template <class T>
742 constexpr bool operator<(const T& v, const optional<T>& x) {
743  return bool(x) ? v < *x : false;
744 }
745 
746 template <class T>
747 constexpr bool operator>=(const optional<T>& x, const T& v) {
748  return bool(x) ? *x >= v : false;
749 }
750 
751 template <class T>
752 constexpr bool operator<=(const T& v, const optional<T>& x) {
753  return bool(x) ? v <= *x : false;
754 }
755 
756 template <class T>
757 constexpr bool operator<=(const optional<T>& x, const T& v) {
758  return bool(x) ? *x <= v : true;
759 }
760 
761 template <class T>
762 constexpr bool operator>=(const T& v, const optional<T>& x) {
763  return bool(x) ? v >= *x : true;
764 }
765 
766 // Comparison of optional<T&> with T
767 template <class T>
768 constexpr bool operator==(const optional<T&>& x, const T& v) {
769  return bool(x) ? *x == v : false;
770 }
771 
772 template <class T>
773 constexpr bool operator==(const T& v, const optional<T&>& x) {
774  return bool(x) ? v == *x : false;
775 }
776 
777 template <class T>
778 constexpr bool operator!=(const optional<T&>& x, const T& v) {
779  return bool(x) ? *x != v : true;
780 }
781 
782 template <class T>
783 constexpr bool operator!=(const T& v, const optional<T&>& x) {
784  return bool(x) ? v != *x : true;
785 }
786 
787 template <class T>
788 constexpr bool operator<(const optional<T&>& x, const T& v) {
789  return bool(x) ? *x < v : true;
790 }
791 
792 template <class T>
793 constexpr bool operator>(const T& v, const optional<T&>& x) {
794  return bool(x) ? v > *x : true;
795 }
796 
797 template <class T>
798 constexpr bool operator>(const optional<T&>& x, const T& v) {
799  return bool(x) ? *x > v : false;
800 }
801 
802 template <class T>
803 constexpr bool operator<(const T& v, const optional<T&>& x) {
804  return bool(x) ? v < *x : false;
805 }
806 
807 template <class T>
808 constexpr bool operator>=(const optional<T&>& x, const T& v) {
809  return bool(x) ? *x >= v : false;
810 }
811 
812 template <class T>
813 constexpr bool operator<=(const T& v, const optional<T&>& x) {
814  return bool(x) ? v <= *x : false;
815 }
816 
817 template <class T>
818 constexpr bool operator<=(const optional<T&>& x, const T& v) {
819  return bool(x) ? *x <= v : true;
820 }
821 
822 template <class T>
823 constexpr bool operator>=(const T& v, const optional<T&>& x) {
824  return bool(x) ? v >= *x : true;
825 }
826 
827 // Comparison of optional<T const&> with T
828 template <class T>
829 constexpr bool operator==(const optional<const T&>& x, const T& v) {
830  return bool(x) ? *x == v : false;
831 }
832 
833 template <class T>
834 constexpr bool operator==(const T& v, const optional<const T&>& x) {
835  return bool(x) ? v == *x : false;
836 }
837 
838 template <class T>
839 constexpr bool operator!=(const optional<const T&>& x, const T& v) {
840  return bool(x) ? *x != v : true;
841 }
842 
843 template <class T>
844 constexpr bool operator!=(const T& v, const optional<const T&>& x) {
845  return bool(x) ? v != *x : true;
846 }
847 
848 template <class T>
849 constexpr bool operator<(const optional<const T&>& x, const T& v) {
850  return bool(x) ? *x < v : true;
851 }
852 
853 template <class T>
854 constexpr bool operator>(const T& v, const optional<const T&>& x) {
855  return bool(x) ? v > *x : true;
856 }
857 
858 template <class T>
859 constexpr bool operator>(const optional<const T&>& x, const T& v) {
860  return bool(x) ? *x > v : false;
861 }
862 
863 template <class T>
864 constexpr bool operator<(const T& v, const optional<const T&>& x) {
865  return bool(x) ? v < *x : false;
866 }
867 
868 template <class T>
869 constexpr bool operator>=(const optional<const T&>& x, const T& v) {
870  return bool(x) ? *x >= v : false;
871 }
872 
873 template <class T>
874 constexpr bool operator<=(const T& v, const optional<const T&>& x) {
875  return bool(x) ? v <= *x : false;
876 }
877 
878 template <class T>
879 constexpr bool operator<=(const optional<const T&>& x, const T& v) {
880  return bool(x) ? *x <= v : true;
881 }
882 
883 template <class T>
884 constexpr bool operator>=(const T& v, const optional<const T&>& x) {
885  return bool(x) ? v >= *x : true;
886 }
887 
888 // 20.5.12, Specialized algorithms
889 template <class T>
890 void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y))) {
891  x.swap(y);
892 }
893 
894 template <class T>
896  return optional<typename std::decay<T>::type>(constexpr_forward<T>(v));
897 }
898 
899 template <class X>
900 constexpr optional<X&> make_optional(std::reference_wrapper<X> v) {
901  return optional<X&>(v.get());
902 }
903 
904 } // namespace utility
905 } // namespace cloudViewer
906 
907 namespace std {
908 template <typename T>
909 struct hash<cloudViewer::utility::optional<T>> {
910  typedef typename hash<T>::result_type result_type;
912 
913  constexpr result_type operator()(argument_type const& arg) const {
914  return arg ? std::hash<T>{}(*arg) : result_type{};
915  }
916 };
917 
918 template <typename T>
919 struct hash<cloudViewer::utility::optional<T&>> {
920  typedef typename hash<T>::result_type result_type;
922 
923  constexpr result_type operator()(argument_type const& arg) const {
924  return arg ? std::hash<T>{}(*arg) : result_type{};
925  }
926 };
927 } // namespace std
928 
929 #undef TR2_OPTIONAL_REQUIRES
930 #undef TR2_OPTIONAL_ASSERTED_EXPRESSION
931 #undef TR2_OPTIONAL_HOST_CONSTEXPR
char type
#define TR2_OPTIONAL_REQUIRES(...)
Definition: Optional.h:20
#define TR2_OPTIONAL_HOST_CONSTEXPR
Definition: Optional.h:80
#define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR)
Definition: Optional.h:73
bad_optional_access(const char *what_arg)
Definition: Optional.h:143
bad_optional_access(const std::string &what_arg)
Definition: Optional.h:141
constexpr optional() noexcept
Definition: Optional.h:523
constexpr optional(in_place_t, T &v) noexcept
Definition: Optional.h:535
constexpr optional(const optional &rhs) noexcept
Definition: Optional.h:533
constexpr optional(U &u) noexcept
Definition: Optional.h:528
void swap(optional< T & > &rhs) noexcept
Definition: Optional.h:577
constexpr std::decay< T >::type value_or(V &&v) const
Definition: Optional.h:598
constexpr bool has_value() const noexcept
Definition: Optional.h:595
optional(in_place_t, T &&)=delete
auto operator=(U &&rhs) noexcept -> typename std::enable_if<!std::is_same< typename std::decay< U >::type, optional< T & >>::value, optional & >::type=delete
constexpr T * operator->() const
Definition: Optional.h:580
constexpr optional(nullopt_t) noexcept
Definition: Optional.h:525
auto operator=(U &&rhs) noexcept -> typename std::enable_if< std::is_same< typename std::decay< U >::type, optional< T & >>::value, optional & >::type
Definition: Optional.h:559
optional & operator=(nullopt_t) noexcept
Definition: Optional.h:543
constexpr T & operator*() const
Definition: Optional.h:584
constexpr T & value() const
Definition: Optional.h:588
void emplace(Args &&... args)
Definition: Optional.h:410
constexpr optional(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:354
void emplace(std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:416
constexpr T value_or(V &&v) const &
Definition: Optional.h:485
auto operator=(U &&v) -> typename std::enable_if< std::is_constructible< T, U >::value &&!std::is_same< typename std::decay< U >::type, optional< T >>::value &&(std::is_scalar< T >::value||std::is_same< typename std::decay< U >::type, T >::value) &&std::is_assignable< T &, U >::value, optional & >::type
Definition: Optional.h:391
constexpr T && value() &&
Definition: Optional.h:479
optional & operator=(const optional &rhs)
Definition: Optional.h:368
constexpr T const & operator*() const &
Definition: Optional.h:451
constexpr bool has_value() const noexcept
Definition: Optional.h:440
optional & operator=(nullopt_t) noexcept
Definition: Optional.h:363
constexpr T const * operator->() const
Definition: Optional.h:442
constexpr T * operator->()
Definition: Optional.h:446
constexpr optional(nullopt_t) noexcept
Definition: Optional.h:303
constexpr T const & value() const &
Definition: Optional.h:465
constexpr optional() noexcept
Definition: Optional.h:302
constexpr optional(in_place_t, Args &&... args)
Definition: Optional.h:347
optional(const optional &rhs)
Definition: Optional.h:305
optional & operator=(optional &&rhs) noexcept(std::is_nothrow_move_assignable< T >::value &&std::is_nothrow_move_constructible< T >::value)
Definition: Optional.h:378
constexpr T value_or(V &&v) &&
Definition: Optional.h:490
constexpr T && operator*() &&
Definition: Optional.h:460
constexpr T & operator*() &
Definition: Optional.h:455
void swap(optional< T > &rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&noexcept(std::swap(std::declval< T & >(), std::declval< T & >())))
Definition: Optional.h:422
constexpr optional(U &&u)
Definition: Optional.h:334
constexpr T & value() &
Definition: Optional.h:472
optional(optional &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value)
Definition: Optional.h:312
constexpr T * static_addressof(T &ref)
Definition: Optional.h:109
constexpr U convert(U v)
Definition: Optional.h:122
constexpr std::remove_reference< T >::type && constexpr_move(T &&t) noexcept
Definition: Optional.h:65
constexpr struct cloudViewer::utility::trivial_init_t trivial_init
constexpr optional< typename std::decay< T >::type > make_optional(T &&v)
Definition: Optional.h:895
void swap(optional< T > &x, optional< T > &y) noexcept(noexcept(x.swap(y)))
Definition: Optional.h:890
constexpr bool operator<=(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:635
constexpr bool operator<(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:625
constexpr bool operator>=(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:640
constexpr in_place_t in_place
Definition: Optional.h:40
constexpr nullopt_t nullopt
Definition: Optional.h:136
constexpr T && constexpr_forward(typename std::remove_reference< T >::type &t) noexcept
Definition: Optional.h:52
constexpr bool operator!=(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:620
typename std::conditional< std::is_trivially_destructible< T >::value, constexpr_optional_base< typename std::remove_const< T >::type >, optional_base< typename std::remove_const< T >::type > >::type OptionalBase
Definition: Optional.h:241
constexpr bool operator>(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:630
constexpr bool operator==(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:615
Generic file read and write utility for python interface.
Definition: Eigen.h:85
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1370
constexpr constexpr_optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:228
constexpr constexpr_optional_base() noexcept
Definition: Optional.h:211
constexpr constexpr_optional_base(const T &v)
Definition: Optional.h:214
constexpr constexpr_optional_base(in_place_t, Args &&... args)
Definition: Optional.h:221
constexpr optional_base(const T &v)
Definition: Optional.h:183
optional_base(in_place_t, Args &&... args)
Definition: Optional.h:189
constexpr optional_base() noexcept
Definition: Optional.h:180
optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:196
constexpr result_type operator()(argument_type const &arg) const
Definition: Optional.h:913
cloudViewer::utility::optional< T > argument_type
Definition: Optional.h:911
cloudViewer::utility::optional< T & > argument_type
Definition: Optional.h:921
constexpr result_type operator()(argument_type const &arg) const
Definition: Optional.h:923
constexpr constexpr_storage_t(trivial_init_t) noexcept
Definition: Optional.h:166
constexpr constexpr_storage_t(Args &&... args)
Definition: Optional.h:169
constexpr storage_t(Args &&... args)
Definition: Optional.h:155
constexpr storage_t(trivial_init_t) noexcept
Definition: Optional.h:152