optional 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526
  1. // <optional> -*- C++ -*-
  2. // Copyright (C) 2013-2023 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. else // This seems redundant but improves codegen, see PR 112480.
  266. this->_M_engaged = false;
  267. }
  268. };
  269. // Class template that manages the payload for optionals.
  270. template <typename _Tp,
  271. bool /*_HasTrivialDestructor*/ =
  272. is_trivially_destructible_v<_Tp>,
  273. bool /*_HasTrivialCopy */ =
  274. is_trivially_copy_assignable_v<_Tp>
  275. && is_trivially_copy_constructible_v<_Tp>,
  276. bool /*_HasTrivialMove */ =
  277. is_trivially_move_assignable_v<_Tp>
  278. && is_trivially_move_constructible_v<_Tp>>
  279. struct _Optional_payload;
  280. // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
  281. template <typename _Tp>
  282. struct _Optional_payload<_Tp, true, true, true>
  283. : _Optional_payload_base<_Tp>
  284. {
  285. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  286. _Optional_payload() = default;
  287. };
  288. // Payload for optionals with non-trivial copy construction/assignment.
  289. template <typename _Tp>
  290. struct _Optional_payload<_Tp, true, false, true>
  291. : _Optional_payload_base<_Tp>
  292. {
  293. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  294. _Optional_payload() = default;
  295. ~_Optional_payload() = default;
  296. _Optional_payload(const _Optional_payload&) = default;
  297. _Optional_payload(_Optional_payload&&) = default;
  298. _Optional_payload& operator=(_Optional_payload&&) = default;
  299. // Non-trivial copy assignment.
  300. constexpr
  301. _Optional_payload&
  302. operator=(const _Optional_payload& __other)
  303. {
  304. this->_M_copy_assign(__other);
  305. return *this;
  306. }
  307. };
  308. // Payload for optionals with non-trivial move construction/assignment.
  309. template <typename _Tp>
  310. struct _Optional_payload<_Tp, true, true, false>
  311. : _Optional_payload_base<_Tp>
  312. {
  313. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  314. _Optional_payload() = default;
  315. ~_Optional_payload() = default;
  316. _Optional_payload(const _Optional_payload&) = default;
  317. _Optional_payload(_Optional_payload&&) = default;
  318. _Optional_payload& operator=(const _Optional_payload&) = default;
  319. // Non-trivial move assignment.
  320. constexpr
  321. _Optional_payload&
  322. operator=(_Optional_payload&& __other)
  323. noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
  324. is_nothrow_move_assignable<_Tp>>)
  325. {
  326. this->_M_move_assign(std::move(__other));
  327. return *this;
  328. }
  329. };
  330. // Payload for optionals with non-trivial copy and move assignment.
  331. template <typename _Tp>
  332. struct _Optional_payload<_Tp, true, false, false>
  333. : _Optional_payload_base<_Tp>
  334. {
  335. using _Optional_payload_base<_Tp>::_Optional_payload_base;
  336. _Optional_payload() = default;
  337. ~_Optional_payload() = default;
  338. _Optional_payload(const _Optional_payload&) = default;
  339. _Optional_payload(_Optional_payload&&) = default;
  340. // Non-trivial copy assignment.
  341. constexpr
  342. _Optional_payload&
  343. operator=(const _Optional_payload& __other)
  344. {
  345. this->_M_copy_assign(__other);
  346. return *this;
  347. }
  348. // Non-trivial move assignment.
  349. constexpr
  350. _Optional_payload&
  351. operator=(_Optional_payload&& __other)
  352. noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
  353. is_nothrow_move_assignable<_Tp>>)
  354. {
  355. this->_M_move_assign(std::move(__other));
  356. return *this;
  357. }
  358. };
  359. // Payload for optionals with non-trivial destructors.
  360. template <typename _Tp, bool _Copy, bool _Move>
  361. struct _Optional_payload<_Tp, false, _Copy, _Move>
  362. : _Optional_payload<_Tp, true, false, false>
  363. {
  364. // Base class implements all the constructors and assignment operators:
  365. using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
  366. _Optional_payload() = default;
  367. _Optional_payload(const _Optional_payload&) = default;
  368. _Optional_payload(_Optional_payload&&) = default;
  369. _Optional_payload& operator=(const _Optional_payload&) = default;
  370. _Optional_payload& operator=(_Optional_payload&&) = default;
  371. // Destructor needs to destroy the contained value:
  372. _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); }
  373. };
  374. // Common base class for _Optional_base<T> to avoid repeating these
  375. // member functions in each specialization.
  376. template<typename _Tp, typename _Dp>
  377. class _Optional_base_impl
  378. {
  379. protected:
  380. using _Stored_type = remove_const_t<_Tp>;
  381. // The _M_construct operation has !_M_engaged as a precondition
  382. // while _M_destruct has _M_engaged as a precondition.
  383. template<typename... _Args>
  384. constexpr void
  385. _M_construct(_Args&&... __args)
  386. noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
  387. {
  388. static_cast<_Dp*>(this)->_M_payload._M_construct(
  389. std::forward<_Args>(__args)...);
  390. }
  391. constexpr void
  392. _M_destruct() noexcept
  393. { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
  394. // _M_reset is a 'safe' operation with no precondition.
  395. constexpr void
  396. _M_reset() noexcept
  397. { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
  398. constexpr bool _M_is_engaged() const noexcept
  399. { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
  400. // The _M_get operations have _M_engaged as a precondition.
  401. constexpr _Tp&
  402. _M_get() noexcept
  403. {
  404. __glibcxx_assert(this->_M_is_engaged());
  405. return static_cast<_Dp*>(this)->_M_payload._M_get();
  406. }
  407. constexpr const _Tp&
  408. _M_get() const noexcept
  409. {
  410. __glibcxx_assert(this->_M_is_engaged());
  411. return static_cast<const _Dp*>(this)->_M_payload._M_get();
  412. }
  413. };
  414. /**
  415. * @brief Class template that provides copy/move constructors of optional.
  416. *
  417. * Such a separate base class template is necessary in order to
  418. * conditionally make copy/move constructors trivial.
  419. *
  420. * When the contained value is trivially copy/move constructible,
  421. * the copy/move constructors of _Optional_base will invoke the
  422. * trivial copy/move constructor of _Optional_payload. Otherwise,
  423. * they will invoke _Optional_payload(bool, const _Optional_payload&)
  424. * or _Optional_payload(bool, _Optional_payload&&) to initialize
  425. * the contained value, if copying/moving an engaged optional.
  426. *
  427. * Whether the other special members are trivial is determined by the
  428. * _Optional_payload<_Tp> specialization used for the _M_payload member.
  429. *
  430. * @see optional, _Enable_special_members
  431. */
  432. template<typename _Tp,
  433. bool = is_trivially_copy_constructible_v<_Tp>,
  434. bool = is_trivially_move_constructible_v<_Tp>>
  435. struct _Optional_base
  436. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  437. {
  438. // Constructors for disengaged optionals.
  439. constexpr _Optional_base() = default;
  440. // Constructors for engaged optionals.
  441. template<typename... _Args,
  442. enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
  443. constexpr explicit
  444. _Optional_base(in_place_t, _Args&&... __args)
  445. : _M_payload(in_place, std::forward<_Args>(__args)...)
  446. { }
  447. template<typename _Up, typename... _Args,
  448. enable_if_t<is_constructible_v<_Tp,
  449. initializer_list<_Up>&,
  450. _Args...>, bool> = false>
  451. constexpr explicit
  452. _Optional_base(in_place_t,
  453. initializer_list<_Up> __il,
  454. _Args&&... __args)
  455. : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
  456. { }
  457. // Copy and move constructors.
  458. constexpr
  459. _Optional_base(const _Optional_base& __other)
  460. : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
  461. { }
  462. constexpr
  463. _Optional_base(_Optional_base&& __other)
  464. noexcept(is_nothrow_move_constructible_v<_Tp>)
  465. : _M_payload(__other._M_payload._M_engaged,
  466. std::move(__other._M_payload))
  467. { }
  468. // Assignment operators.
  469. _Optional_base& operator=(const _Optional_base&) = default;
  470. _Optional_base& operator=(_Optional_base&&) = default;
  471. _Optional_payload<_Tp> _M_payload;
  472. };
  473. template<typename _Tp>
  474. struct _Optional_base<_Tp, false, true>
  475. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  476. {
  477. // Constructors for disengaged optionals.
  478. constexpr _Optional_base() = default;
  479. // Constructors for engaged optionals.
  480. template<typename... _Args,
  481. enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
  482. constexpr explicit
  483. _Optional_base(in_place_t, _Args&&... __args)
  484. : _M_payload(in_place, std::forward<_Args>(__args)...)
  485. { }
  486. template<typename _Up, typename... _Args,
  487. enable_if_t<is_constructible_v<_Tp,
  488. initializer_list<_Up>&,
  489. _Args...>, bool> = false>
  490. constexpr explicit
  491. _Optional_base(in_place_t,
  492. initializer_list<_Up> __il,
  493. _Args... __args)
  494. : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
  495. { }
  496. // Copy and move constructors.
  497. constexpr _Optional_base(const _Optional_base& __other)
  498. : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
  499. { }
  500. constexpr _Optional_base(_Optional_base&& __other) = default;
  501. // Assignment operators.
  502. _Optional_base& operator=(const _Optional_base&) = default;
  503. _Optional_base& operator=(_Optional_base&&) = default;
  504. _Optional_payload<_Tp> _M_payload;
  505. };
  506. template<typename _Tp>
  507. struct _Optional_base<_Tp, true, false>
  508. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  509. {
  510. // Constructors for disengaged optionals.
  511. constexpr _Optional_base() = default;
  512. // Constructors for engaged optionals.
  513. template<typename... _Args,
  514. enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
  515. constexpr explicit
  516. _Optional_base(in_place_t, _Args&&... __args)
  517. : _M_payload(in_place, std::forward<_Args>(__args)...)
  518. { }
  519. template<typename _Up, typename... _Args,
  520. enable_if_t<is_constructible_v<_Tp,
  521. initializer_list<_Up>&,
  522. _Args...>, bool> = false>
  523. constexpr explicit
  524. _Optional_base(in_place_t,
  525. initializer_list<_Up> __il,
  526. _Args&&... __args)
  527. : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
  528. { }
  529. // Copy and move constructors.
  530. constexpr _Optional_base(const _Optional_base& __other) = default;
  531. constexpr
  532. _Optional_base(_Optional_base&& __other)
  533. noexcept(is_nothrow_move_constructible_v<_Tp>)
  534. : _M_payload(__other._M_payload._M_engaged,
  535. std::move(__other._M_payload))
  536. { }
  537. // Assignment operators.
  538. _Optional_base& operator=(const _Optional_base&) = default;
  539. _Optional_base& operator=(_Optional_base&&) = default;
  540. _Optional_payload<_Tp> _M_payload;
  541. };
  542. template<typename _Tp>
  543. struct _Optional_base<_Tp, true, true>
  544. : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
  545. {
  546. // Constructors for disengaged optionals.
  547. constexpr _Optional_base() = default;
  548. // Constructors for engaged optionals.
  549. template<typename... _Args,
  550. enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
  551. constexpr explicit
  552. _Optional_base(in_place_t, _Args&&... __args)
  553. : _M_payload(in_place, std::forward<_Args>(__args)...)
  554. { }
  555. template<typename _Up, typename... _Args,
  556. enable_if_t<is_constructible_v<_Tp,
  557. initializer_list<_Up>&,
  558. _Args...>, bool> = false>
  559. constexpr explicit
  560. _Optional_base(in_place_t,
  561. initializer_list<_Up> __il,
  562. _Args&&... __args)
  563. : _M_payload(in_place, __il, std::forward<_Args>(__args)...)
  564. { }
  565. // Copy and move constructors.
  566. constexpr _Optional_base(const _Optional_base& __other) = default;
  567. constexpr _Optional_base(_Optional_base&& __other) = default;
  568. // Assignment operators.
  569. _Optional_base& operator=(const _Optional_base&) = default;
  570. _Optional_base& operator=(_Optional_base&&) = default;
  571. _Optional_payload<_Tp> _M_payload;
  572. };
  573. template<typename _Tp>
  574. class optional;
  575. template<typename _Tp>
  576. inline constexpr bool __is_optional_v = false;
  577. template<typename _Tp>
  578. inline constexpr bool __is_optional_v<optional<_Tp>> = true;
  579. template<typename _Tp, typename _Up>
  580. using __converts_from_optional =
  581. __or_<is_constructible<_Tp, const optional<_Up>&>,
  582. is_constructible<_Tp, optional<_Up>&>,
  583. is_constructible<_Tp, const optional<_Up>&&>,
  584. is_constructible<_Tp, optional<_Up>&&>,
  585. is_convertible<const optional<_Up>&, _Tp>,
  586. is_convertible<optional<_Up>&, _Tp>,
  587. is_convertible<const optional<_Up>&&, _Tp>,
  588. is_convertible<optional<_Up>&&, _Tp>>;
  589. template<typename _Tp, typename _Up>
  590. using __assigns_from_optional =
  591. __or_<is_assignable<_Tp&, const optional<_Up>&>,
  592. is_assignable<_Tp&, optional<_Up>&>,
  593. is_assignable<_Tp&, const optional<_Up>&&>,
  594. is_assignable<_Tp&, optional<_Up>&&>>;
  595. /**
  596. * @brief Class template for optional values.
  597. */
  598. template<typename _Tp>
  599. class optional
  600. : private _Optional_base<_Tp>,
  601. private _Enable_copy_move<
  602. // Copy constructor.
  603. is_copy_constructible_v<_Tp>,
  604. // Copy assignment.
  605. __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
  606. // Move constructor.
  607. is_move_constructible_v<_Tp>,
  608. // Move assignment.
  609. __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
  610. // Unique tag type.
  611. optional<_Tp>>
  612. {
  613. static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
  614. static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
  615. static_assert(is_object_v<_Tp> && !is_array_v<_Tp>);
  616. private:
  617. using _Base = _Optional_base<_Tp>;
  618. // SFINAE helpers
  619. template<typename _Up>
  620. using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
  621. template<typename _Up>
  622. using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
  623. template<typename... _Cond>
  624. using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
  625. public:
  626. using value_type = _Tp;
  627. constexpr optional() noexcept { }
  628. constexpr optional(nullopt_t) noexcept { }
  629. // Converting constructors for engaged optionals.
  630. template<typename _Up = _Tp,
  631. _Requires<__not_self<_Up>, __not_tag<_Up>,
  632. is_constructible<_Tp, _Up>,
  633. is_convertible<_Up, _Tp>> = true>
  634. constexpr
  635. optional(_Up&& __t)
  636. noexcept(is_nothrow_constructible_v<_Tp, _Up>)
  637. : _Base(std::in_place, std::forward<_Up>(__t)) { }
  638. template<typename _Up = _Tp,
  639. _Requires<__not_self<_Up>, __not_tag<_Up>,
  640. is_constructible<_Tp, _Up>,
  641. __not_<is_convertible<_Up, _Tp>>> = false>
  642. explicit constexpr
  643. optional(_Up&& __t)
  644. noexcept(is_nothrow_constructible_v<_Tp, _Up>)
  645. : _Base(std::in_place, std::forward<_Up>(__t)) { }
  646. template<typename _Up,
  647. _Requires<__not_<is_same<_Tp, _Up>>,
  648. is_constructible<_Tp, const _Up&>,
  649. is_convertible<const _Up&, _Tp>,
  650. __not_<__converts_from_optional<_Tp, _Up>>> = true>
  651. constexpr
  652. optional(const optional<_Up>& __t)
  653. noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
  654. {
  655. if (__t)
  656. emplace(*__t);
  657. }
  658. template<typename _Up,
  659. _Requires<__not_<is_same<_Tp, _Up>>,
  660. is_constructible<_Tp, const _Up&>,
  661. __not_<is_convertible<const _Up&, _Tp>>,
  662. __not_<__converts_from_optional<_Tp, _Up>>> = false>
  663. explicit constexpr
  664. optional(const optional<_Up>& __t)
  665. noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
  666. {
  667. if (__t)
  668. emplace(*__t);
  669. }
  670. template<typename _Up,
  671. _Requires<__not_<is_same<_Tp, _Up>>,
  672. is_constructible<_Tp, _Up>,
  673. is_convertible<_Up, _Tp>,
  674. __not_<__converts_from_optional<_Tp, _Up>>> = true>
  675. constexpr
  676. optional(optional<_Up>&& __t)
  677. noexcept(is_nothrow_constructible_v<_Tp, _Up>)
  678. {
  679. if (__t)
  680. emplace(std::move(*__t));
  681. }
  682. template<typename _Up,
  683. _Requires<__not_<is_same<_Tp, _Up>>,
  684. is_constructible<_Tp, _Up>,
  685. __not_<is_convertible<_Up, _Tp>>,
  686. __not_<__converts_from_optional<_Tp, _Up>>> = false>
  687. explicit constexpr
  688. optional(optional<_Up>&& __t)
  689. noexcept(is_nothrow_constructible_v<_Tp, _Up>)
  690. {
  691. if (__t)
  692. emplace(std::move(*__t));
  693. }
  694. template<typename... _Args,
  695. _Requires<is_constructible<_Tp, _Args...>> = false>
  696. explicit constexpr
  697. optional(in_place_t, _Args&&... __args)
  698. noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
  699. : _Base(std::in_place, std::forward<_Args>(__args)...) { }
  700. template<typename _Up, typename... _Args,
  701. _Requires<is_constructible<_Tp,
  702. initializer_list<_Up>&,
  703. _Args...>> = false>
  704. explicit constexpr
  705. optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
  706. noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
  707. _Args...>)
  708. : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
  709. // Assignment operators.
  710. _GLIBCXX20_CONSTEXPR optional&
  711. operator=(nullopt_t) noexcept
  712. {
  713. this->_M_reset();
  714. return *this;
  715. }
  716. template<typename _Up = _Tp>
  717. _GLIBCXX20_CONSTEXPR
  718. enable_if_t<__and_v<__not_self<_Up>,
  719. __not_<__and_<is_scalar<_Tp>,
  720. is_same<_Tp, decay_t<_Up>>>>,
  721. is_constructible<_Tp, _Up>,
  722. is_assignable<_Tp&, _Up>>,
  723. optional&>
  724. operator=(_Up&& __u)
  725. noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
  726. is_nothrow_assignable<_Tp&, _Up>>)
  727. {
  728. if (this->_M_is_engaged())
  729. this->_M_get() = std::forward<_Up>(__u);
  730. else
  731. this->_M_construct(std::forward<_Up>(__u));
  732. return *this;
  733. }
  734. template<typename _Up>
  735. _GLIBCXX20_CONSTEXPR
  736. enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
  737. is_constructible<_Tp, const _Up&>,
  738. is_assignable<_Tp&, const _Up&>,
  739. __not_<__converts_from_optional<_Tp, _Up>>,
  740. __not_<__assigns_from_optional<_Tp, _Up>>>,
  741. optional&>
  742. operator=(const optional<_Up>& __u)
  743. noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
  744. is_nothrow_assignable<_Tp&, const _Up&>>)
  745. {
  746. if (__u)
  747. {
  748. if (this->_M_is_engaged())
  749. this->_M_get() = *__u;
  750. else
  751. this->_M_construct(*__u);
  752. }
  753. else
  754. {
  755. this->_M_reset();
  756. }
  757. return *this;
  758. }
  759. template<typename _Up>
  760. _GLIBCXX20_CONSTEXPR
  761. enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
  762. is_constructible<_Tp, _Up>,
  763. is_assignable<_Tp&, _Up>,
  764. __not_<__converts_from_optional<_Tp, _Up>>,
  765. __not_<__assigns_from_optional<_Tp, _Up>>>,
  766. optional&>
  767. operator=(optional<_Up>&& __u)
  768. noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
  769. is_nothrow_assignable<_Tp&, _Up>>)
  770. {
  771. if (__u)
  772. {
  773. if (this->_M_is_engaged())
  774. this->_M_get() = std::move(*__u);
  775. else
  776. this->_M_construct(std::move(*__u));
  777. }
  778. else
  779. {
  780. this->_M_reset();
  781. }
  782. return *this;
  783. }
  784. template<typename... _Args>
  785. _GLIBCXX20_CONSTEXPR
  786. enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
  787. emplace(_Args&&... __args)
  788. noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
  789. {
  790. this->_M_reset();
  791. this->_M_construct(std::forward<_Args>(__args)...);
  792. return this->_M_get();
  793. }
  794. template<typename _Up, typename... _Args>
  795. _GLIBCXX20_CONSTEXPR
  796. enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
  797. _Tp&>
  798. emplace(initializer_list<_Up> __il, _Args&&... __args)
  799. noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
  800. _Args...>)
  801. {
  802. this->_M_reset();
  803. this->_M_construct(__il, std::forward<_Args>(__args)...);
  804. return this->_M_get();
  805. }
  806. // Destructor is implicit, implemented in _Optional_base.
  807. // Swap.
  808. _GLIBCXX20_CONSTEXPR void
  809. swap(optional& __other)
  810. noexcept(is_nothrow_move_constructible_v<_Tp>
  811. && is_nothrow_swappable_v<_Tp>)
  812. {
  813. using std::swap;
  814. if (this->_M_is_engaged() && __other._M_is_engaged())
  815. swap(this->_M_get(), __other._M_get());
  816. else if (this->_M_is_engaged())
  817. {
  818. __other._M_construct(std::move(this->_M_get()));
  819. this->_M_destruct();
  820. }
  821. else if (__other._M_is_engaged())
  822. {
  823. this->_M_construct(std::move(__other._M_get()));
  824. __other._M_destruct();
  825. }
  826. }
  827. // Observers.
  828. constexpr const _Tp*
  829. operator->() const noexcept
  830. { return std::__addressof(this->_M_get()); }
  831. constexpr _Tp*
  832. operator->() noexcept
  833. { return std::__addressof(this->_M_get()); }
  834. constexpr const _Tp&
  835. operator*() const& noexcept
  836. { return this->_M_get(); }
  837. constexpr _Tp&
  838. operator*()& noexcept
  839. { return this->_M_get(); }
  840. constexpr _Tp&&
  841. operator*()&& noexcept
  842. { return std::move(this->_M_get()); }
  843. constexpr const _Tp&&
  844. operator*() const&& noexcept
  845. { return std::move(this->_M_get()); }
  846. constexpr explicit operator bool() const noexcept
  847. { return this->_M_is_engaged(); }
  848. constexpr bool has_value() const noexcept
  849. { return this->_M_is_engaged(); }
  850. constexpr const _Tp&
  851. value() const&
  852. {
  853. if (this->_M_is_engaged())
  854. return this->_M_get();
  855. __throw_bad_optional_access();
  856. }
  857. constexpr _Tp&
  858. value()&
  859. {
  860. if (this->_M_is_engaged())
  861. return this->_M_get();
  862. __throw_bad_optional_access();
  863. }
  864. constexpr _Tp&&
  865. value()&&
  866. {
  867. if (this->_M_is_engaged())
  868. return std::move(this->_M_get());
  869. __throw_bad_optional_access();
  870. }
  871. constexpr const _Tp&&
  872. value() const&&
  873. {
  874. if (this->_M_is_engaged())
  875. return std::move(this->_M_get());
  876. __throw_bad_optional_access();
  877. }
  878. template<typename _Up>
  879. constexpr _Tp
  880. value_or(_Up&& __u) const&
  881. {
  882. static_assert(is_copy_constructible_v<_Tp>);
  883. static_assert(is_convertible_v<_Up&&, _Tp>);
  884. if (this->_M_is_engaged())
  885. return this->_M_get();
  886. else
  887. return static_cast<_Tp>(std::forward<_Up>(__u));
  888. }
  889. template<typename _Up>
  890. constexpr _Tp
  891. value_or(_Up&& __u) &&
  892. {
  893. static_assert(is_move_constructible_v<_Tp>);
  894. static_assert(is_convertible_v<_Up&&, _Tp>);
  895. if (this->_M_is_engaged())
  896. return std::move(this->_M_get());
  897. else
  898. return static_cast<_Tp>(std::forward<_Up>(__u));
  899. }
  900. #if __cpp_lib_optional >= 202110L
  901. // [optional.monadic]
  902. template<typename _Fn>
  903. constexpr auto
  904. and_then(_Fn&& __f) &
  905. {
  906. using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp&>>;
  907. static_assert(__is_optional_v<remove_cvref_t<_Up>>,
  908. "the function passed to std::optional<T>::and_then "
  909. "must return a std::optional");
  910. if (has_value())
  911. return std::__invoke(std::forward<_Fn>(__f), **this);
  912. else
  913. return _Up();
  914. }
  915. template<typename _Fn>
  916. constexpr auto
  917. and_then(_Fn&& __f) const &
  918. {
  919. using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp&>>;
  920. static_assert(__is_optional_v<_Up>,
  921. "the function passed to std::optional<T>::and_then "
  922. "must return a std::optional");
  923. if (has_value())
  924. return std::__invoke(std::forward<_Fn>(__f), **this);
  925. else
  926. return _Up();
  927. }
  928. template<typename _Fn>
  929. constexpr auto
  930. and_then(_Fn&& __f) &&
  931. {
  932. using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>;
  933. static_assert(__is_optional_v<remove_cvref_t<_Up>>,
  934. "the function passed to std::optional<T>::and_then "
  935. "must return a std::optional");
  936. if (has_value())
  937. return std::__invoke(std::forward<_Fn>(__f), std::move(**this));
  938. else
  939. return _Up();
  940. }
  941. template<typename _Fn>
  942. constexpr auto
  943. and_then(_Fn&& __f) const &&
  944. {
  945. using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>;
  946. static_assert(__is_optional_v<remove_cvref_t<_Up>>,
  947. "the function passed to std::optional<T>::and_then "
  948. "must return a std::optional");
  949. if (has_value())
  950. return std::__invoke(std::forward<_Fn>(__f), std::move(**this));
  951. else
  952. return _Up();
  953. }
  954. template<typename _Fn>
  955. constexpr auto
  956. transform(_Fn&& __f) &
  957. {
  958. using _Up = remove_cv_t<invoke_result_t<_Fn, _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) const &
  967. {
  968. using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>;
  969. if (has_value())
  970. return optional<_Up>(_Optional_func<_Fn>{__f}, **this);
  971. else
  972. return optional<_Up>();
  973. }
  974. template<typename _Fn>
  975. constexpr auto
  976. transform(_Fn&& __f) &&
  977. {
  978. using _Up = remove_cv_t<invoke_result_t<_Fn, _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>
  985. constexpr auto
  986. transform(_Fn&& __f) const &&
  987. {
  988. using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;
  989. if (has_value())
  990. return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this));
  991. else
  992. return optional<_Up>();
  993. }
  994. template<typename _Fn> requires invocable<_Fn> && copy_constructible<_Tp>
  995. constexpr optional
  996. or_else(_Fn&& __f) const&
  997. {
  998. using _Up = invoke_result_t<_Fn>;
  999. static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
  1000. "the function passed to std::optional<T>::or_else "
  1001. "must return a std::optional<T>");
  1002. if (has_value())
  1003. return *this;
  1004. else
  1005. return std::forward<_Fn>(__f)();
  1006. }
  1007. template<typename _Fn> requires invocable<_Fn> && move_constructible<_Tp>
  1008. constexpr optional
  1009. or_else(_Fn&& __f) &&
  1010. {
  1011. using _Up = invoke_result_t<_Fn>;
  1012. static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
  1013. "the function passed to std::optional<T>::or_else "
  1014. "must return a std::optional<T>");
  1015. if (has_value())
  1016. return std::move(*this);
  1017. else
  1018. return std::forward<_Fn>(__f)();
  1019. }
  1020. #endif
  1021. _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }
  1022. private:
  1023. #if __cplusplus >= 202002L
  1024. template<typename _Up> friend class optional;
  1025. template<typename _Fn, typename _Value>
  1026. explicit constexpr
  1027. optional(_Optional_func<_Fn> __f, _Value&& __v)
  1028. {
  1029. this->_M_payload._M_apply(__f, std::forward<_Value>(__v));
  1030. }
  1031. #endif
  1032. };
  1033. template<typename _Tp>
  1034. using __optional_relop_t =
  1035. enable_if_t<is_convertible<_Tp, bool>::value, bool>;
  1036. template<typename _Tp, typename _Up>
  1037. using __optional_eq_t = __optional_relop_t<
  1038. decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
  1039. >;
  1040. template<typename _Tp, typename _Up>
  1041. using __optional_ne_t = __optional_relop_t<
  1042. decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
  1043. >;
  1044. template<typename _Tp, typename _Up>
  1045. using __optional_lt_t = __optional_relop_t<
  1046. decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
  1047. >;
  1048. template<typename _Tp, typename _Up>
  1049. using __optional_gt_t = __optional_relop_t<
  1050. decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
  1051. >;
  1052. template<typename _Tp, typename _Up>
  1053. using __optional_le_t = __optional_relop_t<
  1054. decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
  1055. >;
  1056. template<typename _Tp, typename _Up>
  1057. using __optional_ge_t = __optional_relop_t<
  1058. decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
  1059. >;
  1060. // Comparisons between optional values.
  1061. template<typename _Tp, typename _Up>
  1062. constexpr auto
  1063. operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1064. -> __optional_eq_t<_Tp, _Up>
  1065. {
  1066. return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
  1067. && (!__lhs || *__lhs == *__rhs);
  1068. }
  1069. template<typename _Tp, typename _Up>
  1070. constexpr auto
  1071. operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1072. -> __optional_ne_t<_Tp, _Up>
  1073. {
  1074. return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
  1075. || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
  1076. }
  1077. template<typename _Tp, typename _Up>
  1078. constexpr auto
  1079. operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1080. -> __optional_lt_t<_Tp, _Up>
  1081. {
  1082. return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
  1083. }
  1084. template<typename _Tp, typename _Up>
  1085. constexpr auto
  1086. operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1087. -> __optional_gt_t<_Tp, _Up>
  1088. {
  1089. return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
  1090. }
  1091. template<typename _Tp, typename _Up>
  1092. constexpr auto
  1093. operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1094. -> __optional_le_t<_Tp, _Up>
  1095. {
  1096. return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
  1097. }
  1098. template<typename _Tp, typename _Up>
  1099. constexpr auto
  1100. operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
  1101. -> __optional_ge_t<_Tp, _Up>
  1102. {
  1103. return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
  1104. }
  1105. #ifdef __cpp_lib_three_way_comparison
  1106. template<typename _Tp, three_way_comparable_with<_Tp> _Up>
  1107. constexpr compare_three_way_result_t<_Tp, _Up>
  1108. operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
  1109. {
  1110. return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
  1111. }
  1112. #endif
  1113. // Comparisons with nullopt.
  1114. template<typename _Tp>
  1115. constexpr bool
  1116. operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1117. { return !__lhs; }
  1118. #ifdef __cpp_lib_three_way_comparison
  1119. template<typename _Tp>
  1120. constexpr strong_ordering
  1121. operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
  1122. { return bool(__x) <=> false; }
  1123. #else
  1124. template<typename _Tp>
  1125. constexpr bool
  1126. operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1127. { return !__rhs; }
  1128. template<typename _Tp>
  1129. constexpr bool
  1130. operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1131. { return static_cast<bool>(__lhs); }
  1132. template<typename _Tp>
  1133. constexpr bool
  1134. operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1135. { return static_cast<bool>(__rhs); }
  1136. template<typename _Tp>
  1137. constexpr bool
  1138. operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
  1139. { return false; }
  1140. template<typename _Tp>
  1141. constexpr bool
  1142. operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1143. { return static_cast<bool>(__rhs); }
  1144. template<typename _Tp>
  1145. constexpr bool
  1146. operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1147. { return static_cast<bool>(__lhs); }
  1148. template<typename _Tp>
  1149. constexpr bool
  1150. operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
  1151. { return false; }
  1152. template<typename _Tp>
  1153. constexpr bool
  1154. operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
  1155. { return !__lhs; }
  1156. template<typename _Tp>
  1157. constexpr bool
  1158. operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
  1159. { return true; }
  1160. template<typename _Tp>
  1161. constexpr bool
  1162. operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
  1163. { return true; }
  1164. template<typename _Tp>
  1165. constexpr bool
  1166. operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
  1167. { return !__rhs; }
  1168. #endif // three-way-comparison
  1169. // Comparisons with value type.
  1170. template<typename _Tp, typename _Up>
  1171. constexpr auto
  1172. operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
  1173. -> __optional_eq_t<_Tp, _Up>
  1174. { return __lhs && *__lhs == __rhs; }
  1175. template<typename _Tp, typename _Up>
  1176. constexpr auto
  1177. operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
  1178. -> __optional_eq_t<_Up, _Tp>
  1179. { return __rhs && __lhs == *__rhs; }
  1180. template<typename _Tp, typename _Up>
  1181. constexpr auto
  1182. operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
  1183. -> __optional_ne_t<_Tp, _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_ne_t<_Up, _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_lt_t<_Tp, _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_lt_t<_Up, _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_gt_t<_Tp, _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_gt_t<_Up, _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_le_t<_Tp, _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_le_t<_Up, _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_ge_t<_Tp, _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_ge_t<_Up, _Tp>
  1229. { return !__rhs || __lhs >= *__rhs; }
  1230. #ifdef __cpp_lib_three_way_comparison
  1231. template<typename _Tp, typename _Up>
  1232. requires (!__is_optional_v<_Up>)
  1233. && three_way_comparable_with<_Up, _Tp>
  1234. constexpr compare_three_way_result_t<_Tp, _Up>
  1235. operator<=>(const optional<_Tp>& __x, const _Up& __v)
  1236. { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
  1237. #endif
  1238. // Swap and creation functions.
  1239. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  1240. // 2748. swappable traits for optionals
  1241. template<typename _Tp>
  1242. _GLIBCXX20_CONSTEXPR
  1243. inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
  1244. swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
  1245. noexcept(noexcept(__lhs.swap(__rhs)))
  1246. { __lhs.swap(__rhs); }
  1247. template<typename _Tp>
  1248. enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
  1249. swap(optional<_Tp>&, optional<_Tp>&) = delete;
  1250. template<typename _Tp>
  1251. constexpr
  1252. enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>,
  1253. optional<decay_t<_Tp>>>
  1254. make_optional(_Tp&& __t)
  1255. noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
  1256. { return optional<decay_t<_Tp>>{ std::forward<_Tp>(__t) }; }
  1257. template<typename _Tp, typename... _Args>
  1258. constexpr
  1259. enable_if_t<is_constructible_v<_Tp, _Args...>,
  1260. optional<_Tp>>
  1261. make_optional(_Args&&... __args)
  1262. noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
  1263. { return optional<_Tp>{ in_place, std::forward<_Args>(__args)... }; }
  1264. template<typename _Tp, typename _Up, typename... _Args>
  1265. constexpr
  1266. enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
  1267. optional<_Tp>>
  1268. make_optional(initializer_list<_Up> __il, _Args&&... __args)
  1269. noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
  1270. { return optional<_Tp>{ in_place, __il, std::forward<_Args>(__args)... }; }
  1271. // Hash.
  1272. template<typename _Tp, typename _Up = remove_const_t<_Tp>,
  1273. bool = __poison_hash<_Up>::__enable_hash_call>
  1274. struct __optional_hash_call_base
  1275. {
  1276. size_t
  1277. operator()(const optional<_Tp>& __t) const
  1278. noexcept(noexcept(hash<_Up>{}(*__t)))
  1279. {
  1280. // We pick an arbitrary hash for disengaged optionals which hopefully
  1281. // usual values of _Tp won't typically hash to.
  1282. constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
  1283. return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
  1284. }
  1285. };
  1286. template<typename _Tp, typename _Up>
  1287. struct __optional_hash_call_base<_Tp, _Up, false> {};
  1288. template<typename _Tp>
  1289. struct hash<optional<_Tp>>
  1290. : private __poison_hash<remove_const_t<_Tp>>,
  1291. public __optional_hash_call_base<_Tp>
  1292. {
  1293. using result_type [[__deprecated__]] = size_t;
  1294. using argument_type [[__deprecated__]] = optional<_Tp>;
  1295. };
  1296. template<typename _Tp>
  1297. struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
  1298. { };
  1299. /// @}
  1300. #if __cpp_deduction_guides >= 201606
  1301. template <typename _Tp> optional(_Tp) -> optional<_Tp>;
  1302. #endif
  1303. _GLIBCXX_END_NAMESPACE_VERSION
  1304. } // namespace std
  1305. #endif // C++17
  1306. #endif // _GLIBCXX_OPTIONAL