optional 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534
  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 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 <stdexcept>
  30. #include <new>
  31. #include <initializer_list>
  32. #include <bits/functexcept.h>
  33. #include <bits/functional_hash.h>
  34. #include <bits/enable_special_members.h>
  35. namespace std _GLIBCXX_VISIBILITY(default)
  36. {
  37. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  38. /**
  39. * @addtogroup utilities
  40. * @{
  41. */
  42. #define __cpp_lib_optional 201603
  43. template<typename _Tp>
  44. class optional;
  45. /// Tag type to disengage optional objects.
  46. struct nullopt_t
  47. {
  48. // Do not user-declare default constructor at all for
  49. // optional_value = {} syntax to work.
  50. // nullopt_t() = delete;
  51. // Used for constructing nullopt.
  52. enum class _Construct { _Token };
  53. // Must be constexpr for nullopt_t to be literal.
  54. explicit constexpr nullopt_t(_Construct) { }
  55. };
  56. /// Tag to disengage optional objects.
  57. inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
  58. /**
  59. * @brief Exception class thrown when a disengaged optional object is
  60. * dereferenced.
  61. * @ingroup exceptions
  62. */
  63. class bad_optional_access : public exception
  64. {
  65. public:
  66. bad_optional_access() { }
  67. virtual const char* what() const noexcept override
  68. { return "bad optional access"; }
  69. virtual ~bad_optional_access() noexcept = default;
  70. };
  71. void
  72. __throw_bad_optional_access()
  73. __attribute__((__noreturn__));
  74. // XXX Does not belong here.
  75. inline void
  76. __throw_bad_optional_access()
  77. { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
  78. // Payload for optionals with non-trivial destructor.
  79. template <typename _Tp,
  80. bool /*_HasTrivialDestructor*/ =
  81. is_trivially_destructible_v<_Tp>,
  82. bool /*_HasTrivialCopy */ =
  83. is_trivially_copy_assignable_v<_Tp>
  84. && is_trivially_copy_constructible_v<_Tp>,
  85. bool /*_HasTrivialMove */ =
  86. is_trivially_move_assignable_v<_Tp>
  87. && is_trivially_move_constructible_v<_Tp>>
  88. struct _Optional_payload
  89. {
  90. constexpr _Optional_payload() noexcept : _M_empty() { }
  91. template <typename... _Args>
  92. constexpr
  93. _Optional_payload(in_place_t, _Args&&... __args)
  94. : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
  95. template<typename _Up, typename... _Args>
  96. constexpr
  97. _Optional_payload(std::initializer_list<_Up> __il,
  98. _Args&&... __args)
  99. : _M_payload(__il, std::forward<_Args>(__args)...),
  100. _M_engaged(true)
  101. { }
  102. constexpr
  103. _Optional_payload(bool __engaged, const _Optional_payload& __other)
  104. : _Optional_payload(__other)
  105. { }
  106. constexpr
  107. _Optional_payload(bool __engaged, _Optional_payload&& __other)
  108. : _Optional_payload(std::move(__other))
  109. { }
  110. constexpr
  111. _Optional_payload(const _Optional_payload& __other)
  112. {
  113. if (__other._M_engaged)
  114. this->_M_construct(__other._M_payload);
  115. }
  116. constexpr
  117. _Optional_payload(_Optional_payload&& __other)
  118. {
  119. if (__other._M_engaged)
  120. this->_M_construct(std::move(__other._M_payload));
  121. }
  122. constexpr
  123. _Optional_payload&
  124. operator=(const _Optional_payload& __other)
  125. {
  126. if (this->_M_engaged && __other._M_engaged)
  127. this->_M_get() = __other._M_get();
  128. else
  129. {
  130. if (__other._M_engaged)
  131. this->_M_construct(__other._M_get());
  132. else
  133. this->_M_reset();
  134. }
  135. return *this;
  136. }
  137. constexpr
  138. _Optional_payload&
  139. operator=(_Optional_payload&& __other)
  140. noexcept(__and_<is_nothrow_move_constructible<_Tp>,
  141. is_nothrow_move_assignable<_Tp>>())
  142. {
  143. if (this->_M_engaged && __other._M_engaged)
  144. this->_M_get() = std::move(__other._M_get());
  145. else
  146. {
  147. if (__other._M_engaged)
  148. this->_M_construct(std::move(__other._M_get()));
  149. else
  150. this->_M_reset();
  151. }
  152. return *this;
  153. }
  154. using _Stored_type = remove_const_t<_Tp>;
  155. struct _Empty_byte { };
  156. union {
  157. _Empty_byte _M_empty;
  158. _Stored_type _M_payload;
  159. };
  160. bool _M_engaged = false;
  161. ~_Optional_payload()
  162. {
  163. if (_M_engaged)
  164. _M_payload.~_Stored_type();
  165. }
  166. template<typename... _Args>
  167. void
  168. _M_construct(_Args&&... __args)
  169. noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
  170. {
  171. ::new ((void *) std::__addressof(this->_M_payload))
  172. _Stored_type(std::forward<_Args>(__args)...);
  173. this->_M_engaged = true;
  174. }
  175. // The _M_get operations have _M_engaged as a precondition.
  176. constexpr _Tp&
  177. _M_get() noexcept
  178. { return this->_M_payload; }
  179. constexpr const _Tp&
  180. _M_get() const noexcept
  181. { return this->_M_payload; }
  182. // _M_reset is a 'safe' operation with no precondition.
  183. constexpr
  184. void
  185. _M_reset() noexcept
  186. {
  187. if (this->_M_engaged)
  188. {
  189. this->_M_engaged = false;
  190. this->_M_payload.~_Stored_type();
  191. }
  192. }
  193. };
  194. // Payload for potentially-constexpr optionals.
  195. template <typename _Tp>
  196. struct _Optional_payload<_Tp, true, true, true>
  197. {
  198. constexpr _Optional_payload() noexcept
  199. : _M_empty(), _M_engaged(false) { }
  200. template<typename... _Args>
  201. constexpr
  202. _Optional_payload(in_place_t, _Args&&... __args)
  203. : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
  204. { }
  205. template<typename _Up, typename... _Args>
  206. constexpr
  207. _Optional_payload(std::initializer_list<_Up> __il,
  208. _Args&&... __args)
  209. : _M_payload(__il, std::forward<_Args>(__args)...),
  210. _M_engaged(true)
  211. { }
  212. constexpr
  213. _Optional_payload(bool __engaged, const _Optional_payload& __other)
  214. : _M_engaged(__engaged)
  215. {
  216. if (__engaged)
  217. _M_construct(__other._M_get());
  218. }
  219. constexpr
  220. _Optional_payload(bool __engaged, _Optional_payload&& __other)
  221. : _M_engaged(__engaged)
  222. {
  223. if (__engaged)
  224. _M_construct(std::move(__other._M_get()));
  225. }
  226. using _Stored_type = remove_const_t<_Tp>;
  227. struct _Empty_byte { };
  228. union {
  229. _Empty_byte _M_empty;
  230. _Stored_type _M_payload;
  231. };
  232. bool _M_engaged;
  233. // The _M_get operations have _M_engaged as a precondition.
  234. constexpr _Tp&
  235. _M_get() noexcept
  236. { return this->_M_payload; }
  237. constexpr const _Tp&
  238. _M_get() const noexcept
  239. { return this->_M_payload; }
  240. };
  241. // Payload for optionals with non-trivial copy assignment.
  242. template <typename _Tp>
  243. struct _Optional_payload<_Tp, true, false, true>
  244. {
  245. constexpr _Optional_payload() noexcept
  246. : _M_empty(), _M_engaged(false) { }
  247. template<typename... _Args>
  248. constexpr
  249. _Optional_payload(in_place_t, _Args&&... __args)
  250. : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
  251. { }
  252. template<typename _Up, typename... _Args>
  253. constexpr
  254. _Optional_payload(std::initializer_list<_Up> __il,
  255. _Args&&... __args)
  256. : _M_payload(__il, std::forward<_Args>(__args)...),
  257. _M_engaged(true)
  258. { }
  259. constexpr
  260. _Optional_payload(bool __engaged, const _Optional_payload& __other)
  261. : _M_engaged(__engaged)
  262. {
  263. if (__engaged)
  264. _M_construct(__other._M_get());
  265. }
  266. constexpr
  267. _Optional_payload(bool __engaged, _Optional_payload&& __other)
  268. : _M_engaged(__engaged)
  269. {
  270. if (__engaged)
  271. _M_construct(std::move(__other._M_get()));
  272. }
  273. _Optional_payload(const _Optional_payload&) = default;
  274. _Optional_payload(_Optional_payload&&) = default;
  275. constexpr
  276. _Optional_payload&
  277. operator=(const _Optional_payload& __other)
  278. {
  279. if (this->_M_engaged && __other._M_engaged)
  280. this->_M_get() = __other._M_get();
  281. else
  282. {
  283. if (__other._M_engaged)
  284. this->_M_construct(__other._M_get());
  285. else
  286. this->_M_reset();
  287. }
  288. return *this;
  289. }
  290. _Optional_payload&
  291. operator=(_Optional_payload&& __other) = default;
  292. using _Stored_type = remove_const_t<_Tp>;
  293. struct _Empty_byte { };
  294. union {
  295. _Empty_byte _M_empty;
  296. _Stored_type _M_payload;
  297. };
  298. bool _M_engaged;
  299. template<typename... _Args>
  300. void
  301. _M_construct(_Args&&... __args)
  302. noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
  303. {
  304. ::new ((void *) std::__addressof(this->_M_payload))
  305. _Stored_type(std::forward<_Args>(__args)...);
  306. this->_M_engaged = true;
  307. }
  308. // The _M_get operations have _M_engaged as a precondition.
  309. constexpr _Tp&
  310. _M_get() noexcept
  311. { return this->_M_payload; }
  312. constexpr const _Tp&
  313. _M_get() const noexcept
  314. { return this->_M_payload; }
  315. // _M_reset is a 'safe' operation with no precondition.
  316. constexpr
  317. void
  318. _M_reset() noexcept
  319. {
  320. if (this->_M_engaged)
  321. {
  322. this->_M_engaged = false;
  323. this->_M_payload.~_Stored_type();
  324. }
  325. }
  326. };
  327. // Payload for optionals with non-trivial move assignment.
  328. template <typename _Tp>
  329. struct _Optional_payload<_Tp, true, true, false>
  330. {
  331. constexpr _Optional_payload() noexcept
  332. : _M_empty(), _M_engaged(false) { }
  333. template<typename... _Args>
  334. constexpr
  335. _Optional_payload(in_place_t, _Args&&... __args)
  336. : _M_payload(std::forward<_Args>(__args)...),
  337. _M_engaged(true)
  338. { }
  339. template<typename _Up, typename... _Args>
  340. constexpr
  341. _Optional_payload(std::initializer_list<_Up> __il,
  342. _Args&&... __args)
  343. : _M_payload(__il, std::forward<_Args>(__args)...),
  344. _M_engaged(true)
  345. { }
  346. constexpr
  347. _Optional_payload(bool __engaged, const _Optional_payload& __other)
  348. : _M_engaged(__engaged)
  349. {
  350. if (__engaged)
  351. _M_construct(__other._M_get());
  352. }
  353. constexpr
  354. _Optional_payload(bool __engaged, _Optional_payload&& __other)
  355. : _M_engaged(__engaged)
  356. {
  357. if (__engaged)
  358. _M_construct(std::move(__other._M_get()));
  359. }
  360. _Optional_payload(const _Optional_payload&) = default;
  361. _Optional_payload(_Optional_payload&&) = default;
  362. _Optional_payload&
  363. operator=(const _Optional_payload& __other) = default;
  364. constexpr
  365. _Optional_payload&
  366. operator=(_Optional_payload&& __other)
  367. noexcept(__and_<is_nothrow_move_constructible<_Tp>,
  368. is_nothrow_move_assignable<_Tp>>())
  369. {
  370. if (this->_M_engaged && __other._M_engaged)
  371. this->_M_get() = std::move(__other._M_get());
  372. else
  373. {
  374. if (__other._M_engaged)
  375. this->_M_construct(std::move(__other._M_get()));
  376. else
  377. this->_M_reset();
  378. }
  379. return *this;
  380. }
  381. using _Stored_type = remove_const_t<_Tp>;
  382. struct _Empty_byte { };
  383. union {
  384. _Empty_byte _M_empty;
  385. _Stored_type _M_payload;
  386. };
  387. bool _M_engaged;
  388. template<typename... _Args>
  389. void
  390. _M_construct(_Args&&... __args)
  391. noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
  392. {
  393. ::new ((void *) std::__addressof(this->_M_payload))
  394. _Stored_type(std::forward<_Args>(__args)...);
  395. this->_M_engaged = true;
  396. }
  397. // The _M_get operations have _M_engaged as a precondition.
  398. constexpr _Tp&
  399. _M_get() noexcept
  400. { return this->_M_payload; }
  401. constexpr const _Tp&
  402. _M_get() const noexcept
  403. { return this->_M_payload; }
  404. // _M_reset is a 'safe' operation with no precondition.
  405. constexpr
  406. void
  407. _M_reset() noexcept
  408. {
  409. if (this->_M_engaged)
  410. {
  411. this->_M_engaged = false;
  412. this->_M_payload.~_Stored_type();
  413. }
  414. }
  415. };
  416. // Payload for optionals with non-trivial copy and move assignment.
  417. template <typename _Tp>
  418. struct _Optional_payload<_Tp, true, false, false>
  419. {
  420. constexpr _Optional_payload() noexcept
  421. : _M_empty(), _M_engaged(false) {}
  422. template<typename... _Args>
  423. constexpr
  424. _Optional_payload(in_place_t, _Args&&... __args)
  425. : _M_payload(std::forward<_Args>(__args)...),
  426. _M_engaged(true)
  427. { }
  428. template<typename _Up, typename... _Args>
  429. constexpr
  430. _Optional_payload(std::initializer_list<_Up> __il,
  431. _Args&&... __args)
  432. : _M_payload(__il, std::forward<_Args>(__args)...),
  433. _M_engaged(true)
  434. { }
  435. constexpr
  436. _Optional_payload(bool __engaged, const _Optional_payload& __other)
  437. : _M_engaged(__engaged)
  438. {
  439. if (__engaged)
  440. _M_construct(__other._M_get());
  441. }
  442. constexpr
  443. _Optional_payload(bool __engaged, _Optional_payload&& __other)
  444. : _M_engaged(__engaged)
  445. {
  446. if (__engaged)
  447. _M_construct(std::move(__other._M_get()));
  448. }
  449. _Optional_payload(const _Optional_payload&) = default;
  450. _Optional_payload(_Optional_payload&&) = default;
  451. constexpr
  452. _Optional_payload&
  453. operator=(const _Optional_payload& __other)
  454. {
  455. if (this->_M_engaged && __other._M_engaged)
  456. this->_M_get() = __other._M_get();
  457. else
  458. {
  459. if (__other._M_engaged)
  460. this->_M_construct(__other._M_get());
  461. else
  462. this->_M_reset();
  463. }
  464. return *this;
  465. }
  466. constexpr
  467. _Optional_payload&
  468. operator=(_Optional_payload&& __other)
  469. noexcept(__and_<is_nothrow_move_constructible<_Tp>,
  470. is_nothrow_move_assignable<_Tp>>())
  471. {
  472. if (this->_M_engaged && __other._M_engaged)
  473. this->_M_get() = std::move(__other._M_get());
  474. else
  475. {
  476. if (__other._M_engaged)
  477. this->_M_construct(std::move(__other._M_get()));
  478. else
  479. this->_M_reset();
  480. }
  481. return *this;
  482. }
  483. using _Stored_type = remove_const_t<_Tp>;
  484. struct _Empty_byte { };
  485. union {
  486. _Empty_byte _M_empty;
  487. _Stored_type _M_payload;
  488. };
  489. bool _M_engaged;
  490. template<typename... _Args>
  491. void
  492. _M_construct(_Args&&... __args)
  493. noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
  494. {
  495. ::new ((void *) std::__addressof(this->_M_payload))
  496. _Stored_type(std::forward<_Args>(__args)...);
  497. this->_M_engaged = true;
  498. }
  499. // The _M_get operations have _M_engaged as a precondition.
  500. constexpr _Tp&
  501. _M_get() noexcept
  502. { return this->_M_payload; }
  503. constexpr const _Tp&
  504. _M_get() const noexcept
  505. { return this->_M_payload; }
  506. // _M_reset is a 'safe' operation with no precondition.
  507. constexpr
  508. void
  509. _M_reset() noexcept
  510. {
  511. if (this->_M_engaged)
  512. {
  513. this->_M_engaged = false;
  514. this->_M_payload.~_Stored_type();
  515. }
  516. }
  517. };
  518. template<typename _Tp, typename _Dp>
  519. class _Optional_base_impl
  520. {
  521. protected:
  522. using _Stored_type = remove_const_t<_Tp>;
  523. // The _M_construct operation has !_M_engaged as a precondition
  524. // while _M_destruct has _M_engaged as a precondition.
  525. template<typename... _Args>
  526. void
  527. _M_construct(_Args&&... __args)
  528. noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
  529. {
  530. ::new
  531. (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
  532. _Stored_type(std::forward<_Args>(__args)...);
  533. static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
  534. }
  535. void
  536. _M_destruct() noexcept
  537. {
  538. static_cast<_Dp*>(this)->_M_payload._M_engaged = false;
  539. static_cast<_Dp*>(this)->_M_payload._M_payload.~_Stored_type();
  540. }
  541. // _M_reset is a 'safe' operation with no precondition.
  542. constexpr
  543. void
  544. _M_reset() noexcept
  545. {
  546. if (static_cast<_Dp*>(this)->_M_payload._M_engaged)
  547. static_cast<_Dp*>(this)->_M_destruct();
  548. }
  549. };
  550. /**
  551. * @brief Class template that takes care of copy/move constructors
  552. of optional
  553. *
  554. * Such a separate base class template is necessary in order to
  555. * conditionally make copy/move constructors trivial.
  556. * @see optional, _Enable_special_members
  557. */
  558. template<typename _Tp,
  559. bool = is_trivially_copy_constructible_v<_Tp>,
  560. bool = is_trivially_move_constructible_v<_Tp>>
  561. class _Optional_base
  562. // protected inheritance because optional needs to reach that base too
  563. : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  564. {
  565. friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
  566. public:
  567. // Constructors for disengaged optionals.
  568. constexpr _Optional_base() = default;
  569. // Constructors for engaged optionals.
  570. template<typename... _Args,
  571. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  572. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  573. : _M_payload(in_place,
  574. std::forward<_Args>(__args)...) { }
  575. template<typename _Up, typename... _Args,
  576. enable_if_t<is_constructible_v<_Tp,
  577. initializer_list<_Up>&,
  578. _Args&&...>, bool> = false>
  579. constexpr explicit _Optional_base(in_place_t,
  580. initializer_list<_Up> __il,
  581. _Args&&... __args)
  582. : _M_payload(in_place,
  583. __il, std::forward<_Args>(__args)...)
  584. { }
  585. // Copy and move constructors.
  586. constexpr _Optional_base(const _Optional_base& __other)
  587. : _M_payload(__other._M_payload._M_engaged,
  588. __other._M_payload)
  589. { }
  590. constexpr _Optional_base(_Optional_base&& __other)
  591. noexcept(is_nothrow_move_constructible<_Tp>())
  592. : _M_payload(__other._M_payload._M_engaged,
  593. std::move(__other._M_payload))
  594. { }
  595. // Assignment operators.
  596. _Optional_base& operator=(const _Optional_base&) = default;
  597. _Optional_base& operator=(_Optional_base&&) = default;
  598. protected:
  599. constexpr bool _M_is_engaged() const noexcept
  600. { return this->_M_payload._M_engaged; }
  601. // The _M_get operations have _M_engaged as a precondition.
  602. constexpr _Tp&
  603. _M_get() noexcept
  604. {
  605. __glibcxx_assert(this->_M_is_engaged());
  606. return this->_M_payload._M_payload;
  607. }
  608. constexpr const _Tp&
  609. _M_get() const noexcept
  610. {
  611. __glibcxx_assert(this->_M_is_engaged());
  612. return this->_M_payload._M_payload;
  613. }
  614. private:
  615. _Optional_payload<_Tp> _M_payload;
  616. };
  617. template<typename _Tp>
  618. class _Optional_base<_Tp, false, true>
  619. : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  620. {
  621. friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
  622. public:
  623. // Constructors for disengaged optionals.
  624. constexpr _Optional_base() = default;
  625. // Constructors for engaged optionals.
  626. template<typename... _Args,
  627. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  628. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  629. : _M_payload(in_place,
  630. std::forward<_Args>(__args)...) { }
  631. template<typename _Up, typename... _Args,
  632. enable_if_t<is_constructible_v<_Tp,
  633. initializer_list<_Up>&,
  634. _Args&&...>, bool> = false>
  635. constexpr explicit _Optional_base(in_place_t,
  636. initializer_list<_Up> __il,
  637. _Args&&... __args)
  638. : _M_payload(in_place,
  639. __il, std::forward<_Args>(__args)...)
  640. { }
  641. // Copy and move constructors.
  642. constexpr _Optional_base(const _Optional_base& __other)
  643. : _M_payload(__other._M_payload._M_engaged,
  644. __other._M_payload)
  645. { }
  646. constexpr _Optional_base(_Optional_base&& __other) = default;
  647. // Assignment operators.
  648. _Optional_base& operator=(const _Optional_base&) = default;
  649. _Optional_base& operator=(_Optional_base&&) = default;
  650. protected:
  651. constexpr bool _M_is_engaged() const noexcept
  652. { return this->_M_payload._M_engaged; }
  653. // The _M_get operations have _M_engaged as a precondition.
  654. constexpr _Tp&
  655. _M_get() noexcept
  656. {
  657. __glibcxx_assert(this->_M_is_engaged());
  658. return this->_M_payload._M_payload;
  659. }
  660. constexpr const _Tp&
  661. _M_get() const noexcept
  662. {
  663. __glibcxx_assert(this->_M_is_engaged());
  664. return this->_M_payload._M_payload;
  665. }
  666. private:
  667. _Optional_payload<_Tp> _M_payload;
  668. };
  669. template<typename _Tp>
  670. class _Optional_base<_Tp, true, false>
  671. : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  672. {
  673. friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
  674. public:
  675. // Constructors for disengaged optionals.
  676. constexpr _Optional_base() = default;
  677. // Constructors for engaged optionals.
  678. template<typename... _Args,
  679. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  680. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  681. : _M_payload(in_place,
  682. std::forward<_Args>(__args)...) { }
  683. template<typename _Up, typename... _Args,
  684. enable_if_t<is_constructible_v<_Tp,
  685. initializer_list<_Up>&,
  686. _Args&&...>, bool> = false>
  687. constexpr explicit _Optional_base(in_place_t,
  688. initializer_list<_Up> __il,
  689. _Args&&... __args)
  690. : _M_payload(in_place,
  691. __il, std::forward<_Args>(__args)...)
  692. { }
  693. // Copy and move constructors.
  694. constexpr _Optional_base(const _Optional_base& __other) = default;
  695. constexpr _Optional_base(_Optional_base&& __other)
  696. noexcept(is_nothrow_move_constructible<_Tp>())
  697. : _M_payload(__other._M_payload._M_engaged,
  698. std::move(__other._M_payload))
  699. { }
  700. // Assignment operators.
  701. _Optional_base& operator=(const _Optional_base&) = default;
  702. _Optional_base& operator=(_Optional_base&&) = default;
  703. protected:
  704. constexpr bool _M_is_engaged() const noexcept
  705. { return this->_M_payload._M_engaged; }
  706. // The _M_get operations have _M_engaged as a precondition.
  707. constexpr _Tp&
  708. _M_get() noexcept
  709. {
  710. __glibcxx_assert(this->_M_is_engaged());
  711. return this->_M_payload._M_payload;
  712. }
  713. constexpr const _Tp&
  714. _M_get() const noexcept
  715. {
  716. __glibcxx_assert(this->_M_is_engaged());
  717. return this->_M_payload._M_payload;
  718. }
  719. private:
  720. _Optional_payload<_Tp> _M_payload;
  721. };
  722. template<typename _Tp>
  723. class _Optional_base<_Tp, true, true>
  724. : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  725. {
  726. friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
  727. public:
  728. // Constructors for disengaged optionals.
  729. constexpr _Optional_base() = default;
  730. // Constructors for engaged optionals.
  731. template<typename... _Args,
  732. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  733. constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
  734. : _M_payload(in_place,
  735. std::forward<_Args>(__args)...) { }
  736. template<typename _Up, typename... _Args,
  737. enable_if_t<is_constructible_v<_Tp,
  738. initializer_list<_Up>&,
  739. _Args&&...>, bool> = false>
  740. constexpr explicit _Optional_base(in_place_t,
  741. initializer_list<_Up> __il,
  742. _Args&&... __args)
  743. : _M_payload(in_place,
  744. __il, std::forward<_Args>(__args)...)
  745. { }
  746. // Copy and move constructors.
  747. constexpr _Optional_base(const _Optional_base& __other) = default;
  748. constexpr _Optional_base(_Optional_base&& __other) = default;
  749. // Assignment operators.
  750. _Optional_base& operator=(const _Optional_base&) = default;
  751. _Optional_base& operator=(_Optional_base&&) = default;
  752. protected:
  753. constexpr bool _M_is_engaged() const noexcept
  754. { return this->_M_payload._M_engaged; }
  755. // The _M_get operations have _M_engaged as a precondition.
  756. constexpr _Tp&
  757. _M_get() noexcept
  758. {
  759. __glibcxx_assert(this->_M_is_engaged());
  760. return this->_M_payload._M_payload;
  761. }
  762. constexpr const _Tp&
  763. _M_get() const noexcept
  764. {
  765. __glibcxx_assert(this->_M_is_engaged());
  766. return this->_M_payload._M_payload;
  767. }
  768. private:
  769. _Optional_payload<_Tp> _M_payload;
  770. };
  771. template<typename _Tp>
  772. class optional;
  773. template<typename _Tp, typename _Up>
  774. using __converts_from_optional =
  775. __or_<is_constructible<_Tp, const optional<_Up>&>,
  776. is_constructible<_Tp, optional<_Up>&>,
  777. is_constructible<_Tp, const optional<_Up>&&>,
  778. is_constructible<_Tp, optional<_Up>&&>,
  779. is_convertible<const optional<_Up>&, _Tp>,
  780. is_convertible<optional<_Up>&, _Tp>,
  781. is_convertible<const optional<_Up>&&, _Tp>,
  782. is_convertible<optional<_Up>&&, _Tp>>;
  783. template<typename _Tp, typename _Up>
  784. using __assigns_from_optional =
  785. __or_<is_assignable<_Tp&, const optional<_Up>&>,
  786. is_assignable<_Tp&, optional<_Up>&>,
  787. is_assignable<_Tp&, const optional<_Up>&&>,
  788. is_assignable<_Tp&, optional<_Up>&&>>;
  789. /**
  790. * @brief Class template for optional values.
  791. */
  792. template<typename _Tp>
  793. class optional
  794. : private _Optional_base<_Tp>,
  795. private _Enable_copy_move<
  796. // Copy constructor.
  797. is_copy_constructible<_Tp>::value,
  798. // Copy assignment.
  799. __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
  800. // Move constructor.
  801. is_move_constructible<_Tp>::value,
  802. // Move assignment.
  803. __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
  804. // Unique tag type.
  805. optional<_Tp>>
  806. {
  807. static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
  808. static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
  809. static_assert(!is_reference_v<_Tp>);
  810. private:
  811. using _Base = _Optional_base<_Tp>;
  812. public:
  813. using value_type = _Tp;
  814. constexpr optional() = default;
  815. constexpr optional(nullopt_t) noexcept { }
  816. // Converting constructors for engaged optionals.
  817. template <typename _Up = _Tp,
  818. enable_if_t<__and_<
  819. __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
  820. __not_<is_same<in_place_t, decay_t<_Up>>>,
  821. is_constructible<_Tp, _Up&&>,
  822. is_convertible<_Up&&, _Tp>
  823. >::value, bool> = true>
  824. constexpr optional(_Up&& __t)
  825. : _Base(std::in_place, std::forward<_Up>(__t)) { }
  826. template <typename _Up = _Tp,
  827. enable_if_t<__and_<
  828. __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
  829. __not_<is_same<in_place_t, decay_t<_Up>>>,
  830. is_constructible<_Tp, _Up&&>,
  831. __not_<is_convertible<_Up&&, _Tp>>
  832. >::value, bool> = false>
  833. explicit constexpr optional(_Up&& __t)
  834. : _Base(std::in_place, std::forward<_Up>(__t)) { }
  835. template <typename _Up,
  836. enable_if_t<__and_<
  837. __not_<is_same<_Tp, _Up>>,
  838. is_constructible<_Tp, const _Up&>,
  839. is_convertible<const _Up&, _Tp>,
  840. __not_<__converts_from_optional<_Tp, _Up>>
  841. >::value, bool> = true>
  842. constexpr optional(const optional<_Up>& __t)
  843. {
  844. if (__t)
  845. emplace(*__t);
  846. }
  847. template <typename _Up,
  848. enable_if_t<__and_<
  849. __not_<is_same<_Tp, _Up>>,
  850. is_constructible<_Tp, const _Up&>,
  851. __not_<is_convertible<const _Up&, _Tp>>,
  852. __not_<__converts_from_optional<_Tp, _Up>>
  853. >::value, bool> = false>
  854. explicit constexpr optional(const optional<_Up>& __t)
  855. {
  856. if (__t)
  857. emplace(*__t);
  858. }
  859. template <typename _Up,
  860. enable_if_t<__and_<
  861. __not_<is_same<_Tp, _Up>>,
  862. is_constructible<_Tp, _Up&&>,
  863. is_convertible<_Up&&, _Tp>,
  864. __not_<__converts_from_optional<_Tp, _Up>>
  865. >::value, bool> = true>
  866. constexpr optional(optional<_Up>&& __t)
  867. {
  868. if (__t)
  869. emplace(std::move(*__t));
  870. }
  871. template <typename _Up,
  872. enable_if_t<__and_<
  873. __not_<is_same<_Tp, _Up>>,
  874. is_constructible<_Tp, _Up&&>,
  875. __not_<is_convertible<_Up&&, _Tp>>,
  876. __not_<__converts_from_optional<_Tp, _Up>>
  877. >::value, bool> = false>
  878. explicit constexpr optional(optional<_Up>&& __t)
  879. {
  880. if (__t)
  881. emplace(std::move(*__t));
  882. }
  883. template<typename... _Args,
  884. enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
  885. explicit constexpr optional(in_place_t, _Args&&... __args)
  886. : _Base(std::in_place, std::forward<_Args>(__args)...) { }
  887. template<typename _Up, typename... _Args,
  888. enable_if_t<is_constructible_v<_Tp,
  889. initializer_list<_Up>&,
  890. _Args&&...>, bool> = false>
  891. explicit constexpr optional(in_place_t,
  892. initializer_list<_Up> __il,
  893. _Args&&... __args)
  894. : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
  895. // Assignment operators.
  896. optional&
  897. operator=(nullopt_t) noexcept
  898. {
  899. this->_M_reset();
  900. return *this;
  901. }
  902. template<typename _Up = _Tp>
  903. enable_if_t<__and_<
  904. __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
  905. is_constructible<_Tp, _Up>,
  906. __not_<__and_<is_scalar<_Tp>,
  907. is_same<_Tp, decay_t<_Up>>>>,
  908. is_assignable<_Tp&, _Up>>::value,
  909. optional&>
  910. operator=(_Up&& __u)
  911. {
  912. if (this->_M_is_engaged())
  913. this->_M_get() = std::forward<_Up>(__u);
  914. else
  915. this->_M_construct(std::forward<_Up>(__u));
  916. return *this;
  917. }
  918. template<typename _Up>
  919. enable_if_t<__and_<
  920. __not_<is_same<_Tp, _Up>>,
  921. is_constructible<_Tp, const _Up&>,
  922. is_assignable<_Tp&, _Up>,
  923. __not_<__converts_from_optional<_Tp, _Up>>,
  924. __not_<__assigns_from_optional<_Tp, _Up>>
  925. >::value,
  926. optional&>
  927. operator=(const optional<_Up>& __u)
  928. {
  929. if (__u)
  930. {
  931. if (this->_M_is_engaged())
  932. this->_M_get() = *__u;
  933. else
  934. this->_M_construct(*__u);
  935. }
  936. else
  937. {
  938. this->_M_reset();
  939. }
  940. return *this;
  941. }
  942. template<typename _Up>
  943. enable_if_t<__and_<
  944. __not_<is_same<_Tp, _Up>>,
  945. is_constructible<_Tp, _Up>,
  946. is_assignable<_Tp&, _Up>,
  947. __not_<__converts_from_optional<_Tp, _Up>>,
  948. __not_<__assigns_from_optional<_Tp, _Up>>
  949. >::value,
  950. optional&>
  951. operator=(optional<_Up>&& __u)
  952. {
  953. if (__u)
  954. {
  955. if (this->_M_is_engaged())
  956. this->_M_get() = std::move(*__u);
  957. else
  958. this->_M_construct(std::move(*__u));
  959. }
  960. else
  961. {
  962. this->_M_reset();
  963. }
  964. return *this;
  965. }
  966. template<typename... _Args>
  967. enable_if_t<is_constructible<_Tp, _Args&&...>::value, _Tp&>
  968. emplace(_Args&&... __args)
  969. {
  970. this->_M_reset();
  971. this->_M_construct(std::forward<_Args>(__args)...);
  972. return this->_M_get();
  973. }
  974. template<typename _Up, typename... _Args>
  975. enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
  976. _Args&&...>::value, _Tp&>
  977. emplace(initializer_list<_Up> __il, _Args&&... __args)
  978. {
  979. this->_M_reset();
  980. this->_M_construct(__il, std::forward<_Args>(__args)...);
  981. return this->_M_get();
  982. }
  983. // Destructor is implicit, implemented in _Optional_base.
  984. // Swap.
  985. void
  986. swap(optional& __other)
  987. noexcept(is_nothrow_move_constructible<_Tp>()
  988. && is_nothrow_swappable_v<_Tp>)
  989. {
  990. using std::swap;
  991. if (this->_M_is_engaged() && __other._M_is_engaged())
  992. swap(this->_M_get(), __other._M_get());
  993. else if (this->_M_is_engaged())
  994. {
  995. __other._M_construct(std::move(this->_M_get()));
  996. this->_M_destruct();
  997. }
  998. else if (__other._M_is_engaged())
  999. {
  1000. this->_M_construct(std::move(__other._M_get()));
  1001. __other._M_destruct();
  1002. }
  1003. }
  1004. // Observers.
  1005. constexpr const _Tp*
  1006. operator->() const
  1007. { return std::__addressof(this->_M_get()); }
  1008. constexpr
  1009. _Tp*
  1010. operator->()
  1011. { return std::__addressof(this->_M_get()); }
  1012. constexpr const _Tp&
  1013. operator*() const&
  1014. { return this->_M_get(); }
  1015. constexpr _Tp&
  1016. operator*()&
  1017. { return this->_M_get(); }
  1018. constexpr _Tp&&
  1019. operator*()&&
  1020. { return std::move(this->_M_get()); }
  1021. constexpr const _Tp&&
  1022. operator*() const&&
  1023. { return std::move(this->_M_get()); }
  1024. constexpr explicit operator bool() const noexcept
  1025. { return this->_M_is_engaged(); }
  1026. constexpr bool has_value() const noexcept
  1027. { return this->_M_is_engaged(); }
  1028. constexpr const _Tp&
  1029. value() const&
  1030. {
  1031. return this->_M_is_engaged()
  1032. ? this->_M_get()
  1033. : (__throw_bad_optional_access(),
  1034. this->_M_get());
  1035. }
  1036. constexpr _Tp&
  1037. value()&
  1038. {
  1039. return this->_M_is_engaged()
  1040. ? this->_M_get()
  1041. : (__throw_bad_optional_access(),
  1042. this->_M_get());
  1043. }
  1044. constexpr _Tp&&
  1045. value()&&
  1046. {
  1047. return this->_M_is_engaged()
  1048. ? std::move(this->_M_get())
  1049. : (__throw_bad_optional_access(),
  1050. std::move(this->_M_get()));
  1051. }
  1052. constexpr const _Tp&&
  1053. value() const&&
  1054. {
  1055. return this->_M_is_engaged()
  1056. ? std::move(this->_M_get())
  1057. : (__throw_bad_optional_access(),
  1058. std::move(this->_M_get()));
  1059. }
  1060. template<typename _Up>
  1061. constexpr _Tp
  1062. value_or(_Up&& __u) const&
  1063. {
  1064. static_assert(is_copy_constructible_v<_Tp>);
  1065. static_assert(is_convertible_v<_Up&&, _Tp>);
  1066. return this->_M_is_engaged()
  1067. ? this->_M_get()
  1068. : static_cast<_Tp>(std::forward<_Up>(__u));
  1069. }
  1070. template<typename _Up>
  1071. _Tp
  1072. value_or(_Up&& __u) &&
  1073. {
  1074. static_assert(is_move_constructible_v<_Tp>);
  1075. static_assert(is_convertible_v<_Up&&, _Tp>);
  1076. return this->_M_is_engaged()
  1077. ? std::move(this->_M_get())
  1078. : static_cast<_Tp>(std::forward<_Up>(__u));
  1079. }
  1080. void reset() noexcept { this->_M_reset(); }
  1081. };
  1082. template<typename _Tp>
  1083. using __optional_relop_t =
  1084. enable_if_t<is_convertible<_Tp, bool>::value, bool>;
  1085. // Comparisons between optional values.
  1086. template<typename _Tp, typename _Up>
  1087. constexpr auto
  1088. operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1089. -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
  1090. {
  1091. return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
  1092. && (!__lhs || *__lhs == *__rhs);
  1093. }
  1094. template<typename _Tp, typename _Up>
  1095. constexpr auto
  1096. operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1097. -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
  1098. {
  1099. return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
  1100. || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
  1101. }
  1102. template<typename _Tp, typename _Up>
  1103. constexpr auto
  1104. operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1105. -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
  1106. {
  1107. return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
  1108. }
  1109. template<typename _Tp, typename _Up>
  1110. constexpr auto
  1111. operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1112. -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
  1113. {
  1114. return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
  1115. }
  1116. template<typename _Tp, typename _Up>
  1117. constexpr auto
  1118. operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1119. -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
  1120. {
  1121. return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
  1122. }
  1123. template<typename _Tp, typename _Up>
  1124. constexpr auto
  1125. operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1126. -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
  1127. {
  1128. return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
  1129. }
  1130. // Comparisons with nullopt.
  1131. template<typename _Tp>
  1132. constexpr bool
  1133. operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1134. { return !__lhs; }
  1135. template<typename _Tp>
  1136. constexpr bool
  1137. operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1138. { return !__rhs; }
  1139. template<typename _Tp>
  1140. constexpr bool
  1141. operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1142. { return static_cast<bool>(__lhs); }
  1143. template<typename _Tp>
  1144. constexpr bool
  1145. operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1146. { return static_cast<bool>(__rhs); }
  1147. template<typename _Tp>
  1148. constexpr bool
  1149. operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
  1150. { return false; }
  1151. template<typename _Tp>
  1152. constexpr bool
  1153. operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1154. { return static_cast<bool>(__rhs); }
  1155. template<typename _Tp>
  1156. constexpr bool
  1157. operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1158. { return static_cast<bool>(__lhs); }
  1159. template<typename _Tp>
  1160. constexpr bool
  1161. operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
  1162. { return false; }
  1163. template<typename _Tp>
  1164. constexpr bool
  1165. operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1166. { return !__lhs; }
  1167. template<typename _Tp>
  1168. constexpr bool
  1169. operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
  1170. { return true; }
  1171. template<typename _Tp>
  1172. constexpr bool
  1173. operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
  1174. { return true; }
  1175. template<typename _Tp>
  1176. constexpr bool
  1177. operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1178. { return !__rhs; }
  1179. // Comparisons with value type.
  1180. template<typename _Tp, typename _Up>
  1181. constexpr auto
  1182. operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
  1183. -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
  1184. { return __lhs && *__lhs == __rhs; }
  1185. template<typename _Tp, typename _Up>
  1186. constexpr auto
  1187. operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
  1188. -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
  1189. { return __rhs && __lhs == *__rhs; }
  1190. template<typename _Tp, typename _Up>
  1191. constexpr auto
  1192. operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
  1193. -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
  1194. { return !__lhs || *__lhs != __rhs; }
  1195. template<typename _Tp, typename _Up>
  1196. constexpr auto
  1197. operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
  1198. -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
  1199. { return !__rhs || __lhs != *__rhs; }
  1200. template<typename _Tp, typename _Up>
  1201. constexpr auto
  1202. operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
  1203. -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
  1204. { return !__lhs || *__lhs < __rhs; }
  1205. template<typename _Tp, typename _Up>
  1206. constexpr auto
  1207. operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
  1208. -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
  1209. { return __rhs && __lhs < *__rhs; }
  1210. template<typename _Tp, typename _Up>
  1211. constexpr auto
  1212. operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
  1213. -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
  1214. { return __lhs && *__lhs > __rhs; }
  1215. template<typename _Tp, typename _Up>
  1216. constexpr auto
  1217. operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
  1218. -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
  1219. { return !__rhs || __lhs > *__rhs; }
  1220. template<typename _Tp, typename _Up>
  1221. constexpr auto
  1222. operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
  1223. -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
  1224. { return !__lhs || *__lhs <= __rhs; }
  1225. template<typename _Tp, typename _Up>
  1226. constexpr auto
  1227. operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
  1228. -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
  1229. { return __rhs && __lhs <= *__rhs; }
  1230. template<typename _Tp, typename _Up>
  1231. constexpr auto
  1232. operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
  1233. -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
  1234. { return __lhs && *__lhs >= __rhs; }
  1235. template<typename _Tp, typename _Up>
  1236. constexpr auto
  1237. operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
  1238. -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
  1239. { return !__rhs || __lhs >= *__rhs; }
  1240. // Swap and creation functions.
  1241. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1242. // 2748. swappable traits for optionals
  1243. template<typename _Tp>
  1244. inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
  1245. swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
  1246. noexcept(noexcept(__lhs.swap(__rhs)))
  1247. { __lhs.swap(__rhs); }
  1248. template<typename _Tp>
  1249. enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
  1250. swap(optional<_Tp>&, optional<_Tp>&) = delete;
  1251. template<typename _Tp>
  1252. constexpr optional<decay_t<_Tp>>
  1253. make_optional(_Tp&& __t)
  1254. { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
  1255. template<typename _Tp, typename ..._Args>
  1256. constexpr optional<_Tp>
  1257. make_optional(_Args&&... __args)
  1258. { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
  1259. template<typename _Tp, typename _Up, typename ..._Args>
  1260. constexpr optional<_Tp>
  1261. make_optional(initializer_list<_Up> __il, _Args&&... __args)
  1262. { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
  1263. // Hash.
  1264. template<typename _Tp, typename _Up = remove_const_t<_Tp>,
  1265. bool = __poison_hash<_Up>::__enable_hash_call>
  1266. struct __optional_hash_call_base
  1267. {
  1268. size_t
  1269. operator()(const optional<_Tp>& __t) const
  1270. noexcept(noexcept(hash<_Up>{}(*__t)))
  1271. {
  1272. // We pick an arbitrary hash for disengaged optionals which hopefully
  1273. // usual values of _Tp won't typically hash to.
  1274. constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
  1275. return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
  1276. }
  1277. };
  1278. template<typename _Tp, typename _Up>
  1279. struct __optional_hash_call_base<_Tp, _Up, false> {};
  1280. template<typename _Tp>
  1281. struct hash<optional<_Tp>>
  1282. : private __poison_hash<remove_const_t<_Tp>>,
  1283. public __optional_hash_call_base<_Tp>
  1284. {
  1285. using result_type [[__deprecated__]] = size_t;
  1286. using argument_type [[__deprecated__]] = optional<_Tp>;
  1287. };
  1288. template<typename _Tp>
  1289. struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
  1290. { };
  1291. /// @}
  1292. #if __cpp_deduction_guides >= 201606
  1293. template <typename _Tp> optional(_Tp) -> optional<_Tp>;
  1294. #endif
  1295. _GLIBCXX_END_NAMESPACE_VERSION
  1296. } // namespace std
  1297. #endif // C++17
  1298. #endif // _GLIBCXX_OPTIONAL