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