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