libstdc++
optional
Go to the documentation of this file.
1 // <optional> -*- C++ -*-
2 
3 // Copyright (C) 2013-2019 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file experimental/optional
26  * This is a TS C++ Library header.
27  */
28 
29 #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL
30 #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1
31 
32 /**
33  * @defgroup experimental Experimental
34  *
35  * Components specified by various Technical Specifications.
36  *
37  * As indicated by the std::experimental namespace and the header paths,
38  * the contents of these Technical Specifications are experimental and not
39  * part of the C++ standard. As such the interfaces and implementations may
40  * change in the future, and there is <STRONG> no guarantee of compatibility
41  * between different GCC releases </STRONG> for these features.
42  */
43 
44 #if __cplusplus >= 201402L
45 
46 #include <utility>
47 #include <type_traits>
48 #include <stdexcept>
49 #include <new>
50 #include <initializer_list>
51 #include <bits/functexcept.h>
52 #include <bits/functional_hash.h>
53 #include <bits/enable_special_members.h>
54 #include <experimental/bits/lfts_config.h>
55 
56 namespace std _GLIBCXX_VISIBILITY(default)
57 {
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
59 
60 namespace experimental
61 {
62 inline namespace fundamentals_v1
63 {
64  /**
65  * @defgroup optional Optional values
66  * @ingroup experimental
67  *
68  * Class template for optional values and surrounding facilities, as
69  * described in n3793 "A proposal to add a utility class to represent
70  * optional objects (Revision 5)".
71  *
72  * @{
73  */
74 
75 #define __cpp_lib_experimental_optional 201411
76 
77  // All subsequent [X.Y.n] references are against n3793.
78 
79  // [X.Y.4]
80  template<typename _Tp>
81  class optional;
82 
83  // [X.Y.5]
84  /// Tag type for in-place construction.
85  struct in_place_t { };
86 
87  /// Tag for in-place construction.
88  constexpr in_place_t in_place { };
89 
90  // [X.Y.6]
91  /// Tag type to disengage optional objects.
92  struct nullopt_t
93  {
94  // Do not user-declare default constructor at all for
95  // optional_value = {} syntax to work.
96  // nullopt_t() = delete;
97 
98  // Used for constructing nullopt.
99  enum class _Construct { _Token };
100 
101  // Must be constexpr for nullopt_t to be literal.
102  explicit constexpr nullopt_t(_Construct) { }
103  };
104 
105  // [X.Y.6]
106  /// Tag to disengage optional objects.
107  constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
108 
109  // [X.Y.7]
110  /**
111  * @brief Exception class thrown when a disengaged optional object is
112  * dereferenced.
113  * @ingroup exceptions
114  */
115  class bad_optional_access : public logic_error
116  {
117  public:
118  bad_optional_access() : logic_error("bad optional access") { }
119 
120  // XXX This constructor is non-standard. Should not be inline
121  explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }
122 
123  virtual ~bad_optional_access() noexcept = default;
124  };
125 
126  void
127  __throw_bad_optional_access(const char*)
128  __attribute__((__noreturn__));
129 
130  // XXX Does not belong here.
131  inline void
132  __throw_bad_optional_access(const char* __s)
133  { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }
134 
135 #ifndef __cpp_lib_addressof_constexpr
136  template<typename _Tp, typename = void>
137  struct _Has_addressof_mem : std::false_type { };
138 
139  template<typename _Tp>
140  struct _Has_addressof_mem<_Tp,
141  __void_t<decltype( std::declval<const _Tp&>().operator&() )>
142  >
143  : std::true_type { };
144 
145  template<typename _Tp, typename = void>
146  struct _Has_addressof_free : std::false_type { };
147 
148  template<typename _Tp>
149  struct _Has_addressof_free<_Tp,
150  __void_t<decltype( operator&(std::declval<const _Tp&>()) )>
151  >
152  : std::true_type { };
153 
154  /**
155  * @brief Trait that detects the presence of an overloaded unary operator&.
156  *
157  * Practically speaking this detects the presence of such an operator when
158  * called on a const-qualified lvalue (e.g.
159  * declval<const _Tp&>().operator&()).
160  */
161  template<typename _Tp>
162  struct _Has_addressof
163  : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type
164  { };
165 
166  /**
167  * @brief An overload that attempts to take the address of an lvalue as a
168  * constant expression. Falls back to __addressof in the presence of an
169  * overloaded addressof operator (unary operator&), in which case the call
170  * will not be a constant expression.
171  */
172  template<typename _Tp>
173  constexpr
174  enable_if_t<!_Has_addressof<_Tp>::value, _Tp*>
175  __constexpr_addressof(_Tp& __t)
176  { return &__t; }
177 
178  /**
179  * @brief Fallback overload that defers to __addressof.
180  */
181  template<typename _Tp>
182  inline
183  enable_if_t<_Has_addressof<_Tp>::value, _Tp*>
184  __constexpr_addressof(_Tp& __t)
185  { return std::__addressof(__t); }
186 #endif // __cpp_lib_addressof_constexpr
187 
188  /**
189  * @brief Class template that holds the necessary state for @ref optional
190  * and that has the responsibility for construction and the special members.
191  *
192  * Such a separate base class template is necessary in order to
193  * conditionally enable the special members (e.g. copy/move constructors).
194  * Note that this means that @ref _Optional_base implements the
195  * functionality for copy and move assignment, but not for converting
196  * assignment.
197  *
198  * @see optional, _Enable_special_members
199  */
200  template<typename _Tp, bool _ShouldProvideDestructor =
201  !is_trivially_destructible<_Tp>::value>
202  class _Optional_base
203  {
204  private:
205  // Remove const to avoid prohibition of reusing object storage for
206  // const-qualified types in [3.8/9]. This is strictly internal
207  // and even optional itself is oblivious to it.
208  using _Stored_type = remove_const_t<_Tp>;
209 
210  public:
211  // [X.Y.4.1] Constructors.
212 
213  // Constructors for disengaged optionals.
214  constexpr _Optional_base() noexcept
215  : _M_empty{} { }
216 
217  constexpr _Optional_base(nullopt_t) noexcept
218  : _Optional_base{} { }
219 
220  // Constructors for engaged optionals.
221  template<typename... _Args>
222  constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
223  : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
224 
225  template<typename _Up, typename... _Args,
226  enable_if_t<is_constructible<_Tp,
227  initializer_list<_Up>&,
228  _Args&&...>::value,
229  int>...>
230  constexpr explicit _Optional_base(in_place_t,
231  initializer_list<_Up> __il,
232  _Args&&... __args)
233  : _M_payload(__il, std::forward<_Args>(__args)...),
234  _M_engaged(true) { }
235 
236  // Copy and move constructors.
237  _Optional_base(const _Optional_base& __other)
238  {
239  if (__other._M_engaged)
240  this->_M_construct(__other._M_get());
241  }
242 
243  _Optional_base(_Optional_base&& __other)
244  noexcept(is_nothrow_move_constructible<_Tp>())
245  {
246  if (__other._M_engaged)
247  this->_M_construct(std::move(__other._M_get()));
248  }
249 
250  // [X.Y.4.3] (partly) Assignment.
251  _Optional_base&
252  operator=(const _Optional_base& __other)
253  {
254  if (this->_M_engaged && __other._M_engaged)
255  this->_M_get() = __other._M_get();
256  else
257  {
258  if (__other._M_engaged)
259  this->_M_construct(__other._M_get());
260  else
261  this->_M_reset();
262  }
263 
264  return *this;
265  }
266 
267  _Optional_base&
268  operator=(_Optional_base&& __other)
269  noexcept(__and_<is_nothrow_move_constructible<_Tp>,
270  is_nothrow_move_assignable<_Tp>>())
271  {
272  if (this->_M_engaged && __other._M_engaged)
273  this->_M_get() = std::move(__other._M_get());
274  else
275  {
276  if (__other._M_engaged)
277  this->_M_construct(std::move(__other._M_get()));
278  else
279  this->_M_reset();
280  }
281  return *this;
282  }
283 
284  // [X.Y.4.2] Destructor.
285  ~_Optional_base()
286  {
287  if (this->_M_engaged)
288  this->_M_payload.~_Stored_type();
289  }
290 
291  // The following functionality is also needed by optional, hence the
292  // protected accessibility.
293  protected:
294  constexpr bool _M_is_engaged() const noexcept
295  { return this->_M_engaged; }
296 
297  // The _M_get operations have _M_engaged as a precondition.
298  constexpr _Tp&
299  _M_get() noexcept
300  { return _M_payload; }
301 
302  constexpr const _Tp&
303  _M_get() const noexcept
304  { return _M_payload; }
305 
306  // The _M_construct operation has !_M_engaged as a precondition
307  // while _M_destruct has _M_engaged as a precondition.
308  template<typename... _Args>
309  void
310  _M_construct(_Args&&... __args)
311  noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
312  {
313  ::new (std::__addressof(this->_M_payload))
314  _Stored_type(std::forward<_Args>(__args)...);
315  this->_M_engaged = true;
316  }
317 
318  void
319  _M_destruct()
320  {
321  this->_M_engaged = false;
322  this->_M_payload.~_Stored_type();
323  }
324 
325  // _M_reset is a 'safe' operation with no precondition.
326  void
327  _M_reset()
328  {
329  if (this->_M_engaged)
330  this->_M_destruct();
331  }
332 
333  private:
334  struct _Empty_byte { };
335  union {
336  _Empty_byte _M_empty;
337  _Stored_type _M_payload;
338  };
339  bool _M_engaged = false;
340  };
341 
342  /// Partial specialization that is exactly identical to the primary template
343  /// save for not providing a destructor, to fulfill triviality requirements.
344  template<typename _Tp>
345  class _Optional_base<_Tp, false>
346  {
347  private:
348  using _Stored_type = remove_const_t<_Tp>;
349 
350  public:
351  constexpr _Optional_base() noexcept
352  : _M_empty{} { }
353 
354  constexpr _Optional_base(nullopt_t) noexcept
355  : _Optional_base{} { }
356 
357  template<typename... _Args>
358  constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
359  : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
360 
361  template<typename _Up, typename... _Args,
362  enable_if_t<is_constructible<_Tp,
363  initializer_list<_Up>&,
364  _Args&&...>::value,
365  int>...>
366  constexpr explicit _Optional_base(in_place_t,
367  initializer_list<_Up> __il,
368  _Args&&... __args)
369  : _M_payload(__il, std::forward<_Args>(__args)...),
370  _M_engaged(true) { }
371 
372  _Optional_base(const _Optional_base& __other)
373  {
374  if (__other._M_engaged)
375  this->_M_construct(__other._M_get());
376  }
377 
378  _Optional_base(_Optional_base&& __other)
379  noexcept(is_nothrow_move_constructible<_Tp>())
380  {
381  if (__other._M_engaged)
382  this->_M_construct(std::move(__other._M_get()));
383  }
384 
385  _Optional_base&
386  operator=(const _Optional_base& __other)
387  {
388  if (this->_M_engaged && __other._M_engaged)
389  this->_M_get() = __other._M_get();
390  else
391  {
392  if (__other._M_engaged)
393  this->_M_construct(__other._M_get());
394  else
395  this->_M_reset();
396  }
397  return *this;
398  }
399 
400  _Optional_base&
401  operator=(_Optional_base&& __other)
402  noexcept(__and_<is_nothrow_move_constructible<_Tp>,
403  is_nothrow_move_assignable<_Tp>>())
404  {
405  if (this->_M_engaged && __other._M_engaged)
406  this->_M_get() = std::move(__other._M_get());
407  else
408  {
409  if (__other._M_engaged)
410  this->_M_construct(std::move(__other._M_get()));
411  else
412  this->_M_reset();
413  }
414  return *this;
415  }
416 
417  // Sole difference
418  // ~_Optional_base() noexcept = default;
419 
420  protected:
421  constexpr bool _M_is_engaged() const noexcept
422  { return this->_M_engaged; }
423 
424  _Tp&
425  _M_get() noexcept
426  { return _M_payload; }
427 
428  constexpr const _Tp&
429  _M_get() const noexcept
430  { return _M_payload; }
431 
432  template<typename... _Args>
433  void
434  _M_construct(_Args&&... __args)
435  noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
436  {
437  ::new (std::__addressof(this->_M_payload))
438  _Stored_type(std::forward<_Args>(__args)...);
439  this->_M_engaged = true;
440  }
441 
442  void
443  _M_destruct()
444  {
445  this->_M_engaged = false;
446  this->_M_payload.~_Stored_type();
447  }
448 
449  void
450  _M_reset()
451  {
452  if (this->_M_engaged)
453  this->_M_destruct();
454  }
455 
456  private:
457  struct _Empty_byte { };
458  union
459  {
460  _Empty_byte _M_empty;
461  _Stored_type _M_payload;
462  };
463  bool _M_engaged = false;
464  };
465 
466  template<typename _Tp>
467  class optional;
468 
469  template<typename _Tp, typename _Up>
470  using __converts_from_optional =
471  __or_<is_constructible<_Tp, const optional<_Up>&>,
472  is_constructible<_Tp, optional<_Up>&>,
473  is_constructible<_Tp, const optional<_Up>&&>,
474  is_constructible<_Tp, optional<_Up>&&>,
475  is_convertible<const optional<_Up>&, _Tp>,
476  is_convertible<optional<_Up>&, _Tp>,
477  is_convertible<const optional<_Up>&&, _Tp>,
478  is_convertible<optional<_Up>&&, _Tp>>;
479 
480  template<typename _Tp, typename _Up>
481  using __assigns_from_optional =
482  __or_<is_assignable<_Tp&, const optional<_Up>&>,
483  is_assignable<_Tp&, optional<_Up>&>,
484  is_assignable<_Tp&, const optional<_Up>&&>,
485  is_assignable<_Tp&, optional<_Up>&&>>;
486 
487  /**
488  * @brief Class template for optional values.
489  */
490  template<typename _Tp>
491  class optional
492  : private _Optional_base<_Tp>,
493  private _Enable_copy_move<
494  // Copy constructor.
495  is_copy_constructible<_Tp>::value,
496  // Copy assignment.
497  __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
498  // Move constructor.
499  is_move_constructible<_Tp>::value,
500  // Move assignment.
501  __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
502  // Unique tag type.
503  optional<_Tp>>
504  {
505  static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>,
506  __not_<is_same<remove_cv_t<_Tp>, in_place_t>>,
507  __not_<is_reference<_Tp>>>(),
508  "Invalid instantiation of optional<T>");
509 
510  private:
511  using _Base = _Optional_base<_Tp>;
512 
513  public:
514  using value_type = _Tp;
515 
516  // _Optional_base has the responsibility for construction.
517  using _Base::_Base;
518 
519  constexpr optional() = default;
520  // Converting constructors for engaged optionals.
521  template <typename _Up = _Tp,
522  enable_if_t<__and_<
523  __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
524  is_constructible<_Tp, _Up&&>,
525  is_convertible<_Up&&, _Tp>
526  >::value, bool> = true>
527  constexpr optional(_Up&& __t)
528  : _Base(in_place, std::forward<_Up>(__t)) { }
529 
530  template <typename _Up = _Tp,
531  enable_if_t<__and_<
532  __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
533  is_constructible<_Tp, _Up&&>,
534  __not_<is_convertible<_Up&&, _Tp>>
535  >::value, bool> = false>
536  explicit constexpr optional(_Up&& __t)
537  : _Base(in_place, std::forward<_Up>(__t)) { }
538 
539  template <typename _Up,
540  enable_if_t<__and_<
541  __not_<is_same<_Tp, _Up>>,
542  is_constructible<_Tp, const _Up&>,
543  is_convertible<const _Up&, _Tp>,
544  __not_<__converts_from_optional<_Tp, _Up>>
545  >::value, bool> = true>
546  constexpr optional(const optional<_Up>& __t)
547  {
548  if (__t)
549  emplace(*__t);
550  }
551 
552  template <typename _Up,
553  enable_if_t<__and_<
554  __not_<is_same<_Tp, _Up>>,
555  is_constructible<_Tp, const _Up&>,
556  __not_<is_convertible<const _Up&, _Tp>>,
557  __not_<__converts_from_optional<_Tp, _Up>>
558  >::value, bool> = false>
559  explicit constexpr optional(const optional<_Up>& __t)
560  {
561  if (__t)
562  emplace(*__t);
563  }
564 
565  template <typename _Up,
566  enable_if_t<__and_<
567  __not_<is_same<_Tp, _Up>>,
568  is_constructible<_Tp, _Up&&>,
569  is_convertible<_Up&&, _Tp>,
570  __not_<__converts_from_optional<_Tp, _Up>>
571  >::value, bool> = true>
572  constexpr optional(optional<_Up>&& __t)
573  {
574  if (__t)
575  emplace(std::move(*__t));
576  }
577 
578  template <typename _Up,
579  enable_if_t<__and_<
580  __not_<is_same<_Tp, _Up>>,
581  is_constructible<_Tp, _Up&&>,
582  __not_<is_convertible<_Up&&, _Tp>>,
583  __not_<__converts_from_optional<_Tp, _Up>>
584  >::value, bool> = false>
585  explicit constexpr optional(optional<_Up>&& __t)
586  {
587  if (__t)
588  emplace(std::move(*__t));
589  }
590 
591  // [X.Y.4.3] (partly) Assignment.
592  optional&
593  operator=(nullopt_t) noexcept
594  {
595  this->_M_reset();
596  return *this;
597  }
598 
599  template<typename _Up = _Tp>
600  enable_if_t<__and_<
601  __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
602  is_constructible<_Tp, _Up>,
603  __not_<__and_<is_scalar<_Tp>,
604  is_same<_Tp, decay_t<_Up>>>>,
605  is_assignable<_Tp&, _Up>>::value,
606  optional&>
607  operator=(_Up&& __u)
608  {
609  if (this->_M_is_engaged())
610  this->_M_get() = std::forward<_Up>(__u);
611  else
612  this->_M_construct(std::forward<_Up>(__u));
613 
614  return *this;
615  }
616 
617  template<typename _Up>
618  enable_if_t<__and_<
619  __not_<is_same<_Tp, _Up>>,
620  is_constructible<_Tp, const _Up&>,
621  is_assignable<_Tp&, _Up>,
622  __not_<__converts_from_optional<_Tp, _Up>>,
623  __not_<__assigns_from_optional<_Tp, _Up>>
624  >::value,
625  optional&>
626  operator=(const optional<_Up>& __u)
627  {
628  if (__u)
629  {
630  if (this->_M_is_engaged())
631  this->_M_get() = *__u;
632  else
633  this->_M_construct(*__u);
634  }
635  else
636  {
637  this->_M_reset();
638  }
639  return *this;
640  }
641 
642  template<typename _Up>
643  enable_if_t<__and_<
644  __not_<is_same<_Tp, _Up>>,
645  is_constructible<_Tp, _Up>,
646  is_assignable<_Tp&, _Up>,
647  __not_<__converts_from_optional<_Tp, _Up>>,
648  __not_<__assigns_from_optional<_Tp, _Up>>
649  >::value,
650  optional&>
651  operator=(optional<_Up>&& __u)
652  {
653  if (__u)
654  {
655  if (this->_M_is_engaged())
656  this->_M_get() = std::move(*__u);
657  else
658  this->_M_construct(std::move(*__u));
659  }
660  else
661  {
662  this->_M_reset();
663  }
664 
665  return *this;
666  }
667 
668  template<typename... _Args>
669  enable_if_t<is_constructible<_Tp, _Args&&...>::value>
670  emplace(_Args&&... __args)
671  {
672  this->_M_reset();
673  this->_M_construct(std::forward<_Args>(__args)...);
674  }
675 
676  template<typename _Up, typename... _Args>
677  enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
678  _Args&&...>::value>
679  emplace(initializer_list<_Up> __il, _Args&&... __args)
680  {
681  this->_M_reset();
682  this->_M_construct(__il, std::forward<_Args>(__args)...);
683  }
684 
685  // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base.
686 
687  // [X.Y.4.4] Swap.
688  void
689  swap(optional& __other)
690  noexcept(is_nothrow_move_constructible<_Tp>()
691  && __is_nothrow_swappable<_Tp>::value)
692  {
693  using std::swap;
694 
695  if (this->_M_is_engaged() && __other._M_is_engaged())
696  swap(this->_M_get(), __other._M_get());
697  else if (this->_M_is_engaged())
698  {
699  __other._M_construct(std::move(this->_M_get()));
700  this->_M_destruct();
701  }
702  else if (__other._M_is_engaged())
703  {
704  this->_M_construct(std::move(__other._M_get()));
705  __other._M_destruct();
706  }
707  }
708 
709  // [X.Y.4.5] Observers.
710  constexpr const _Tp*
711  operator->() const
712  {
713 #ifndef __cpp_lib_addressof_constexpr
714  return __constexpr_addressof(this->_M_get());
715 #else
716  return std::__addressof(this->_M_get());
717 #endif
718  }
719 
720  _Tp*
721  operator->()
722  { return std::__addressof(this->_M_get()); }
723 
724  constexpr const _Tp&
725  operator*() const&
726  { return this->_M_get(); }
727 
728  constexpr _Tp&
729  operator*()&
730  { return this->_M_get(); }
731 
732  constexpr _Tp&&
733  operator*()&&
734  { return std::move(this->_M_get()); }
735 
736  constexpr const _Tp&&
737  operator*() const&&
738  { return std::move(this->_M_get()); }
739 
740  constexpr explicit operator bool() const noexcept
741  { return this->_M_is_engaged(); }
742 
743  constexpr const _Tp&
744  value() const&
745  {
746  return this->_M_is_engaged()
747  ? this->_M_get()
748  : (__throw_bad_optional_access("Attempt to access value of a "
749  "disengaged optional object"),
750  this->_M_get());
751  }
752 
753  constexpr _Tp&
754  value()&
755  {
756  return this->_M_is_engaged()
757  ? this->_M_get()
758  : (__throw_bad_optional_access("Attempt to access value of a "
759  "disengaged optional object"),
760  this->_M_get());
761  }
762 
763  constexpr _Tp&&
764  value()&&
765  {
766  return this->_M_is_engaged()
767  ? std::move(this->_M_get())
768  : (__throw_bad_optional_access("Attempt to access value of a "
769  "disengaged optional object"),
770  std::move(this->_M_get()));
771  }
772 
773  constexpr const _Tp&&
774  value() const&&
775  {
776  return this->_M_is_engaged()
777  ? std::move(this->_M_get())
778  : (__throw_bad_optional_access("Attempt to access value of a "
779  "disengaged optional object"),
780  std::move(this->_M_get()));
781  }
782 
783  template<typename _Up>
784  constexpr _Tp
785  value_or(_Up&& __u) const&
786  {
787  static_assert(__and_<is_copy_constructible<_Tp>,
788  is_convertible<_Up&&, _Tp>>(),
789  "Cannot return value");
790 
791  return this->_M_is_engaged()
792  ? this->_M_get()
793  : static_cast<_Tp>(std::forward<_Up>(__u));
794  }
795 
796  template<typename _Up>
797  _Tp
798  value_or(_Up&& __u) &&
799  {
800  static_assert(__and_<is_move_constructible<_Tp>,
801  is_convertible<_Up&&, _Tp>>(),
802  "Cannot return value" );
803 
804  return this->_M_is_engaged()
805  ? std::move(this->_M_get())
806  : static_cast<_Tp>(std::forward<_Up>(__u));
807  }
808  };
809 
810  // [X.Y.8] Comparisons between optional values.
811  template<typename _Tp>
812  constexpr bool
813  operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
814  {
815  return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
816  && (!__lhs || *__lhs == *__rhs);
817  }
818 
819  template<typename _Tp>
820  constexpr bool
821  operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
822  { return !(__lhs == __rhs); }
823 
824  template<typename _Tp>
825  constexpr bool
826  operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
827  {
828  return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
829  }
830 
831  template<typename _Tp>
832  constexpr bool
833  operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
834  { return __rhs < __lhs; }
835 
836  template<typename _Tp>
837  constexpr bool
838  operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
839  { return !(__rhs < __lhs); }
840 
841  template<typename _Tp>
842  constexpr bool
843  operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
844  { return !(__lhs < __rhs); }
845 
846  // [X.Y.9] Comparisons with nullopt.
847  template<typename _Tp>
848  constexpr bool
849  operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
850  { return !__lhs; }
851 
852  template<typename _Tp>
853  constexpr bool
854  operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
855  { return !__rhs; }
856 
857  template<typename _Tp>
858  constexpr bool
859  operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
860  { return static_cast<bool>(__lhs); }
861 
862  template<typename _Tp>
863  constexpr bool
864  operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
865  { return static_cast<bool>(__rhs); }
866 
867  template<typename _Tp>
868  constexpr bool
869  operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
870  { return false; }
871 
872  template<typename _Tp>
873  constexpr bool
874  operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
875  { return static_cast<bool>(__rhs); }
876 
877  template<typename _Tp>
878  constexpr bool
879  operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
880  { return static_cast<bool>(__lhs); }
881 
882  template<typename _Tp>
883  constexpr bool
884  operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
885  { return false; }
886 
887  template<typename _Tp>
888  constexpr bool
889  operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
890  { return !__lhs; }
891 
892  template<typename _Tp>
893  constexpr bool
894  operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
895  { return true; }
896 
897  template<typename _Tp>
898  constexpr bool
899  operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
900  { return true; }
901 
902  template<typename _Tp>
903  constexpr bool
904  operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
905  { return !__rhs; }
906 
907  // [X.Y.10] Comparisons with value type.
908  template<typename _Tp>
909  constexpr bool
910  operator==(const optional<_Tp>& __lhs, const _Tp& __rhs)
911  { return __lhs && *__lhs == __rhs; }
912 
913  template<typename _Tp>
914  constexpr bool
915  operator==(const _Tp& __lhs, const optional<_Tp>& __rhs)
916  { return __rhs && __lhs == *__rhs; }
917 
918  template<typename _Tp>
919  constexpr bool
920  operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs)
921  { return !__lhs || !(*__lhs == __rhs); }
922 
923  template<typename _Tp>
924  constexpr bool
925  operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs)
926  { return !__rhs || !(__lhs == *__rhs); }
927 
928  template<typename _Tp>
929  constexpr bool
930  operator<(const optional<_Tp>& __lhs, const _Tp& __rhs)
931  { return !__lhs || *__lhs < __rhs; }
932 
933  template<typename _Tp>
934  constexpr bool
935  operator<(const _Tp& __lhs, const optional<_Tp>& __rhs)
936  { return __rhs && __lhs < *__rhs; }
937 
938  template<typename _Tp>
939  constexpr bool
940  operator>(const optional<_Tp>& __lhs, const _Tp& __rhs)
941  { return __lhs && __rhs < *__lhs; }
942 
943  template<typename _Tp>
944  constexpr bool
945  operator>(const _Tp& __lhs, const optional<_Tp>& __rhs)
946  { return !__rhs || *__rhs < __lhs; }
947 
948  template<typename _Tp>
949  constexpr bool
950  operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs)
951  { return !__lhs || !(__rhs < *__lhs); }
952 
953  template<typename _Tp>
954  constexpr bool
955  operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs)
956  { return __rhs && !(*__rhs < __lhs); }
957 
958  template<typename _Tp>
959  constexpr bool
960  operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs)
961  { return __lhs && !(*__lhs < __rhs); }
962 
963  template<typename _Tp>
964  constexpr bool
965  operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs)
966  { return !__rhs || !(__lhs < *__rhs); }
967 
968  // [X.Y.11]
969  template<typename _Tp>
970  inline void
971  swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
972  noexcept(noexcept(__lhs.swap(__rhs)))
973  { __lhs.swap(__rhs); }
974 
975  template<typename _Tp>
976  constexpr optional<decay_t<_Tp>>
977  make_optional(_Tp&& __t)
978  { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
979 
980  // @} group optional
981 } // namespace fundamentals_v1
982 } // namespace experimental
983 
984  // [X.Y.12]
985  template<typename _Tp>
986  struct hash<experimental::optional<_Tp>>
987  {
988  using result_type = size_t;
989  using argument_type = experimental::optional<_Tp>;
990 
991  size_t
992  operator()(const experimental::optional<_Tp>& __t) const
993  noexcept(noexcept(hash<_Tp> {}(*__t)))
994  {
995  // We pick an arbitrary hash for disengaged optionals which hopefully
996  // usual values of _Tp won't typically hash to.
997  constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
998  return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash;
999  }
1000  };
1001 
1002 _GLIBCXX_END_NAMESPACE_VERSION
1003 } // namespace std
1004 
1005 #endif // C++14
1006 
1007 #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL