You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. // <optional> -*- C++ -*-
  2. // Copyright (C) 2013-2020 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 include/optional
  21. * This is a Standard C++ Library header.
  22. */
  23. #ifndef _GLIBCXX_OPTIONAL
  24. #define _GLIBCXX_OPTIONAL 1
  25. #pragma GCC system_header
  26. #if __cplusplus >= 201703L
  27. #include <utility>
  28. #include <type_traits>
  29. #include <exception>
  30. #include <new>
  31. #include <initializer_list>
  32. #include <bits/exception_defines.h>
  33. #include <bits/functional_hash.h>
  34. #include <bits/enable_special_members.h>
  35. #if __cplusplus > 201703L
  36. # include <compare>
  37. #endif
  38. namespace std _GLIBCXX_VISIBILITY(default)
  39. {
  40. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  41. /**
  42. * @addtogroup utilities
  43. * @{
  44. */
  45. #define __cpp_lib_optional 201606L
  46. template<typename _Tp>
  47. class optional;
  48. /// Tag type to disengage optional objects.
  49. struct nullopt_t
  50. {
  51. // Do not user-declare default constructor at all for
  52. // optional_value = {} syntax to work.
  53. // nullopt_t() = delete;
  54. // Used for constructing nullopt.
  55. enum class _Construct { _Token };
  56. // Must be constexpr for nullopt_t to be literal.
  57. explicit constexpr nullopt_t(_Construct) { }
  58. };
  59. /// Tag to disengage optional objects.
  60. inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
  61. /**
  62. * @brief Exception class thrown when a disengaged optional object is
  63. * dereferenced.
  64. * @ingroup exceptions
  65. */
  66. class bad_optional_access : public exception
  67. {
  68. public:
  69. bad_optional_access() { }
  70. virtual const char* what() const noexcept override
  71. { return "bad optional access"; }
  72. virtual ~bad_optional_access() noexcept = default;
  73. };
  74. void
  75. __throw_bad_optional_access()
  76. __attribute__((__noreturn__));
  77. // XXX Does not belong here.
  78. inline void
  79. __throw_bad_optional_access()
  80. { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
  81. // This class template manages construction/destruction of
  82. // the contained value for a std::optional.
  83. template <typename _Tp>
  84. struct _Optional_payload_base
  85. {
  86. using _Stored_type = remove_const_t<_Tp>;
  87. _Optional_payload_base() = default;
  88. ~_Optional_payload_base() = default;
  89. template<typename... _Args>
  90. constexpr
  91. _Optional_payload_base(in_place_t __tag, _Args&&... __args)
  92. : _M_payload(__tag, std::forward<_Args>(__args)...),
  93. _M_engaged(true)
  94. { }
  95. template<typename _Up, typename... _Args>
  96. constexpr
  97. _Optional_payload_base(std::initializer_list<_Up> __il,
  98. _Args&&... __args)
  99. : _M_payload(__il, std::forward<_Args>(__args)...),
  100. _M_engaged(true)
  101. { }
  102. // Constructor used by _Optional_base copy constructor when the
  103. // contained value is not trivially copy constructible.
  104. constexpr
  105. _Optional_payload_base(bool __engaged,
  106. const _Optional_payload_base& __other)
  107. {
  108. if (__other._M_engaged)
  109. this->_M_construct(__other._M_get());
  110. }
  111. // Constructor used by _Optional_base move constructor when the
  112. // contained value is not trivially move constructible.
  113. constexpr
  114. _Optional_payload_base(bool __engaged,
  115. _Optional_payload_base&& __other)
  116. {
  117. if (__other._M_engaged)
  118. this->_M_construct(std::move(__other._M_get()));
  119. }
  120. // Copy constructor is only used to when the contained value is
  121. // trivially copy constructible.
  122. _Optional_payload_base(const _Optional_payload_base&) = default;
  123. // Move constructor is only used to when the contained value is
  124. // trivially copy constructible.
  125. _Optional_payload_base(_Optional_payload_base&&) = default;
  126. _Optional_payload_base&
  127. operator=(const _Optional_payload_base&) = default;
  128. _Optional_payload_base&
  129. operator=(_Optional_payload_base&&) = default;
  130. // used to perform non-trivial copy assignment.
  131. constexpr void
  132. _M_copy_assign(const _Optional_payload_base& __other)
  133. {
  134. if (this->_M_engaged && __other._M_engaged)
  135. this->_M_get() = __other._M_get();
  136. else
  137. {
  138. if (__other._M_engaged)
  139. this->_M_construct(__other._M_get());
  140. else
  141. this->_M_reset();
  142. }
  143. }
  144. // used to perform non-trivial move assignment.
  145. constexpr void
  146. _M_move_assign(_Optional_payload_base&& __other)
  147. noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
  148. is_nothrow_move_assignable<_Tp>>)
  149. {
  150. if (this->_M_engaged && __other._M_engaged)
  151. this->_M_get() = std::move(__other._M_get());
  152. else
  153. {
  154. if (__other._M_engaged)
  155. this->_M_construct(std::move(__other._M_get()));
  156. else
  157. this->_M_reset();
  158. }
  159. }
  160. struct _Empty_byte { };
  161. template<typename _Up, bool = is_trivially_destructible_v<_Up>>
  162. union _Storage
  163. {
  164. constexpr _Storage() noexcept : _M_empty() { }
  165. template<typename... _Args>
  166. constexpr
  167. _Storage(in_place_t, _Args&&... __args)
  168. : _M_value(std::forward<_Args>(__args)...)
  169. { }
  170. template<typename _Vp, typename... _Args>
  171. constexpr
  172. _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
  173. : _M_value(__il, std::forward<_Args>(__args)...)
  174. { }
  175. _Empty_byte _M_empty;
  176. _Up _M_value;
  177. };
  178. template<typename _Up>
  179. union _Storage<_Up, false>
  180. {
  181. constexpr _Storage() noexcept : _M_empty() { }
  182. template<typename... _Args>
  183. constexpr
  184. _Storage(in_place_t, _Args&&... __args)
  185. : _M_value(std::forward<_Args>(__args)...)
  186. { }
  187. template<typename _Vp, typename... _Args>
  188. constexpr
  189. _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
  190. : _M_value(__il, std::forward<_Args>(__args)...)
  191. { }
  192. // User-provided destructor is needed when _Up has non-trivial dtor.
  193. ~_Storage() { }
  194. _Empty_byte _M_empty;
  195. _Up _M_value;
  196. };
  197. _Storage<_Stored_type> _M_payload;
  198. bool _M_engaged = false;
  199. template<typename... _Args>
  200. void
  201. _M_construct(_Args&&... __args)
  202. noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
  203. {
  204. ::new ((void *) std::__addressof(this->_M_payload))
  205. _Stored_type(std::forward<_Args>(__args)...);
  206. this->_M_engaged = true;
  207. }
  208. constexpr void
  209. _M_destroy() noexcept
  210. {
  211. _M_engaged = false;
  212. _M_payload._M_value.~_Stored_type();
  213. }
  214. // The _M_get() operations have _M_engaged as a precondition.
  215. // They exist to access the contained value with the appropriate
  216. // const-qualification, because _M_payload has had the const removed.
  217. constexpr _Tp&
  218. _M_get() noexcept
  219. { return this->_M_payload._M_value; }
  220. constexpr const _Tp&
  221. _M_get() const noexcept
  222. { return this->_M_payload._M_value; }
  223. // _M_reset is a 'safe' operation with no precondition.
  224. constexpr void
  225. _M_reset() noexcept
  226. {
  227. if (this->_M_engaged)
  228. _M_destroy();
  229. }
  230. };
  231. // Class template that manages the payload for optionals.
  232. template <typename _Tp,
  233. bool /*_HasTrivialDestructor*/ =
  234. is_trivially_destructible_v<_Tp>,
  235. bool /*_HasTrivialCopy */ =
  236. is_trivially_copy_assignable_v<_Tp>
  237. && is_trivially_copy_constructible_v<_Tp>,
  238. bool /*_HasTrivialMove */ =
  239. is_trivially_move_assignable_v<_Tp>
  240. && is_trivially_move_constructible_v<_Tp>>
  241. struct _Optional_payload;
  242. // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
  243. template <typename _Tp>
  244. struct _Optional_payload<_Tp, true, true, true>
  245. : _Optional_payload_base<_Tp>
  246. {
  247. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  248. _Optional_payload() = default;
  249. };
  250. // Payload for optionals with non-trivial copy construction/assignment.
  251. template <typename _Tp>
  252. struct _Optional_payload<_Tp, true, false, true>
  253. : _Optional_payload_base<_Tp>
  254. {
  255. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  256. _Optional_payload() = default;
  257. ~_Optional_payload() = default;
  258. _Optional_payload(const _Optional_payload&) = default;
  259. _Optional_payload(_Optional_payload&&) = default;
  260. _Optional_payload& operator=(_Optional_payload&&) = default;
  261. // Non-trivial copy assignment.
  262. constexpr
  263. _Optional_payload&
  264. operator=(const _Optional_payload& __other)
  265. {
  266. this->_M_copy_assign(__other);
  267. return *this;
  268. }
  269. };
  270. // Payload for optionals with non-trivial move construction/assignment.
  271. template <typename _Tp>
  272. struct _Optional_payload<_Tp, true, true, false>
  273. : _Optional_payload_base<_Tp>
  274. {
  275. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  276. _Optional_payload() = default;
  277. ~_Optional_payload() = default;
  278. _Optional_payload(const _Optional_payload&) = default;
  279. _Optional_payload(_Optional_payload&&) = default;
  280. _Optional_payload& operator=(const _Optional_payload&) = default;
  281. // Non-trivial move assignment.
  282. constexpr
  283. _Optional_payload&
  284. operator=(_Optional_payload&& __other)
  285. noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
  286. is_nothrow_move_assignable<_Tp>>)
  287. {
  288. this->_M_move_assign(std::move(__other));
  289. return *this;
  290. }
  291. };
  292. // Payload for optionals with non-trivial copy and move assignment.
  293. template <typename _Tp>
  294. struct _Optional_payload<_Tp, true, false, false>
  295. : _Optional_payload_base<_Tp>
  296. {
  297. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  298. _Optional_payload() = default;
  299. ~_Optional_payload() = default;
  300. _Optional_payload(const _Optional_payload&) = default;
  301. _Optional_payload(_Optional_payload&&) = default;
  302. // Non-trivial copy assignment.
  303. constexpr
  304. _Optional_payload&
  305. operator=(const _Optional_payload& __other)
  306. {
  307. this->_M_copy_assign(__other);
  308. return *this;
  309. }
  310. // Non-trivial move assignment.
  311. constexpr
  312. _Optional_payload&
  313. operator=(_Optional_payload&& __other)
  314. noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
  315. is_nothrow_move_assignable<_Tp>>)
  316. {
  317. this->_M_move_assign(std::move(__other));
  318. return *this;
  319. }
  320. };
  321. // Payload for optionals with non-trivial destructors.
  322. template <typename _Tp, bool _Copy, bool _Move>
  323. struct _Optional_payload<_Tp, false, _Copy, _Move>
  324. : _Optional_payload<_Tp, true, false, false>
  325. {
  326. // Base class implements all the constructors and assignment operators:
  327. using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
  328. _Optional_payload() = default;
  329. _Optional_payload(const _Optional_payload&) = default;
  330. _Optional_payload(_Optional_payload&&) = default;
  331. _Optional_payload& operator=(const _Optional_payload&) = default;
  332. _Optional_payload& operator=(_Optional_payload&&) = default;
  333. // Destructor needs to destroy the contained value:
  334. ~_Optional_payload() { this->_M_reset(); }
  335. };
  336. // Common base class for _Optional_base<T> to avoid repeating these
  337. // member functions in each specialization.
  338. template<typename _Tp, typename _Dp>
  339. class _Optional_base_impl
  340. {
  341. protected:
  342. using _Stored_type = remove_const_t<_Tp>;
  343. // The _M_construct operation has !_M_engaged as a precondition
  344. // while _M_destruct has _M_engaged as a precondition.
  345. template<typename... _Args>
  346. void
  347. _M_construct(_Args&&... __args)
  348. noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
  349. {
  350. ::new
  351. (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
  352. _Stored_type(std::forward<_Args>(__args)...);
  353. static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
  354. }
  355. void
  356. _M_destruct() noexcept
  357. { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
  358. // _M_reset is a 'safe' operation with no precondition.
  359. constexpr void
  360. _M_reset() noexcept
  361. { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
  362. constexpr bool _M_is_engaged() const noexcept
  363. { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
  364. // The _M_get operations have _M_engaged as a precondition.
  365. constexpr _Tp&
  366. _M_get() noexcept
  367. {
  368. __glibcxx_assert(this->_M_is_engaged());
  369. return static_cast<_Dp*>(this)->_M_payload._M_get();
  370. }
  371. constexpr const _Tp&
  372. _M_get() const noexcept
  373. {
  374. __glibcxx_assert(this->_M_is_engaged());
  375. return static_cast<const _Dp*>(this)->_M_payload._M_get();
  376. }
  377. };
  378. /**
  379. * @brief Class template that provides copy/move constructors of optional.
  380. *
  381. * Such a separate base class template is necessary in order to
  382. * conditionally make copy/move constructors trivial.
  383. *
  384. * When the contained value is trivially copy/move constructible,
  385. * the copy/move constructors of _Optional_base will invoke the
  386. * trivial copy/move constructor of _Optional_payload. Otherwise,
  387. * they will invoke _Optional_payload(bool, const _Optional_payload&)
  388. * or _Optional_payload(bool, _Optional_payload&&) to initialize
  389. * the contained value, if copying/moving an engaged optional.
  390. *
  391. * Whether the other special members are trivial is determined by the
  392. * _Optional_payload<_Tp> specialization used for the _M_payload member.
  393. *
  394. * @see optional, _Enable_special_members
  395. */
  396. template<typename _Tp,
  397. bool = is_trivially_copy_constructible_v<_Tp>,
  398. bool = is_trivially_move_constructible_v<_Tp>>
  399. struct _Optional_base
  400. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  401. {
  402. // Constructors for disengaged optionals.
  403. constexpr _Optional_base() = default;
  404. // Constructors for engaged optionals.
  405. template<typename... _Args,
  406. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  407. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  408. : _M_payload(in_place,
  409. std::forward<_Args>(__args)...) { }
  410. template<typename _Up, typename... _Args,
  411. enable_if_t<is_constructible_v<_Tp,
  412. initializer_list<_Up>&,
  413. _Args&&...>, bool> = false>
  414. constexpr explicit _Optional_base(in_place_t,
  415. initializer_list<_Up> __il,
  416. _Args&&... __args)
  417. : _M_payload(in_place,
  418. __il, std::forward<_Args>(__args)...)
  419. { }
  420. // Copy and move constructors.
  421. constexpr _Optional_base(const _Optional_base& __other)
  422. : _M_payload(__other._M_payload._M_engaged,
  423. __other._M_payload)
  424. { }
  425. constexpr _Optional_base(_Optional_base&& __other)
  426. noexcept(is_nothrow_move_constructible_v<_Tp>)
  427. : _M_payload(__other._M_payload._M_engaged,
  428. std::move(__other._M_payload))
  429. { }
  430. // Assignment operators.
  431. _Optional_base& operator=(const _Optional_base&) = default;
  432. _Optional_base& operator=(_Optional_base&&) = default;
  433. _Optional_payload<_Tp> _M_payload;
  434. };
  435. template<typename _Tp>
  436. struct _Optional_base<_Tp, false, true>
  437. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  438. {
  439. // Constructors for disengaged optionals.
  440. constexpr _Optional_base() = default;
  441. // Constructors for engaged optionals.
  442. template<typename... _Args,
  443. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  444. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  445. : _M_payload(in_place,
  446. std::forward<_Args>(__args)...) { }
  447. template<typename _Up, typename... _Args,
  448. enable_if_t<is_constructible_v<_Tp,
  449. initializer_list<_Up>&,
  450. _Args&&...>, bool> = false>
  451. constexpr explicit _Optional_base(in_place_t,
  452. initializer_list<_Up> __il,
  453. _Args&&... __args)
  454. : _M_payload(in_place,
  455. __il, std::forward<_Args>(__args)...)
  456. { }
  457. // Copy and move constructors.
  458. constexpr _Optional_base(const _Optional_base& __other)
  459. : _M_payload(__other._M_payload._M_engaged,
  460. __other._M_payload)
  461. { }
  462. constexpr _Optional_base(_Optional_base&& __other) = default;
  463. // Assignment operators.
  464. _Optional_base& operator=(const _Optional_base&) = default;
  465. _Optional_base& operator=(_Optional_base&&) = default;
  466. _Optional_payload<_Tp> _M_payload;
  467. };
  468. template<typename _Tp>
  469. struct _Optional_base<_Tp, true, false>
  470. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  471. {
  472. // Constructors for disengaged optionals.
  473. constexpr _Optional_base() = default;
  474. // Constructors for engaged optionals.
  475. template<typename... _Args,
  476. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  477. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  478. : _M_payload(in_place,
  479. std::forward<_Args>(__args)...) { }
  480. template<typename _Up, typename... _Args,
  481. enable_if_t<is_constructible_v<_Tp,
  482. initializer_list<_Up>&,
  483. _Args&&...>, bool> = false>
  484. constexpr explicit _Optional_base(in_place_t,
  485. initializer_list<_Up> __il,
  486. _Args&&... __args)
  487. : _M_payload(in_place,
  488. __il, std::forward<_Args>(__args)...)
  489. { }
  490. // Copy and move constructors.
  491. constexpr _Optional_base(const _Optional_base& __other) = default;
  492. constexpr _Optional_base(_Optional_base&& __other)
  493. noexcept(is_nothrow_move_constructible_v<_Tp>)
  494. : _M_payload(__other._M_payload._M_engaged,
  495. std::move(__other._M_payload))
  496. { }
  497. // Assignment operators.
  498. _Optional_base& operator=(const _Optional_base&) = default;
  499. _Optional_base& operator=(_Optional_base&&) = default;
  500. _Optional_payload<_Tp> _M_payload;
  501. };
  502. template<typename _Tp>
  503. struct _Optional_base<_Tp, true, true>
  504. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  505. {
  506. // Constructors for disengaged optionals.
  507. constexpr _Optional_base() = default;
  508. // Constructors for engaged optionals.
  509. template<typename... _Args,
  510. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  511. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  512. : _M_payload(in_place,
  513. std::forward<_Args>(__args)...) { }
  514. template<typename _Up, typename... _Args,
  515. enable_if_t<is_constructible_v<_Tp,
  516. initializer_list<_Up>&,
  517. _Args&&...>, bool> = false>
  518. constexpr explicit _Optional_base(in_place_t,
  519. initializer_list<_Up> __il,
  520. _Args&&... __args)
  521. : _M_payload(in_place,
  522. __il, std::forward<_Args>(__args)...)
  523. { }
  524. // Copy and move constructors.
  525. constexpr _Optional_base(const _Optional_base& __other) = default;
  526. constexpr _Optional_base(_Optional_base&& __other) = default;
  527. // Assignment operators.
  528. _Optional_base& operator=(const _Optional_base&) = default;
  529. _Optional_base& operator=(_Optional_base&&) = default;
  530. _Optional_payload<_Tp> _M_payload;
  531. };
  532. template<typename _Tp>
  533. class optional;
  534. template<typename _Tp, typename _Up>
  535. using __converts_from_optional =
  536. __or_<is_constructible<_Tp, const optional<_Up>&>,
  537. is_constructible<_Tp, optional<_Up>&>,
  538. is_constructible<_Tp, const optional<_Up>&&>,
  539. is_constructible<_Tp, optional<_Up>&&>,
  540. is_convertible<const optional<_Up>&, _Tp>,
  541. is_convertible<optional<_Up>&, _Tp>,
  542. is_convertible<const optional<_Up>&&, _Tp>,
  543. is_convertible<optional<_Up>&&, _Tp>>;
  544. template<typename _Tp, typename _Up>
  545. using __assigns_from_optional =
  546. __or_<is_assignable<_Tp&, const optional<_Up>&>,
  547. is_assignable<_Tp&, optional<_Up>&>,
  548. is_assignable<_Tp&, const optional<_Up>&&>,
  549. is_assignable<_Tp&, optional<_Up>&&>>;
  550. /**
  551. * @brief Class template for optional values.
  552. */
  553. template<typename _Tp>
  554. class optional
  555. : private _Optional_base<_Tp>,
  556. private _Enable_copy_move<
  557. // Copy constructor.
  558. is_copy_constructible_v<_Tp>,
  559. // Copy assignment.
  560. __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
  561. // Move constructor.
  562. is_move_constructible_v<_Tp>,
  563. // Move assignment.
  564. __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
  565. // Unique tag type.
  566. optional<_Tp>>
  567. {
  568. static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
  569. static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
  570. static_assert(!is_reference_v<_Tp>);
  571. private:
  572. using _Base = _Optional_base<_Tp>;
  573. // SFINAE helpers
  574. template<typename _Up>
  575. using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
  576. template<typename _Up>
  577. using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
  578. template<typename... _Cond>
  579. using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
  580. public:
  581. using value_type = _Tp;
  582. constexpr optional() = default;
  583. constexpr optional(nullopt_t) noexcept { }
  584. // Converting constructors for engaged optionals.
  585. template<typename _Up = _Tp,
  586. _Requires<__not_self<_Up>, __not_tag<_Up>,
  587. is_constructible<_Tp, _Up&&>,
  588. is_convertible<_Up&&, _Tp>> = true>
  589. constexpr
  590. optional(_Up&& __t)
  591. : _Base(std::in_place, std::forward<_Up>(__t)) { }
  592. template<typename _Up = _Tp,
  593. _Requires<__not_self<_Up>, __not_tag<_Up>,
  594. is_constructible<_Tp, _Up&&>,
  595. __not_<is_convertible<_Up&&, _Tp>>> = false>
  596. explicit constexpr
  597. optional(_Up&& __t)
  598. : _Base(std::in_place, std::forward<_Up>(__t)) { }
  599. template<typename _Up,
  600. _Requires<__not_<is_same<_Tp, _Up>>,
  601. is_constructible<_Tp, const _Up&>,
  602. is_convertible<const _Up&, _Tp>,
  603. __not_<__converts_from_optional<_Tp, _Up>>> = true>
  604. constexpr
  605. optional(const optional<_Up>& __t)
  606. {
  607. if (__t)
  608. emplace(*__t);
  609. }
  610. template<typename _Up,
  611. _Requires<__not_<is_same<_Tp, _Up>>,
  612. is_constructible<_Tp, const _Up&>,
  613. __not_<is_convertible<const _Up&, _Tp>>,
  614. __not_<__converts_from_optional<_Tp, _Up>>> = false>
  615. explicit constexpr
  616. optional(const optional<_Up>& __t)
  617. {
  618. if (__t)
  619. emplace(*__t);
  620. }
  621. template <typename _Up,
  622. _Requires<__not_<is_same<_Tp, _Up>>,
  623. is_constructible<_Tp, _Up&&>,
  624. is_convertible<_Up&&, _Tp>,
  625. __not_<__converts_from_optional<_Tp, _Up>>> = true>
  626. constexpr
  627. optional(optional<_Up>&& __t)
  628. {
  629. if (__t)
  630. emplace(std::move(*__t));
  631. }
  632. template <typename _Up,
  633. _Requires<__not_<is_same<_Tp, _Up>>,
  634. is_constructible<_Tp, _Up&&>,
  635. __not_<is_convertible<_Up&&, _Tp>>,
  636. __not_<__converts_from_optional<_Tp, _Up>>> = false>
  637. explicit constexpr
  638. optional(optional<_Up>&& __t)
  639. {
  640. if (__t)
  641. emplace(std::move(*__t));
  642. }
  643. template<typename... _Args,
  644. _Requires<is_constructible<_Tp, _Args&&...>> = false>
  645. explicit constexpr
  646. optional(in_place_t, _Args&&... __args)
  647. : _Base(std::in_place, std::forward<_Args>(__args)...) { }
  648. template<typename _Up, typename... _Args,
  649. _Requires<is_constructible<_Tp,
  650. initializer_list<_Up>&,
  651. _Args&&...>> = false>
  652. explicit constexpr
  653. optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
  654. : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
  655. // Assignment operators.
  656. optional&
  657. operator=(nullopt_t) noexcept
  658. {
  659. this->_M_reset();
  660. return *this;
  661. }
  662. template<typename _Up = _Tp>
  663. enable_if_t<__and_v<__not_self<_Up>,
  664. __not_<__and_<is_scalar<_Tp>,
  665. is_same<_Tp, decay_t<_Up>>>>,
  666. is_constructible<_Tp, _Up>,
  667. is_assignable<_Tp&, _Up>>,
  668. optional&>
  669. operator=(_Up&& __u)
  670. {
  671. if (this->_M_is_engaged())
  672. this->_M_get() = std::forward<_Up>(__u);
  673. else
  674. this->_M_construct(std::forward<_Up>(__u));
  675. return *this;
  676. }
  677. template<typename _Up>
  678. enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
  679. is_constructible<_Tp, const _Up&>,
  680. is_assignable<_Tp&, _Up>,
  681. __not_<__converts_from_optional<_Tp, _Up>>,
  682. __not_<__assigns_from_optional<_Tp, _Up>>>,
  683. optional&>
  684. operator=(const optional<_Up>& __u)
  685. {
  686. if (__u)
  687. {
  688. if (this->_M_is_engaged())
  689. this->_M_get() = *__u;
  690. else
  691. this->_M_construct(*__u);
  692. }
  693. else
  694. {
  695. this->_M_reset();
  696. }
  697. return *this;
  698. }
  699. template<typename _Up>
  700. enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
  701. is_constructible<_Tp, _Up>,
  702. is_assignable<_Tp&, _Up>,
  703. __not_<__converts_from_optional<_Tp, _Up>>,
  704. __not_<__assigns_from_optional<_Tp, _Up>>>,
  705. optional&>
  706. operator=(optional<_Up>&& __u)
  707. {
  708. if (__u)
  709. {
  710. if (this->_M_is_engaged())
  711. this->_M_get() = std::move(*__u);
  712. else
  713. this->_M_construct(std::move(*__u));
  714. }
  715. else
  716. {
  717. this->_M_reset();
  718. }
  719. return *this;
  720. }
  721. template<typename... _Args>
  722. enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
  723. emplace(_Args&&... __args)
  724. {
  725. this->_M_reset();
  726. this->_M_construct(std::forward<_Args>(__args)...);
  727. return this->_M_get();
  728. }
  729. template<typename _Up, typename... _Args>
  730. enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
  731. _Args&&...>, _Tp&>
  732. emplace(initializer_list<_Up> __il, _Args&&... __args)
  733. {
  734. this->_M_reset();
  735. this->_M_construct(__il, std::forward<_Args>(__args)...);
  736. return this->_M_get();
  737. }
  738. // Destructor is implicit, implemented in _Optional_base.
  739. // Swap.
  740. void
  741. swap(optional& __other)
  742. noexcept(is_nothrow_move_constructible_v<_Tp>
  743. && is_nothrow_swappable_v<_Tp>)
  744. {
  745. using std::swap;
  746. if (this->_M_is_engaged() && __other._M_is_engaged())
  747. swap(this->_M_get(), __other._M_get());
  748. else if (this->_M_is_engaged())
  749. {
  750. __other._M_construct(std::move(this->_M_get()));
  751. this->_M_destruct();
  752. }
  753. else if (__other._M_is_engaged())
  754. {
  755. this->_M_construct(std::move(__other._M_get()));
  756. __other._M_destruct();
  757. }
  758. }
  759. // Observers.
  760. constexpr const _Tp*
  761. operator->() const
  762. { return std::__addressof(this->_M_get()); }
  763. constexpr _Tp*
  764. operator->()
  765. { return std::__addressof(this->_M_get()); }
  766. constexpr const _Tp&
  767. operator*() const&
  768. { return this->_M_get(); }
  769. constexpr _Tp&
  770. operator*()&
  771. { return this->_M_get(); }
  772. constexpr _Tp&&
  773. operator*()&&
  774. { return std::move(this->_M_get()); }
  775. constexpr const _Tp&&
  776. operator*() const&&
  777. { return std::move(this->_M_get()); }
  778. constexpr explicit operator bool() const noexcept
  779. { return this->_M_is_engaged(); }
  780. constexpr bool has_value() const noexcept
  781. { return this->_M_is_engaged(); }
  782. constexpr const _Tp&
  783. value() const&
  784. {
  785. return this->_M_is_engaged()
  786. ? this->_M_get()
  787. : (__throw_bad_optional_access(), this->_M_get());
  788. }
  789. constexpr _Tp&
  790. value()&
  791. {
  792. return this->_M_is_engaged()
  793. ? this->_M_get()
  794. : (__throw_bad_optional_access(), this->_M_get());
  795. }
  796. constexpr _Tp&&
  797. value()&&
  798. {
  799. return this->_M_is_engaged()
  800. ? std::move(this->_M_get())
  801. : (__throw_bad_optional_access(), std::move(this->_M_get()));
  802. }
  803. constexpr const _Tp&&
  804. value() const&&
  805. {
  806. return this->_M_is_engaged()
  807. ? std::move(this->_M_get())
  808. : (__throw_bad_optional_access(), std::move(this->_M_get()));
  809. }
  810. template<typename _Up>
  811. constexpr _Tp
  812. value_or(_Up&& __u) const&
  813. {
  814. static_assert(is_copy_constructible_v<_Tp>);
  815. static_assert(is_convertible_v<_Up&&, _Tp>);
  816. return this->_M_is_engaged()
  817. ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u));
  818. }
  819. template<typename _Up>
  820. constexpr _Tp
  821. value_or(_Up&& __u) &&
  822. {
  823. static_assert(is_move_constructible_v<_Tp>);
  824. static_assert(is_convertible_v<_Up&&, _Tp>);
  825. return this->_M_is_engaged()
  826. ? std::move(this->_M_get())
  827. : static_cast<_Tp>(std::forward<_Up>(__u));
  828. }
  829. void reset() noexcept { this->_M_reset(); }
  830. };
  831. template<typename _Tp>
  832. using __optional_relop_t =
  833. enable_if_t<is_convertible<_Tp, bool>::value, bool>;
  834. // Comparisons between optional values.
  835. template<typename _Tp, typename _Up>
  836. constexpr auto
  837. operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  838. -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
  839. {
  840. return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
  841. && (!__lhs || *__lhs == *__rhs);
  842. }
  843. template<typename _Tp, typename _Up>
  844. constexpr auto
  845. operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  846. -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
  847. {
  848. return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
  849. || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
  850. }
  851. template<typename _Tp, typename _Up>
  852. constexpr auto
  853. operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  854. -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
  855. {
  856. return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
  857. }
  858. template<typename _Tp, typename _Up>
  859. constexpr auto
  860. operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  861. -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
  862. {
  863. return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
  864. }
  865. template<typename _Tp, typename _Up>
  866. constexpr auto
  867. operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  868. -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
  869. {
  870. return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
  871. }
  872. template<typename _Tp, typename _Up>
  873. constexpr auto
  874. operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  875. -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
  876. {
  877. return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
  878. }
  879. #ifdef __cpp_lib_three_way_comparison
  880. template<typename _Tp, three_way_comparable_with<_Tp> _Up>
  881. constexpr compare_three_way_result_t<_Tp, _Up>
  882. operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
  883. {
  884. return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
  885. }
  886. #endif
  887. // Comparisons with nullopt.
  888. template<typename _Tp>
  889. constexpr bool
  890. operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
  891. { return !__lhs; }
  892. #ifdef __cpp_lib_three_way_comparison
  893. template<typename _Tp>
  894. constexpr strong_ordering
  895. operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
  896. { return bool(__x) <=> false; }
  897. #else
  898. template<typename _Tp>
  899. constexpr bool
  900. operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
  901. { return !__rhs; }
  902. template<typename _Tp>
  903. constexpr bool
  904. operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
  905. { return static_cast<bool>(__lhs); }
  906. template<typename _Tp>
  907. constexpr bool
  908. operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
  909. { return static_cast<bool>(__rhs); }
  910. template<typename _Tp>
  911. constexpr bool
  912. operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
  913. { return false; }
  914. template<typename _Tp>
  915. constexpr bool
  916. operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
  917. { return static_cast<bool>(__rhs); }
  918. template<typename _Tp>
  919. constexpr bool
  920. operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
  921. { return static_cast<bool>(__lhs); }
  922. template<typename _Tp>
  923. constexpr bool
  924. operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
  925. { return false; }
  926. template<typename _Tp>
  927. constexpr bool
  928. operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
  929. { return !__lhs; }
  930. template<typename _Tp>
  931. constexpr bool
  932. operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
  933. { return true; }
  934. template<typename _Tp>
  935. constexpr bool
  936. operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
  937. { return true; }
  938. template<typename _Tp>
  939. constexpr bool
  940. operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
  941. { return !__rhs; }
  942. #endif // three-way-comparison
  943. // Comparisons with value type.
  944. template<typename _Tp, typename _Up>
  945. constexpr auto
  946. operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
  947. -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
  948. { return __lhs && *__lhs == __rhs; }
  949. template<typename _Tp, typename _Up>
  950. constexpr auto
  951. operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
  952. -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
  953. { return __rhs && __lhs == *__rhs; }
  954. template<typename _Tp, typename _Up>
  955. constexpr auto
  956. operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
  957. -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
  958. { return !__lhs || *__lhs != __rhs; }
  959. template<typename _Tp, typename _Up>
  960. constexpr auto
  961. operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
  962. -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
  963. { return !__rhs || __lhs != *__rhs; }
  964. template<typename _Tp, typename _Up>
  965. constexpr auto
  966. operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
  967. -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
  968. { return !__lhs || *__lhs < __rhs; }
  969. template<typename _Tp, typename _Up>
  970. constexpr auto
  971. operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
  972. -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
  973. { return __rhs && __lhs < *__rhs; }
  974. template<typename _Tp, typename _Up>
  975. constexpr auto
  976. operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
  977. -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
  978. { return __lhs && *__lhs > __rhs; }
  979. template<typename _Tp, typename _Up>
  980. constexpr auto
  981. operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
  982. -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
  983. { return !__rhs || __lhs > *__rhs; }
  984. template<typename _Tp, typename _Up>
  985. constexpr auto
  986. operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
  987. -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
  988. { return !__lhs || *__lhs <= __rhs; }
  989. template<typename _Tp, typename _Up>
  990. constexpr auto
  991. operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
  992. -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
  993. { return __rhs && __lhs <= *__rhs; }
  994. template<typename _Tp, typename _Up>
  995. constexpr auto
  996. operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
  997. -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
  998. { return __lhs && *__lhs >= __rhs; }
  999. template<typename _Tp, typename _Up>
  1000. constexpr auto
  1001. operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
  1002. -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
  1003. { return !__rhs || __lhs >= *__rhs; }
  1004. #ifdef __cpp_lib_three_way_comparison
  1005. template<typename _Tp, typename _Up>
  1006. constexpr compare_three_way_result_t<_Tp, _Up>
  1007. operator<=>(const optional<_Tp>& __x, const _Up& __v)
  1008. { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
  1009. #endif
  1010. // Swap and creation functions.
  1011. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1012. // 2748. swappable traits for optionals
  1013. template<typename _Tp>
  1014. inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
  1015. swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
  1016. noexcept(noexcept(__lhs.swap(__rhs)))
  1017. { __lhs.swap(__rhs); }
  1018. template<typename _Tp>
  1019. enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
  1020. swap(optional<_Tp>&, optional<_Tp>&) = delete;
  1021. template<typename _Tp>
  1022. constexpr optional<decay_t<_Tp>>
  1023. make_optional(_Tp&& __t)
  1024. { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
  1025. template<typename _Tp, typename ..._Args>
  1026. constexpr optional<_Tp>
  1027. make_optional(_Args&&... __args)
  1028. { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
  1029. template<typename _Tp, typename _Up, typename ..._Args>
  1030. constexpr optional<_Tp>
  1031. make_optional(initializer_list<_Up> __il, _Args&&... __args)
  1032. { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
  1033. // Hash.
  1034. template<typename _Tp, typename _Up = remove_const_t<_Tp>,
  1035. bool = __poison_hash<_Up>::__enable_hash_call>
  1036. struct __optional_hash_call_base
  1037. {
  1038. size_t
  1039. operator()(const optional<_Tp>& __t) const
  1040. noexcept(noexcept(hash<_Up>{}(*__t)))
  1041. {
  1042. // We pick an arbitrary hash for disengaged optionals which hopefully
  1043. // usual values of _Tp won't typically hash to.
  1044. constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
  1045. return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
  1046. }
  1047. };
  1048. template<typename _Tp, typename _Up>
  1049. struct __optional_hash_call_base<_Tp, _Up, false> {};
  1050. template<typename _Tp>
  1051. struct hash<optional<_Tp>>
  1052. : private __poison_hash<remove_const_t<_Tp>>,
  1053. public __optional_hash_call_base<_Tp>
  1054. {
  1055. using result_type [[__deprecated__]] = size_t;
  1056. using argument_type [[__deprecated__]] = optional<_Tp>;
  1057. };
  1058. template<typename _Tp>
  1059. struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
  1060. { };
  1061. /// @}
  1062. #if __cpp_deduction_guides >= 201606
  1063. template <typename _Tp> optional(_Tp) -> optional<_Tp>;
  1064. #endif
  1065. _GLIBCXX_END_NAMESPACE_VERSION
  1066. } // namespace std
  1067. #endif // C++17
  1068. #endif // _GLIBCXX_OPTIONAL