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