optional 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. // -*- C++ -*-
  2. //===-------------------------- optional ----------------------------------===//
  3. //
  4. // The LLVM Compiler Infrastructure
  5. //
  6. // This file is dual licensed under the MIT and the University of Illinois Open
  7. // Source Licenses. See LICENSE.TXT for details.
  8. //
  9. //===----------------------------------------------------------------------===//
  10. #ifndef _LIBCPP_OPTIONAL
  11. #define _LIBCPP_OPTIONAL
  12. /*
  13. optional synopsis
  14. // C++1y
  15. namespace std { namespace experimental { inline namespace fundamentals_v1 {
  16. // 5.3, optional for object types
  17. template <class T> class optional;
  18. // 5.4, In-place construction
  19. struct in_place_t{};
  20. constexpr in_place_t in_place{};
  21. // 5.5, No-value state indicator
  22. struct nullopt_t{see below};
  23. constexpr nullopt_t nullopt(unspecified);
  24. // 5.6, Class bad_optional_access
  25. class bad_optional_access;
  26. // 5.7, Relational operators
  27. template <class T>
  28. constexpr bool operator==(const optional<T>&, const optional<T>&);
  29. template <class T>
  30. constexpr bool operator!=(const optional<T>&, const optional<T>&);
  31. template <class T>
  32. constexpr bool operator<(const optional<T>&, const optional<T>&);
  33. template <class T>
  34. constexpr bool operator>(const optional<T>&, const optional<T>&);
  35. template <class T>
  36. constexpr bool operator<=(const optional<T>&, const optional<T>&);
  37. template <class T>
  38. constexpr bool operator>=(const optional<T>&, const optional<T>&);
  39. // 5.8, Comparison with nullopt
  40. template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
  41. template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
  42. template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
  43. template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
  44. template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
  45. template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
  46. template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
  47. template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
  48. template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
  49. template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
  50. template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
  51. template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
  52. // 5.9, Comparison with T
  53. template <class T> constexpr bool operator==(const optional<T>&, const T&);
  54. template <class T> constexpr bool operator==(const T&, const optional<T>&);
  55. template <class T> constexpr bool operator!=(const optional<T>&, const T&);
  56. template <class T> constexpr bool operator!=(const T&, const optional<T>&);
  57. template <class T> constexpr bool operator<(const optional<T>&, const T&);
  58. template <class T> constexpr bool operator<(const T&, const optional<T>&);
  59. template <class T> constexpr bool operator<=(const optional<T>&, const T&);
  60. template <class T> constexpr bool operator<=(const T&, const optional<T>&);
  61. template <class T> constexpr bool operator>(const optional<T>&, const T&);
  62. template <class T> constexpr bool operator>(const T&, const optional<T>&);
  63. template <class T> constexpr bool operator>=(const optional<T>&, const T&);
  64. template <class T> constexpr bool operator>=(const T&, const optional<T>&);
  65. // 5.10, Specialized algorithms
  66. template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
  67. template <class T> constexpr optional<see below> make_optional(T&&);
  68. template <class T>
  69. class optional
  70. {
  71. public:
  72. typedef T value_type;
  73. // 5.3.1, Constructors
  74. constexpr optional() noexcept;
  75. constexpr optional(nullopt_t) noexcept;
  76. optional(const optional&);
  77. optional(optional&&) noexcept(see below);
  78. constexpr optional(const T&);
  79. constexpr optional(T&&);
  80. template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
  81. template <class U, class... Args>
  82. constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
  83. // 5.3.2, Destructor
  84. ~optional();
  85. // 5.3.3, Assignment
  86. optional& operator=(nullopt_t) noexcept;
  87. optional& operator=(const optional&);
  88. optional& operator=(optional&&) noexcept(see below);
  89. template <class U> optional& operator=(U&&);
  90. template <class... Args> void emplace(Args&&...);
  91. template <class U, class... Args>
  92. void emplace(initializer_list<U>, Args&&...);
  93. // 5.3.4, Swap
  94. void swap(optional&) noexcept(see below);
  95. // 5.3.5, Observers
  96. constexpr T const* operator ->() const;
  97. constexpr T* operator ->();
  98. constexpr T const& operator *() const &;
  99. constexpr T& operator *() &;
  100. constexpr T&& operator *() &&;
  101. constexpr const T&& operator *() const &&;
  102. constexpr explicit operator bool() const noexcept;
  103. constexpr T const& value() const &;
  104. constexpr T& value() &;
  105. constexpr T&& value() &&;
  106. constexpr const T&& value() const &&;
  107. template <class U> constexpr T value_or(U&&) const &;
  108. template <class U> constexpr T value_or(U&&) &&;
  109. private:
  110. T* val; // exposition only
  111. };
  112. } // namespace fundamentals_v1
  113. } // namespace experimental
  114. // 5.11, Hash support
  115. template <class T> struct hash;
  116. template <class T> struct hash<experimental::optional<T>>;
  117. } // namespace std
  118. */
  119. #include <experimental/__config>
  120. #include <functional>
  121. #include <stdexcept>
  122. _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
  123. class _LIBCPP_EXCEPTION_ABI bad_optional_access
  124. : public std::logic_error
  125. {
  126. public:
  127. bad_optional_access() : std::logic_error("Bad optional Access") {}
  128. // Get the key function ~bad_optional_access() into the dylib
  129. virtual ~bad_optional_access() _NOEXCEPT;
  130. };
  131. _LIBCPP_END_NAMESPACE_EXPERIMENTAL
  132. #if _LIBCPP_STD_VER > 11
  133. #include <initializer_list>
  134. #include <type_traits>
  135. #include <new>
  136. #include <__functional_base>
  137. #include <__undef_min_max>
  138. #include <__debug>
  139. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  140. #pragma GCC system_header
  141. #endif
  142. _LIBCPP_BEGIN_NAMESPACE_LFTS
  143. struct in_place_t {};
  144. constexpr in_place_t in_place{};
  145. struct nullopt_t
  146. {
  147. explicit constexpr nullopt_t(int) noexcept {}
  148. };
  149. constexpr nullopt_t nullopt{0};
  150. template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
  151. class __optional_storage
  152. {
  153. protected:
  154. typedef _Tp value_type;
  155. union
  156. {
  157. char __null_state_;
  158. value_type __val_;
  159. };
  160. bool __engaged_ = false;
  161. _LIBCPP_INLINE_VISIBILITY
  162. ~__optional_storage()
  163. {
  164. if (__engaged_)
  165. __val_.~value_type();
  166. }
  167. _LIBCPP_INLINE_VISIBILITY
  168. constexpr __optional_storage() noexcept
  169. : __null_state_('\0') {}
  170. _LIBCPP_INLINE_VISIBILITY
  171. __optional_storage(const __optional_storage& __x)
  172. : __engaged_(__x.__engaged_)
  173. {
  174. if (__engaged_)
  175. ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
  176. }
  177. _LIBCPP_INLINE_VISIBILITY
  178. __optional_storage(__optional_storage&& __x)
  179. noexcept(is_nothrow_move_constructible<value_type>::value)
  180. : __engaged_(__x.__engaged_)
  181. {
  182. if (__engaged_)
  183. ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
  184. }
  185. _LIBCPP_INLINE_VISIBILITY
  186. constexpr __optional_storage(const value_type& __v)
  187. : __val_(__v),
  188. __engaged_(true) {}
  189. _LIBCPP_INLINE_VISIBILITY
  190. constexpr __optional_storage(value_type&& __v)
  191. : __val_(_VSTD::move(__v)),
  192. __engaged_(true) {}
  193. template <class... _Args>
  194. _LIBCPP_INLINE_VISIBILITY
  195. constexpr
  196. explicit __optional_storage(in_place_t, _Args&&... __args)
  197. : __val_(_VSTD::forward<_Args>(__args)...),
  198. __engaged_(true) {}
  199. };
  200. template <class _Tp>
  201. class __optional_storage<_Tp, true>
  202. {
  203. protected:
  204. typedef _Tp value_type;
  205. union
  206. {
  207. char __null_state_;
  208. value_type __val_;
  209. };
  210. bool __engaged_ = false;
  211. _LIBCPP_INLINE_VISIBILITY
  212. constexpr __optional_storage() noexcept
  213. : __null_state_('\0') {}
  214. _LIBCPP_INLINE_VISIBILITY
  215. __optional_storage(const __optional_storage& __x)
  216. : __engaged_(__x.__engaged_)
  217. {
  218. if (__engaged_)
  219. ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
  220. }
  221. _LIBCPP_INLINE_VISIBILITY
  222. __optional_storage(__optional_storage&& __x)
  223. noexcept(is_nothrow_move_constructible<value_type>::value)
  224. : __engaged_(__x.__engaged_)
  225. {
  226. if (__engaged_)
  227. ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
  228. }
  229. _LIBCPP_INLINE_VISIBILITY
  230. constexpr __optional_storage(const value_type& __v)
  231. : __val_(__v),
  232. __engaged_(true) {}
  233. _LIBCPP_INLINE_VISIBILITY
  234. constexpr __optional_storage(value_type&& __v)
  235. : __val_(_VSTD::move(__v)),
  236. __engaged_(true) {}
  237. template <class... _Args>
  238. _LIBCPP_INLINE_VISIBILITY
  239. constexpr
  240. explicit __optional_storage(in_place_t, _Args&&... __args)
  241. : __val_(_VSTD::forward<_Args>(__args)...),
  242. __engaged_(true) {}
  243. };
  244. template <class _Tp>
  245. class optional
  246. : private __optional_storage<_Tp>
  247. {
  248. typedef __optional_storage<_Tp> __base;
  249. public:
  250. typedef _Tp value_type;
  251. static_assert(!is_reference<value_type>::value,
  252. "Instantiation of optional with a reference type is ill-formed.");
  253. static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
  254. "Instantiation of optional with a in_place_t type is ill-formed.");
  255. static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
  256. "Instantiation of optional with a nullopt_t type is ill-formed.");
  257. static_assert(is_object<value_type>::value,
  258. "Instantiation of optional with a non-object type is undefined behavior.");
  259. static_assert(is_nothrow_destructible<value_type>::value,
  260. "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
  261. _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
  262. _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
  263. _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
  264. _LIBCPP_INLINE_VISIBILITY ~optional() = default;
  265. _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
  266. _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
  267. : __base(__v) {}
  268. _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
  269. : __base(_VSTD::move(__v)) {}
  270. template <class... _Args,
  271. class = typename enable_if
  272. <
  273. is_constructible<value_type, _Args...>::value
  274. >::type
  275. >
  276. _LIBCPP_INLINE_VISIBILITY
  277. constexpr
  278. explicit optional(in_place_t, _Args&&... __args)
  279. : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
  280. template <class _Up, class... _Args,
  281. class = typename enable_if
  282. <
  283. is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
  284. >::type
  285. >
  286. _LIBCPP_INLINE_VISIBILITY
  287. constexpr
  288. explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
  289. : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
  290. _LIBCPP_INLINE_VISIBILITY
  291. optional& operator=(nullopt_t) noexcept
  292. {
  293. if (this->__engaged_)
  294. {
  295. this->__val_.~value_type();
  296. this->__engaged_ = false;
  297. }
  298. return *this;
  299. }
  300. _LIBCPP_INLINE_VISIBILITY
  301. optional&
  302. operator=(const optional& __opt)
  303. {
  304. if (this->__engaged_ == __opt.__engaged_)
  305. {
  306. if (this->__engaged_)
  307. this->__val_ = __opt.__val_;
  308. }
  309. else
  310. {
  311. if (this->__engaged_)
  312. this->__val_.~value_type();
  313. else
  314. ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
  315. this->__engaged_ = __opt.__engaged_;
  316. }
  317. return *this;
  318. }
  319. _LIBCPP_INLINE_VISIBILITY
  320. optional&
  321. operator=(optional&& __opt)
  322. noexcept(is_nothrow_move_assignable<value_type>::value &&
  323. is_nothrow_move_constructible<value_type>::value)
  324. {
  325. if (this->__engaged_ == __opt.__engaged_)
  326. {
  327. if (this->__engaged_)
  328. this->__val_ = _VSTD::move(__opt.__val_);
  329. }
  330. else
  331. {
  332. if (this->__engaged_)
  333. this->__val_.~value_type();
  334. else
  335. ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
  336. this->__engaged_ = __opt.__engaged_;
  337. }
  338. return *this;
  339. }
  340. template <class _Up,
  341. class = typename enable_if
  342. <
  343. is_same<typename remove_reference<_Up>::type, value_type>::value &&
  344. is_constructible<value_type, _Up>::value &&
  345. is_assignable<value_type&, _Up>::value
  346. >::type
  347. >
  348. _LIBCPP_INLINE_VISIBILITY
  349. optional&
  350. operator=(_Up&& __v)
  351. {
  352. if (this->__engaged_)
  353. this->__val_ = _VSTD::forward<_Up>(__v);
  354. else
  355. {
  356. ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
  357. this->__engaged_ = true;
  358. }
  359. return *this;
  360. }
  361. template <class... _Args,
  362. class = typename enable_if
  363. <
  364. is_constructible<value_type, _Args...>::value
  365. >::type
  366. >
  367. _LIBCPP_INLINE_VISIBILITY
  368. void
  369. emplace(_Args&&... __args)
  370. {
  371. *this = nullopt;
  372. ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
  373. this->__engaged_ = true;
  374. }
  375. template <class _Up, class... _Args,
  376. class = typename enable_if
  377. <
  378. is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
  379. >::type
  380. >
  381. _LIBCPP_INLINE_VISIBILITY
  382. void
  383. emplace(initializer_list<_Up> __il, _Args&&... __args)
  384. {
  385. *this = nullopt;
  386. ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
  387. this->__engaged_ = true;
  388. }
  389. _LIBCPP_INLINE_VISIBILITY
  390. void
  391. swap(optional& __opt)
  392. noexcept(is_nothrow_move_constructible<value_type>::value &&
  393. __is_nothrow_swappable<value_type>::value)
  394. {
  395. using _VSTD::swap;
  396. if (this->__engaged_ == __opt.__engaged_)
  397. {
  398. if (this->__engaged_)
  399. swap(this->__val_, __opt.__val_);
  400. }
  401. else
  402. {
  403. if (this->__engaged_)
  404. {
  405. ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
  406. this->__val_.~value_type();
  407. }
  408. else
  409. {
  410. ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
  411. __opt.__val_.~value_type();
  412. }
  413. swap(this->__engaged_, __opt.__engaged_);
  414. }
  415. }
  416. _LIBCPP_INLINE_VISIBILITY
  417. constexpr
  418. value_type const*
  419. operator->() const
  420. {
  421. _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
  422. return __operator_arrow(__has_operator_addressof<value_type>{});
  423. }
  424. _LIBCPP_INLINE_VISIBILITY
  425. value_type*
  426. operator->()
  427. {
  428. _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
  429. return _VSTD::addressof(this->__val_);
  430. }
  431. _LIBCPP_INLINE_VISIBILITY
  432. constexpr
  433. const value_type&
  434. operator*() const
  435. {
  436. _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
  437. return this->__val_;
  438. }
  439. _LIBCPP_INLINE_VISIBILITY
  440. value_type&
  441. operator*()
  442. {
  443. _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
  444. return this->__val_;
  445. }
  446. _LIBCPP_INLINE_VISIBILITY
  447. constexpr explicit operator bool() const noexcept {return this->__engaged_;}
  448. _LIBCPP_INLINE_VISIBILITY
  449. constexpr value_type const& value() const
  450. {
  451. if (!this->__engaged_)
  452. #ifndef _LIBCPP_NO_EXCEPTIONS
  453. throw bad_optional_access();
  454. #else
  455. assert(!"bad optional access");
  456. #endif
  457. return this->__val_;
  458. }
  459. _LIBCPP_INLINE_VISIBILITY
  460. value_type& value()
  461. {
  462. if (!this->__engaged_)
  463. #ifndef _LIBCPP_NO_EXCEPTIONS
  464. throw bad_optional_access();
  465. #else
  466. assert(!"bad optional access");
  467. #endif
  468. return this->__val_;
  469. }
  470. template <class _Up>
  471. _LIBCPP_INLINE_VISIBILITY
  472. constexpr value_type value_or(_Up&& __v) const&
  473. {
  474. static_assert(is_copy_constructible<value_type>::value,
  475. "optional<T>::value_or: T must be copy constructible");
  476. static_assert(is_convertible<_Up, value_type>::value,
  477. "optional<T>::value_or: U must be convertible to T");
  478. return this->__engaged_ ? this->__val_ :
  479. static_cast<value_type>(_VSTD::forward<_Up>(__v));
  480. }
  481. template <class _Up>
  482. _LIBCPP_INLINE_VISIBILITY
  483. value_type value_or(_Up&& __v) &&
  484. {
  485. static_assert(is_move_constructible<value_type>::value,
  486. "optional<T>::value_or: T must be move constructible");
  487. static_assert(is_convertible<_Up, value_type>::value,
  488. "optional<T>::value_or: U must be convertible to T");
  489. return this->__engaged_ ? _VSTD::move(this->__val_) :
  490. static_cast<value_type>(_VSTD::forward<_Up>(__v));
  491. }
  492. private:
  493. _LIBCPP_INLINE_VISIBILITY
  494. value_type const*
  495. __operator_arrow(true_type) const
  496. {
  497. return _VSTD::addressof(this->__val_);
  498. }
  499. _LIBCPP_INLINE_VISIBILITY
  500. constexpr
  501. value_type const*
  502. __operator_arrow(false_type) const
  503. {
  504. return &this->__val_;
  505. }
  506. };
  507. // Comparisons between optionals
  508. template <class _Tp>
  509. inline _LIBCPP_INLINE_VISIBILITY
  510. constexpr
  511. bool
  512. operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
  513. {
  514. if (static_cast<bool>(__x) != static_cast<bool>(__y))
  515. return false;
  516. if (!static_cast<bool>(__x))
  517. return true;
  518. return *__x == *__y;
  519. }
  520. template <class _Tp>
  521. inline _LIBCPP_INLINE_VISIBILITY
  522. constexpr
  523. bool
  524. operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
  525. {
  526. return !(__x == __y);
  527. }
  528. template <class _Tp>
  529. inline _LIBCPP_INLINE_VISIBILITY
  530. constexpr
  531. bool
  532. operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
  533. {
  534. if (!static_cast<bool>(__y))
  535. return false;
  536. if (!static_cast<bool>(__x))
  537. return true;
  538. return *__x < *__y;
  539. }
  540. template <class _Tp>
  541. inline _LIBCPP_INLINE_VISIBILITY
  542. constexpr
  543. bool
  544. operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
  545. {
  546. return __y < __x;
  547. }
  548. template <class _Tp>
  549. inline _LIBCPP_INLINE_VISIBILITY
  550. constexpr
  551. bool
  552. operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
  553. {
  554. return !(__y < __x);
  555. }
  556. template <class _Tp>
  557. inline _LIBCPP_INLINE_VISIBILITY
  558. constexpr
  559. bool
  560. operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
  561. {
  562. return !(__x < __y);
  563. }
  564. // Comparisons with nullopt
  565. template <class _Tp>
  566. inline _LIBCPP_INLINE_VISIBILITY
  567. constexpr
  568. bool
  569. operator==(const optional<_Tp>& __x, nullopt_t) noexcept
  570. {
  571. return !static_cast<bool>(__x);
  572. }
  573. template <class _Tp>
  574. inline _LIBCPP_INLINE_VISIBILITY
  575. constexpr
  576. bool
  577. operator==(nullopt_t, const optional<_Tp>& __x) noexcept
  578. {
  579. return !static_cast<bool>(__x);
  580. }
  581. template <class _Tp>
  582. inline _LIBCPP_INLINE_VISIBILITY
  583. constexpr
  584. bool
  585. operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
  586. {
  587. return static_cast<bool>(__x);
  588. }
  589. template <class _Tp>
  590. inline _LIBCPP_INLINE_VISIBILITY
  591. constexpr
  592. bool
  593. operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
  594. {
  595. return static_cast<bool>(__x);
  596. }
  597. template <class _Tp>
  598. inline _LIBCPP_INLINE_VISIBILITY
  599. constexpr
  600. bool
  601. operator<(const optional<_Tp>&, nullopt_t) noexcept
  602. {
  603. return false;
  604. }
  605. template <class _Tp>
  606. inline _LIBCPP_INLINE_VISIBILITY
  607. constexpr
  608. bool
  609. operator<(nullopt_t, const optional<_Tp>& __x) noexcept
  610. {
  611. return static_cast<bool>(__x);
  612. }
  613. template <class _Tp>
  614. inline _LIBCPP_INLINE_VISIBILITY
  615. constexpr
  616. bool
  617. operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
  618. {
  619. return !static_cast<bool>(__x);
  620. }
  621. template <class _Tp>
  622. inline _LIBCPP_INLINE_VISIBILITY
  623. constexpr
  624. bool
  625. operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
  626. {
  627. return true;
  628. }
  629. template <class _Tp>
  630. inline _LIBCPP_INLINE_VISIBILITY
  631. constexpr
  632. bool
  633. operator>(const optional<_Tp>& __x, nullopt_t) noexcept
  634. {
  635. return static_cast<bool>(__x);
  636. }
  637. template <class _Tp>
  638. inline _LIBCPP_INLINE_VISIBILITY
  639. constexpr
  640. bool
  641. operator>(nullopt_t, const optional<_Tp>& __x) noexcept
  642. {
  643. return false;
  644. }
  645. template <class _Tp>
  646. inline _LIBCPP_INLINE_VISIBILITY
  647. constexpr
  648. bool
  649. operator>=(const optional<_Tp>&, nullopt_t) noexcept
  650. {
  651. return true;
  652. }
  653. template <class _Tp>
  654. inline _LIBCPP_INLINE_VISIBILITY
  655. constexpr
  656. bool
  657. operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
  658. {
  659. return !static_cast<bool>(__x);
  660. }
  661. // Comparisons with T
  662. template <class _Tp>
  663. inline _LIBCPP_INLINE_VISIBILITY
  664. constexpr
  665. bool
  666. operator==(const optional<_Tp>& __x, const _Tp& __v)
  667. {
  668. return static_cast<bool>(__x) ? *__x == __v : false;
  669. }
  670. template <class _Tp>
  671. inline _LIBCPP_INLINE_VISIBILITY
  672. constexpr
  673. bool
  674. operator==(const _Tp& __v, const optional<_Tp>& __x)
  675. {
  676. return static_cast<bool>(__x) ? *__x == __v : false;
  677. }
  678. template <class _Tp>
  679. inline _LIBCPP_INLINE_VISIBILITY
  680. constexpr
  681. bool
  682. operator!=(const optional<_Tp>& __x, const _Tp& __v)
  683. {
  684. return static_cast<bool>(__x) ? !(*__x == __v) : true;
  685. }
  686. template <class _Tp>
  687. inline _LIBCPP_INLINE_VISIBILITY
  688. constexpr
  689. bool
  690. operator!=(const _Tp& __v, const optional<_Tp>& __x)
  691. {
  692. return static_cast<bool>(__x) ? !(*__x == __v) : true;
  693. }
  694. template <class _Tp>
  695. inline _LIBCPP_INLINE_VISIBILITY
  696. constexpr
  697. bool
  698. operator<(const optional<_Tp>& __x, const _Tp& __v)
  699. {
  700. return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
  701. }
  702. template <class _Tp>
  703. inline _LIBCPP_INLINE_VISIBILITY
  704. constexpr
  705. bool
  706. operator<(const _Tp& __v, const optional<_Tp>& __x)
  707. {
  708. return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
  709. }
  710. template <class _Tp>
  711. inline _LIBCPP_INLINE_VISIBILITY
  712. constexpr
  713. bool
  714. operator<=(const optional<_Tp>& __x, const _Tp& __v)
  715. {
  716. return !(__x > __v);
  717. }
  718. template <class _Tp>
  719. inline _LIBCPP_INLINE_VISIBILITY
  720. constexpr
  721. bool
  722. operator<=(const _Tp& __v, const optional<_Tp>& __x)
  723. {
  724. return !(__v > __x);
  725. }
  726. template <class _Tp>
  727. inline _LIBCPP_INLINE_VISIBILITY
  728. constexpr
  729. bool
  730. operator>(const optional<_Tp>& __x, const _Tp& __v)
  731. {
  732. return static_cast<bool>(__x) ? __v < __x : false;
  733. }
  734. template <class _Tp>
  735. inline _LIBCPP_INLINE_VISIBILITY
  736. constexpr
  737. bool
  738. operator>(const _Tp& __v, const optional<_Tp>& __x)
  739. {
  740. return static_cast<bool>(__x) ? __x < __v : true;
  741. }
  742. template <class _Tp>
  743. inline _LIBCPP_INLINE_VISIBILITY
  744. constexpr
  745. bool
  746. operator>=(const optional<_Tp>& __x, const _Tp& __v)
  747. {
  748. return !(__x < __v);
  749. }
  750. template <class _Tp>
  751. inline _LIBCPP_INLINE_VISIBILITY
  752. constexpr
  753. bool
  754. operator>=(const _Tp& __v, const optional<_Tp>& __x)
  755. {
  756. return !(__v < __x);
  757. }
  758. template <class _Tp>
  759. inline _LIBCPP_INLINE_VISIBILITY
  760. void
  761. swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
  762. {
  763. __x.swap(__y);
  764. }
  765. template <class _Tp>
  766. inline _LIBCPP_INLINE_VISIBILITY
  767. constexpr
  768. optional<typename decay<_Tp>::type>
  769. make_optional(_Tp&& __v)
  770. {
  771. return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
  772. }
  773. _LIBCPP_END_NAMESPACE_LFTS
  774. _LIBCPP_BEGIN_NAMESPACE_STD
  775. template <class _Tp>
  776. struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
  777. {
  778. typedef std::experimental::optional<_Tp> argument_type;
  779. typedef size_t result_type;
  780. _LIBCPP_INLINE_VISIBILITY
  781. result_type operator()(const argument_type& __opt) const _NOEXCEPT
  782. {
  783. return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
  784. }
  785. };
  786. _LIBCPP_END_NAMESPACE_STD
  787. #endif // _LIBCPP_STD_VER > 11
  788. #endif // _LIBCPP_OPTIONAL