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