Open3D (C++ API)  0.16.0
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
68namespace open3d {
69namespace utility {
70
71struct in_place_t {
72 explicit in_place_t() = default;
73};
74
75constexpr in_place_t in_place{};
76
77// 20.5.4, optional for object types
78template <class T>
79class optional;
80
81// 20.5.5, optional for lvalue reference types
82template <class T>
83class optional<T&>;
84
85// workaround: std utility functions aren't constexpr yet
86template <class T>
87inline constexpr T&& constexpr_forward(
88 typename std::remove_reference<T>::type& t) noexcept {
89 return static_cast<T&&>(t);
90}
91
92template <class T>
93inline 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
99template <class T>
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
118namespace detail_ {
119
120// VS doesn't handle constexpr well, so we need to skip these stuff.
121#if (defined _MSC_VER)
122template <typename T>
123T* static_addressof(T& ref) {
124 return std::addressof(ref);
125}
126#else
127// static_addressof: a constexpr version of addressof
128template <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
143template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
144constexpr T* static_addressof(T& ref) {
145 return &ref;
146}
147
148template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
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
156template <class U>
157constexpr U convert(U v) {
158 return v;
159}
160
161} // namespace detail_
162
163constexpr struct trivial_init_t {
165
166// 20.5.7, Disengaged state indicator
167struct nullopt_t {
168 struct init {};
169 constexpr explicit nullopt_t(init) {}
170};
172
173// 20.5.8, class bad_optional_access
174class bad_optional_access : public std::logic_error {
175public:
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
182template <class 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
196template <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
208};
209
210template <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
240template <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
268};
269
270template <class T>
271using 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
277template <class T>
278class 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
287 "bad T");
288 static_assert(
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 {
299 return detail_::static_addressof(OptionalBase<T>::storage_.value_);
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
332public:
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,
365 !std::is_same<typename std::decay<U>::type,
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,
375 !std::is_same<typename std::decay<U>::type,
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
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 &&
429 (std::is_scalar<T>::value ||
431 std::is_assignable<T&, U>::value,
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
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.
540template <class T>
541class 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
553public:
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<
594 ref = rhs.ref;
595 return *this;
596 }
597
598 template <typename U>
599 auto operator=(U&& rhs) noexcept -> typename std::enable_if<
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
638template <class T>
639class optional<T&&> {
640 static_assert(sizeof(T) == 0, "optional rvalue references disallowed");
641};
642
643// 20.5.8, Relational operators
644template <class T>
645constexpr 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
649template <class T>
650constexpr bool operator!=(const optional<T>& x, const optional<T>& y) {
651 return !(x == y);
652}
653
654template <class T>
655constexpr bool operator<(const optional<T>& x, const optional<T>& y) {
656 return (!y) ? false : (!x) ? true : *x < *y;
657}
658
659template <class T>
660constexpr bool operator>(const optional<T>& x, const optional<T>& y) {
661 return (y < x);
662}
663
664template <class T>
665constexpr bool operator<=(const optional<T>& x, const optional<T>& y) {
666 return !(y < x);
667}
668
669template <class T>
670constexpr bool operator>=(const optional<T>& x, const optional<T>& y) {
671 return !(x < y);
672}
673
674// 20.5.9, Comparison with nullopt
675template <class T>
676constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept {
677 return (!x);
678}
679
680template <class T>
681constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept {
682 return (!x);
683}
684
685template <class T>
686constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept {
687 return bool(x);
688}
689
690template <class T>
691constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept {
692 return bool(x);
693}
694
695template <class T>
696constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
697 return false;
698}
699
700template <class T>
701constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept {
702 return bool(x);
703}
704
705template <class T>
706constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept {
707 return (!x);
708}
709
710template <class T>
711constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
712 return true;
713}
714
715template <class T>
716constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept {
717 return bool(x);
718}
719
720template <class T>
721constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
722 return false;
723}
724
725template <class T>
726constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
727 return true;
728}
729
730template <class T>
731constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept {
732 return (!x);
733}
734
735// 20.5.10, Comparison with T
736template <class T>
737constexpr bool operator==(const optional<T>& x, const T& v) {
738 return bool(x) ? *x == v : false;
739}
740
741template <class T>
742constexpr bool operator==(const T& v, const optional<T>& x) {
743 return bool(x) ? v == *x : false;
744}
745
746template <class T>
747constexpr bool operator!=(const optional<T>& x, const T& v) {
748 return bool(x) ? *x != v : true;
749}
750
751template <class T>
752constexpr bool operator!=(const T& v, const optional<T>& x) {
753 return bool(x) ? v != *x : true;
754}
755
756template <class T>
757constexpr bool operator<(const optional<T>& x, const T& v) {
758 return bool(x) ? *x < v : true;
759}
760
761template <class T>
762constexpr bool operator>(const T& v, const optional<T>& x) {
763 return bool(x) ? v > *x : true;
764}
765
766template <class T>
767constexpr bool operator>(const optional<T>& x, const T& v) {
768 return bool(x) ? *x > v : false;
769}
770
771template <class T>
772constexpr bool operator<(const T& v, const optional<T>& x) {
773 return bool(x) ? v < *x : false;
774}
775
776template <class T>
777constexpr bool operator>=(const optional<T>& x, const T& v) {
778 return bool(x) ? *x >= v : false;
779}
780
781template <class T>
782constexpr bool operator<=(const T& v, const optional<T>& x) {
783 return bool(x) ? v <= *x : false;
784}
785
786template <class T>
787constexpr bool operator<=(const optional<T>& x, const T& v) {
788 return bool(x) ? *x <= v : true;
789}
790
791template <class T>
792constexpr 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
797template <class T>
798constexpr bool operator==(const optional<T&>& x, const T& v) {
799 return bool(x) ? *x == v : false;
800}
801
802template <class T>
803constexpr bool operator==(const T& v, const optional<T&>& x) {
804 return bool(x) ? v == *x : false;
805}
806
807template <class T>
808constexpr bool operator!=(const optional<T&>& x, const T& v) {
809 return bool(x) ? *x != v : true;
810}
811
812template <class T>
813constexpr bool operator!=(const T& v, const optional<T&>& x) {
814 return bool(x) ? v != *x : true;
815}
816
817template <class T>
818constexpr bool operator<(const optional<T&>& x, const T& v) {
819 return bool(x) ? *x < v : true;
820}
821
822template <class T>
823constexpr bool operator>(const T& v, const optional<T&>& x) {
824 return bool(x) ? v > *x : true;
825}
826
827template <class T>
828constexpr bool operator>(const optional<T&>& x, const T& v) {
829 return bool(x) ? *x > v : false;
830}
831
832template <class T>
833constexpr bool operator<(const T& v, const optional<T&>& x) {
834 return bool(x) ? v < *x : false;
835}
836
837template <class T>
838constexpr bool operator>=(const optional<T&>& x, const T& v) {
839 return bool(x) ? *x >= v : false;
840}
841
842template <class T>
843constexpr bool operator<=(const T& v, const optional<T&>& x) {
844 return bool(x) ? v <= *x : false;
845}
846
847template <class T>
848constexpr bool operator<=(const optional<T&>& x, const T& v) {
849 return bool(x) ? *x <= v : true;
850}
851
852template <class T>
853constexpr 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
858template <class T>
859constexpr bool operator==(const optional<const T&>& x, const T& v) {
860 return bool(x) ? *x == v : false;
861}
862
863template <class T>
864constexpr bool operator==(const T& v, const optional<const T&>& x) {
865 return bool(x) ? v == *x : false;
866}
867
868template <class T>
869constexpr bool operator!=(const optional<const T&>& x, const T& v) {
870 return bool(x) ? *x != v : true;
871}
872
873template <class T>
874constexpr bool operator!=(const T& v, const optional<const T&>& x) {
875 return bool(x) ? v != *x : true;
876}
877
878template <class T>
879constexpr bool operator<(const optional<const T&>& x, const T& v) {
880 return bool(x) ? *x < v : true;
881}
882
883template <class T>
884constexpr bool operator>(const T& v, const optional<const T&>& x) {
885 return bool(x) ? v > *x : true;
886}
887
888template <class T>
889constexpr bool operator>(const optional<const T&>& x, const T& v) {
890 return bool(x) ? *x > v : false;
891}
892
893template <class T>
894constexpr bool operator<(const T& v, const optional<const T&>& x) {
895 return bool(x) ? v < *x : false;
896}
897
898template <class T>
899constexpr bool operator>=(const optional<const T&>& x, const T& v) {
900 return bool(x) ? *x >= v : false;
901}
902
903template <class T>
904constexpr bool operator<=(const T& v, const optional<const T&>& x) {
905 return bool(x) ? v <= *x : false;
906}
907
908template <class T>
909constexpr bool operator<=(const optional<const T&>& x, const T& v) {
910 return bool(x) ? *x <= v : true;
911}
912
913template <class T>
914constexpr 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
919template <class T>
920void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y))) {
921 x.swap(y);
922}
923
924template <class T>
926 return optional<typename std::decay<T>::type>(constexpr_forward<T>(v));
927}
928
929template <class X>
930constexpr optional<X&> make_optional(std::reference_wrapper<X> v) {
931 return optional<X&>(v.get());
932}
933
934} // namespace utility
935} // namespace open3d
936
937namespace std {
938template <typename T>
939struct 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
948template <typename T>
949struct 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
#define TR2_OPTIONAL_REQUIRES(...)
Definition: Optional.h:65
#define TR2_OPTIONAL_HOST_CONSTEXPR
Definition: Optional.h:115
#define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR)
Definition: Optional.h:108
Definition: Optional.h:174
bad_optional_access(const char *what_arg)
Definition: Optional.h:178
bad_optional_access(const std::string &what_arg)
Definition: Optional.h:176
Definition: Optional.h:541
auto operator=(U &&rhs) noexcept -> typename std::enable_if< !std::is_same< typename std::decay< U >::type, optional< T & > >::value, optional & >::type=delete
constexpr optional(U &u) noexcept
Definition: Optional.h:560
constexpr optional() noexcept
Definition: Optional.h:555
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
optional & operator=(nullopt_t) noexcept
Definition: Optional.h:575
void reset() noexcept
Definition: Optional.h:635
constexpr optional(nullopt_t) noexcept
Definition: Optional.h:557
void emplace(T &v) noexcept
Definition: Optional.h:603
constexpr T & value() const
Definition: Optional.h:618
optional(in_place_t, T &&)=delete
TR2_OPTIONAL_HOST_CONSTEXPR T & operator*() const
Definition: Optional.h:614
void swap(optional< T & > &rhs) noexcept
Definition: Optional.h:607
constexpr optional(in_place_t, T &v) noexcept
Definition: Optional.h:567
TR2_OPTIONAL_HOST_CONSTEXPR T * operator->() const
Definition: Optional.h:610
constexpr bool has_value() const noexcept
Definition: Optional.h:625
constexpr std::decay< T >::type value_or(V &&v) const
Definition: Optional.h:628
constexpr optional(const optional &rhs) noexcept
Definition: Optional.h:565
Definition: Optional.h:278
TR2_OPTIONAL_HOST_CONSTEXPR T & operator*() &
Definition: Optional.h:487
constexpr bool has_value() const noexcept
Definition: Optional.h:472
optional(const optional &rhs)
Definition: Optional.h:339
T value_type
Definition: Optional.h:333
constexpr T value_or(V &&v) const &
Definition: Optional.h:517
constexpr optional() noexcept
Definition: Optional.h:336
void emplace(std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:448
constexpr optional(U &&u)
Definition: Optional.h:368
constexpr T value_or(V &&v) &&
Definition: Optional.h:522
void emplace(Args &&... args)
Definition: Optional.h:442
optional & operator=(const optional &rhs)
Definition: Optional.h:402
TR2_OPTIONAL_HOST_CONSTEXPR T && value() &&
Definition: Optional.h:511
void reset() noexcept
Definition: Optional.h:529
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
TR2_OPTIONAL_HOST_CONSTEXPR T const & operator*() const &
Definition: Optional.h:483
constexpr optional(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:388
optional(optional &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value)
Definition: Optional.h:346
constexpr optional(in_place_t, Args &&... args)
Definition: Optional.h:381
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
TR2_OPTIONAL_HOST_CONSTEXPR T && operator*() &&
Definition: Optional.h:492
optional & operator=(optional &&rhs) noexcept(std::is_nothrow_move_assignable< T >::value &&std::is_nothrow_move_constructible< T >::value)
Definition: Optional.h:412
TR2_OPTIONAL_HOST_CONSTEXPR T & value() &
Definition: Optional.h:504
TR2_OPTIONAL_HOST_CONSTEXPR T const * operator->() const
Definition: Optional.h:474
optional & operator=(nullopt_t) noexcept
Definition: Optional.h:397
constexpr optional(nullopt_t) noexcept
Definition: Optional.h:337
TR2_OPTIONAL_HOST_CONSTEXPR T * operator->()
Definition: Optional.h:478
TR2_OPTIONAL_HOST_CONSTEXPR T const & value() const &
Definition: Optional.h:497
char type
Definition: FilePCD.cpp:60
constexpr U convert(U v)
Definition: Optional.h:157
constexpr T * static_addressof(T &ref)
Definition: Optional.h:144
constexpr std::remove_reference< T >::type && constexpr_move(T &&t) noexcept
Definition: Optional.h:100
constexpr in_place_t in_place
Definition: Optional.h:75
constexpr struct open3d::utility::trivial_init_t trivial_init
constexpr bool operator<(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:655
constexpr T && constexpr_forward(typename std::remove_reference< T >::type &t) noexcept
Definition: Optional.h:87
constexpr optional< typename std::decay< T >::type > make_optional(T &&v)
Definition: Optional.h:925
constexpr bool operator>=(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:670
constexpr bool operator==(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:645
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
void swap(optional< T > &x, optional< T > &y) noexcept(noexcept(x.swap(y)))
Definition: Optional.h:920
constexpr bool operator<=(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:665
constexpr bool operator>(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:660
constexpr nullopt_t nullopt
Definition: Optional.h:171
constexpr bool operator!=(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:650
Definition: PinholeCameraIntrinsic.cpp:35
Definition: Device.h:126
void swap(open3d::core::SmallVectorImpl< T > &LHS, open3d::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1389
constexpr constexpr_optional_base() noexcept
Definition: Optional.h:245
constexpr_storage_t< T > storage_
Definition: Optional.h:243
constexpr constexpr_optional_base(in_place_t, Args &&... args)
Definition: Optional.h:255
constexpr constexpr_optional_base(T &&v)
Definition: Optional.h:251
bool init_
Definition: Optional.h:242
constexpr constexpr_optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:262
constexpr constexpr_optional_base(const T &v)
Definition: Optional.h:248
static constexpr bool value
Definition: Optional.h:140
static constexpr bool has_overload(bool)
Definition: Optional.h:136
static constexpr bool has_overload(...)
Definition: Optional.h:131
Definition: Optional.h:71
Definition: Optional.h:168
Definition: Optional.h:167
constexpr nullopt_t(init)
Definition: Optional.h:169
Definition: Optional.h:211
~optional_base()
Definition: Optional.h:235
bool init_
Definition: Optional.h:212
optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: Optional.h:230
storage_t< T > storage_
Definition: Optional.h:213
optional_base(in_place_t, Args &&... args)
Definition: Optional.h:223
constexpr optional_base(const T &v)
Definition: Optional.h:217
constexpr optional_base() noexcept
Definition: Optional.h:215
constexpr optional_base(T &&v)
Definition: Optional.h:219
Definition: Optional.h:163
open3d::utility::optional< T > argument_type
Definition: Optional.h:941
constexpr result_type operator()(argument_type const &arg) const
Definition: Optional.h:943
hash< T >::result_type result_type
Definition: Optional.h:940
open3d::utility::optional< T & > argument_type
Definition: Optional.h:951
constexpr result_type operator()(argument_type const &arg) const
Definition: Optional.h:953
hash< T >::result_type result_type
Definition: Optional.h:950
Definition: Optional.h:197
T value_
Definition: Optional.h:199
constexpr constexpr_storage_t(trivial_init_t) noexcept
Definition: Optional.h:201
unsigned char dummy_
Definition: Optional.h:198
constexpr constexpr_storage_t(Args &&... args)
Definition: Optional.h:204
Definition: Optional.h:183
constexpr storage_t(Args &&... args)
Definition: Optional.h:190
unsigned char dummy_
Definition: Optional.h:184
constexpr storage_t(trivial_init_t) noexcept
Definition: Optional.h:187
~storage_t()
Definition: Optional.h:193
T value_
Definition: Optional.h:185