optional 43 KB

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