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