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