optional 28 KB

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