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