optional 38 KB

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