optional.hpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Casey Carter 2017
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_UTILITY_OPTIONAL_HPP
  14. #define RANGES_V3_UTILITY_OPTIONAL_HPP
  15. #include <exception>
  16. #include <initializer_list>
  17. #include <memory>
  18. #include <new>
  19. #include <concepts/concepts.hpp>
  20. #include <range/v3/detail/config.hpp>
  21. #include <range/v3/utility/addressof.hpp>
  22. #include <range/v3/utility/in_place.hpp>
  23. #include <range/v3/utility/static_const.hpp>
  24. #include <range/v3/utility/swap.hpp>
  25. #include <range/v3/detail/prologue.hpp>
  26. namespace ranges
  27. {
  28. template<typename>
  29. struct optional;
  30. struct bad_optional_access : std::exception
  31. {
  32. virtual const char * what() const noexcept override
  33. {
  34. return "bad optional access";
  35. }
  36. };
  37. struct nullopt_t
  38. {
  39. struct tag
  40. {};
  41. constexpr explicit nullopt_t(tag) noexcept
  42. {}
  43. };
  44. #if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
  45. inline constexpr nullopt_t nullopt{nullopt_t::tag{}};
  46. #else
  47. /// \cond
  48. namespace detail
  49. {
  50. template<typename>
  51. struct nullopt_holder
  52. {
  53. static constexpr nullopt_t nullopt{nullopt_t::tag{}};
  54. };
  55. template<typename T>
  56. constexpr nullopt_t nullopt_holder<T>::nullopt;
  57. } // namespace detail
  58. /// \endcond
  59. namespace
  60. {
  61. constexpr auto & nullopt = detail::nullopt_holder<void>::nullopt;
  62. }
  63. #endif
  64. /// \cond
  65. namespace detail
  66. {
  67. template<typename = void>
  68. [[noreturn]] bool throw_bad_optional_access()
  69. {
  70. throw bad_optional_access{};
  71. }
  72. namespace optional_adl
  73. {
  74. template<typename T, bool = std::is_trivially_destructible<T>::value>
  75. struct optional_storage
  76. {
  77. union
  78. {
  79. char dummy_;
  80. meta::_t<std::remove_cv<T>> data_;
  81. };
  82. bool engaged_;
  83. constexpr optional_storage() noexcept
  84. : optional_storage(
  85. tag{},
  86. meta::bool_<detail::is_trivially_default_constructible_v<T> &&
  87. detail::is_trivially_copyable_v<T>>{})
  88. {}
  89. template(typename... Args)(
  90. requires constructible_from<T, Args...>)
  91. constexpr explicit optional_storage(in_place_t,
  92. Args &&... args) //
  93. noexcept(std::is_nothrow_constructible<T, Args...>::value)
  94. : data_(static_cast<Args &&>(args)...)
  95. , engaged_{true}
  96. {}
  97. constexpr void reset() noexcept
  98. {
  99. engaged_ = false;
  100. }
  101. private:
  102. struct tag
  103. {};
  104. constexpr optional_storage(tag, std::false_type) noexcept
  105. : dummy_{}
  106. , engaged_{false}
  107. {}
  108. constexpr optional_storage(tag, std::true_type) noexcept
  109. : data_{}
  110. , engaged_{false}
  111. {}
  112. };
  113. template<typename T>
  114. struct optional_storage<T, false>
  115. {
  116. union
  117. {
  118. char dummy_;
  119. meta::_t<std::remove_cv<T>> data_;
  120. };
  121. bool engaged_;
  122. ~optional_storage()
  123. {
  124. reset();
  125. }
  126. constexpr optional_storage() noexcept
  127. : dummy_{}
  128. , engaged_{false}
  129. {}
  130. template(typename... Args)(
  131. requires constructible_from<T, Args...>)
  132. constexpr explicit optional_storage(in_place_t,
  133. Args &&... args) //
  134. noexcept(std::is_nothrow_constructible<T, Args...>::value)
  135. : data_(static_cast<Args &&>(args)...)
  136. , engaged_{true}
  137. {}
  138. optional_storage(optional_storage const &) = default;
  139. optional_storage(optional_storage &&) = default;
  140. optional_storage & operator=(optional_storage const &) = default;
  141. optional_storage & operator=(optional_storage &&) = default;
  142. void reset() noexcept
  143. {
  144. if(engaged_)
  145. {
  146. data_.~T();
  147. engaged_ = false;
  148. }
  149. }
  150. };
  151. template<typename T>
  152. struct optional_base : private optional_storage<T>
  153. {
  154. using optional_storage<T>::optional_storage;
  155. using optional_storage<T>::reset;
  156. constexpr bool has_value() const noexcept
  157. {
  158. return engaged_;
  159. }
  160. constexpr T & operator*() & noexcept
  161. {
  162. return RANGES_EXPECT(engaged_), data_;
  163. }
  164. constexpr T const & operator*() const & noexcept
  165. {
  166. return RANGES_EXPECT(engaged_), data_;
  167. }
  168. constexpr T && operator*() && noexcept
  169. {
  170. return RANGES_EXPECT(engaged_), detail::move(data_);
  171. }
  172. constexpr T const && operator*() const && noexcept
  173. {
  174. return RANGES_EXPECT(engaged_), detail::move(data_);
  175. }
  176. constexpr T * operator->() noexcept
  177. {
  178. return RANGES_EXPECT(engaged_), detail::addressof(data_);
  179. }
  180. constexpr T const * operator->() const noexcept
  181. {
  182. return RANGES_EXPECT(engaged_), detail::addressof(data_);
  183. }
  184. CPP_member
  185. constexpr auto swap(optional_base & that) //
  186. noexcept(std::is_nothrow_move_constructible<T>::value &&
  187. is_nothrow_swappable<T>::value) //
  188. -> CPP_ret(void)(
  189. requires move_constructible<T> && swappable<T>)
  190. {
  191. constexpr bool can_swap_trivially =
  192. !::concepts::adl_swap_detail::is_adl_swappable_v<T> &&
  193. detail::is_trivially_move_constructible_v<T> &&
  194. detail::is_trivially_move_assignable_v<T>;
  195. swap_(meta::bool_<can_swap_trivially>{}, that);
  196. }
  197. protected:
  198. template(typename... Args)(
  199. requires constructible_from<T, Args...>)
  200. T & construct_from(Args &&... args)
  201. noexcept(std::is_nothrow_constructible<T, Args...>::value)
  202. {
  203. RANGES_EXPECT(!engaged_);
  204. auto const address = static_cast<void *>(std::addressof(data_));
  205. ::new(address) T(static_cast<Args &&>(args)...);
  206. engaged_ = true;
  207. return data_;
  208. }
  209. template(typename I)(
  210. requires constructible_from<T, decltype(*std::declval<const I &>())>)
  211. T & construct_from_deref(const I & it)
  212. {
  213. RANGES_EXPECT(!engaged_);
  214. auto const address = static_cast<void *>(std::addressof(data_));
  215. ::new(address) T(*it);
  216. engaged_ = true;
  217. return data_;
  218. }
  219. template<typename U>
  220. constexpr void assign_from(U && that) noexcept(
  221. std::is_nothrow_constructible<T, decltype(*static_cast<U &&>(that))>::
  222. value && std::is_nothrow_assignable<
  223. T &, decltype(*static_cast<U &&>(that))>::value)
  224. {
  225. if(!that.has_value())
  226. reset();
  227. else if(engaged_)
  228. data_ = *static_cast<U &&>(that);
  229. else
  230. {
  231. auto const address =
  232. static_cast<void *>(detail::addressof(data_));
  233. ::new(address) T(*static_cast<U &&>(that));
  234. engaged_ = true;
  235. }
  236. }
  237. private:
  238. constexpr void swap_(std::true_type, optional_base & that) noexcept
  239. {
  240. ranges::swap(static_cast<optional_storage<T> &>(*this),
  241. static_cast<optional_storage<T> &>(that));
  242. }
  243. constexpr void swap_(std::false_type, optional_base & that) noexcept(
  244. std::is_nothrow_move_constructible<T>::value &&
  245. is_nothrow_swappable<T>::value)
  246. {
  247. if(that.engaged_ == engaged_)
  248. {
  249. if(engaged_)
  250. ranges::swap(data_, that.data_);
  251. }
  252. else
  253. {
  254. auto & src = engaged_ ? *this : that;
  255. auto & dst = engaged_ ? that : *this;
  256. dst.construct_from(detail::move(src.data_));
  257. src.reset();
  258. }
  259. }
  260. using optional_storage<T>::engaged_;
  261. using optional_storage<T>::data_;
  262. };
  263. template<typename T>
  264. struct optional_base<T &>
  265. {
  266. optional_base() = default;
  267. template(typename Arg)(
  268. requires constructible_from<T &, Arg>)
  269. constexpr explicit optional_base(in_place_t, Arg && arg) noexcept //
  270. : ptr_(detail::addressof(arg))
  271. {}
  272. constexpr bool has_value() const noexcept
  273. {
  274. return ptr_;
  275. }
  276. constexpr T & operator*() const noexcept
  277. {
  278. return RANGES_EXPECT(ptr_), *ptr_;
  279. }
  280. constexpr T * operator->() const noexcept
  281. {
  282. return RANGES_EXPECT(ptr_), ptr_;
  283. }
  284. constexpr void reset() noexcept
  285. {
  286. ptr_ = nullptr;
  287. }
  288. CPP_member
  289. constexpr auto swap(optional_base & that) //
  290. noexcept(is_nothrow_swappable<T>::value) //
  291. -> CPP_ret(void)(
  292. requires swappable<T>)
  293. {
  294. if(ptr_ && that.ptr_)
  295. ranges::swap(*ptr_, *that.ptr_);
  296. else
  297. ranges::swap(ptr_, that.ptr_);
  298. }
  299. protected:
  300. template(typename U)(
  301. requires convertible_to<U &, T &>)
  302. constexpr T & construct_from(U && ref) noexcept
  303. {
  304. RANGES_EXPECT(!ptr_);
  305. ptr_ = detail::addressof(ref);
  306. return *ptr_;
  307. }
  308. template<typename U>
  309. constexpr void assign_from(U && that)
  310. {
  311. if(ptr_ && that.ptr_)
  312. *ptr_ = *that.ptr_;
  313. else
  314. ptr_ = that.ptr_;
  315. }
  316. private:
  317. T * ptr_ = nullptr;
  318. };
  319. template<typename T>
  320. struct optional_copy : optional_base<T>
  321. {
  322. optional_copy() = default;
  323. optional_copy(optional_copy const & that) noexcept(
  324. std::is_nothrow_copy_constructible<T>::value)
  325. {
  326. if(that.has_value())
  327. this->construct_from(*that);
  328. }
  329. optional_copy(optional_copy &&) = default;
  330. optional_copy & operator=(optional_copy const &) = default;
  331. optional_copy & operator=(optional_copy &&) = default;
  332. using optional_base<T>::optional_base;
  333. };
  334. template<typename T>
  335. using copy_construct_layer =
  336. meta::if_c<std::is_copy_constructible<T>::value &&
  337. !detail::is_trivially_copy_constructible_v<T>,
  338. optional_copy<T>, optional_base<T>>;
  339. template<typename T>
  340. struct optional_move : copy_construct_layer<T>
  341. {
  342. optional_move() = default;
  343. optional_move(optional_move const &) = default;
  344. optional_move(optional_move && that) noexcept(
  345. std::is_nothrow_move_constructible<T>::value)
  346. {
  347. if(that.has_value())
  348. this->construct_from(std::move(*that));
  349. }
  350. optional_move & operator=(optional_move const &) = default;
  351. optional_move & operator=(optional_move &&) = default;
  352. using copy_construct_layer<T>::copy_construct_layer;
  353. };
  354. template<typename T>
  355. using move_construct_layer =
  356. meta::if_c<std::is_move_constructible<T>::value &&
  357. !detail::is_trivially_move_constructible_v<T>,
  358. optional_move<T>, copy_construct_layer<T>>;
  359. template<typename T>
  360. struct optional_copy_assign : move_construct_layer<T>
  361. {
  362. optional_copy_assign() = default;
  363. optional_copy_assign(optional_copy_assign const &) = default;
  364. optional_copy_assign(optional_copy_assign &&) = default;
  365. optional_copy_assign & operator=(optional_copy_assign const & that) //
  366. noexcept(std::is_nothrow_copy_constructible<T>::value &&
  367. std::is_nothrow_copy_assignable<T>::value)
  368. {
  369. this->assign_from(that);
  370. return *this;
  371. }
  372. optional_copy_assign & operator=(optional_copy_assign &&) = default;
  373. using move_construct_layer<T>::move_construct_layer;
  374. };
  375. template<typename T>
  376. struct deleted_copy_assign : move_construct_layer<T>
  377. {
  378. deleted_copy_assign() = default;
  379. deleted_copy_assign(deleted_copy_assign const &) = default;
  380. deleted_copy_assign(deleted_copy_assign &&) = default;
  381. deleted_copy_assign & operator=(deleted_copy_assign const &) = delete;
  382. deleted_copy_assign & operator=(deleted_copy_assign &&) = default;
  383. using move_construct_layer<T>::move_construct_layer;
  384. };
  385. template<typename T>
  386. using copy_assign_layer = meta::if_c<
  387. std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
  388. meta::if_c<std::is_reference<T>::value ||
  389. !(detail::is_trivially_copy_constructible_v<T> &&
  390. detail::is_trivially_copy_assignable_v<T>),
  391. optional_copy_assign<T>, move_construct_layer<T>>,
  392. deleted_copy_assign<T>>;
  393. template<typename T>
  394. struct optional_move_assign : copy_assign_layer<T>
  395. {
  396. optional_move_assign() = default;
  397. optional_move_assign(optional_move_assign const &) = default;
  398. optional_move_assign(optional_move_assign &&) = default;
  399. optional_move_assign & operator=(optional_move_assign const &) = default;
  400. optional_move_assign & operator=(optional_move_assign && that) noexcept(
  401. std::is_nothrow_move_constructible<T>::value &&
  402. std::is_nothrow_move_assignable<T>::value)
  403. {
  404. this->assign_from(std::move(that));
  405. return *this;
  406. }
  407. using copy_assign_layer<T>::copy_assign_layer;
  408. };
  409. template<typename T>
  410. struct deleted_move_assign : copy_assign_layer<T>
  411. {
  412. deleted_move_assign() = default;
  413. deleted_move_assign(deleted_move_assign const &) = default;
  414. deleted_move_assign(deleted_move_assign &&) = default;
  415. deleted_move_assign & operator=(deleted_move_assign const &) = default;
  416. deleted_move_assign & operator=(deleted_move_assign &&) = delete;
  417. using copy_assign_layer<T>::copy_assign_layer;
  418. };
  419. template<typename T>
  420. using move_assign_layer = meta::if_c<
  421. std::is_move_constructible<T>::value && std::is_move_assignable<T>::value,
  422. meta::if_c<std::is_reference<T>::value ||
  423. !(detail::is_trivially_move_constructible_v<T> &&
  424. detail::is_trivially_move_assignable_v<T>),
  425. optional_move_assign<T>, copy_assign_layer<T>>,
  426. deleted_move_assign<T>>;
  427. } // namespace optional_adl
  428. } // namespace detail
  429. /// \endcond
  430. // clang-format off
  431. /// \concept optional_should_convert
  432. /// \brief The \c optional_should_convert concept
  433. template<typename U, typename T>
  434. CPP_concept optional_should_convert =
  435. !(
  436. constructible_from<T, optional<U> & > ||
  437. constructible_from<T, optional<U> && > ||
  438. constructible_from<T, optional<U> const & > ||
  439. constructible_from<T, optional<U> const &&> ||
  440. convertible_to<optional<U> &, T> ||
  441. convertible_to<optional<U> &&, T> ||
  442. convertible_to<optional<U> const &, T> ||
  443. convertible_to<optional<U> const &&, T>
  444. );
  445. /// \concept optional_should_convert_assign
  446. /// \brief The \c optional_should_convert_assign concept
  447. template<typename U, typename T>
  448. CPP_concept optional_should_convert_assign =
  449. optional_should_convert<U, T> &&
  450. !(assignable_from<T &, optional<U> &> ||
  451. assignable_from<T &, optional<U> &&> ||
  452. assignable_from<T &, optional<U> const &> ||
  453. assignable_from<T &, optional<U> const &&>);
  454. // clang-format on
  455. template<typename T>
  456. struct optional : detail::optional_adl::move_assign_layer<T>
  457. {
  458. private:
  459. using base_t = detail::optional_adl::move_assign_layer<T>;
  460. public:
  461. CPP_assert(destructible<T>);
  462. static_assert(std::is_object<T>::value || std::is_lvalue_reference<T>::value, "");
  463. static_assert((bool)!same_as<nullopt_t, uncvref_t<T>>, "");
  464. static_assert((bool)!same_as<in_place_t, uncvref_t<T>>, "");
  465. using value_type = meta::_t<std::remove_cv<T>>;
  466. constexpr optional() noexcept
  467. {}
  468. constexpr optional(nullopt_t) noexcept
  469. : optional{}
  470. {}
  471. optional(optional const &) = default;
  472. optional(optional &&) = default;
  473. using base_t::base_t;
  474. template(typename E, typename... Args)(
  475. requires constructible_from<T, std::initializer_list<E> &, Args...>)
  476. constexpr explicit optional(in_place_t, std::initializer_list<E> il,
  477. Args &&... args) //
  478. noexcept(std::is_nothrow_constructible<T, std::initializer_list<E> &,
  479. Args...>::value)
  480. : base_t(in_place, il, static_cast<Args &&>(args)...)
  481. {}
  482. #if defined(__cpp_conditional_explicit) && __cpp_conditional_explicit > 0
  483. template(typename U = T)(
  484. requires (!same_as<detail::decay_t<U>, in_place_t>) AND
  485. (!same_as<detail::decay_t<U>, optional>) AND
  486. constructible_from<T, U>)
  487. constexpr explicit(!convertible_to<U, T>) optional(U && v)
  488. : base_t(in_place, static_cast<U &&>(v))
  489. {}
  490. template(typename U)(
  491. requires optional_should_convert<U, T> AND
  492. constructible_from<T, U const &>)
  493. explicit(!convertible_to<U const &, T>) optional(optional<U> const & that)
  494. {
  495. if(that.has_value())
  496. base_t::construct_from(*that);
  497. }
  498. #else
  499. template(typename U = T)(
  500. requires (!same_as<detail::decay_t<U>, in_place_t>) AND
  501. (!same_as<detail::decay_t<U>, optional>) AND
  502. constructible_from<T, U> AND
  503. convertible_to<U, T>)
  504. constexpr optional(U && v)
  505. : base_t(in_place, static_cast<U &&>(v))
  506. {}
  507. template(typename U = T)(
  508. requires (!same_as<detail::decay_t<U>, in_place_t>) AND
  509. (!same_as<detail::decay_t<U>, optional>) AND
  510. constructible_from<T, U> AND
  511. (!convertible_to<U, T>))
  512. constexpr explicit optional(U && v)
  513. : base_t(in_place, static_cast<U &&>(v))
  514. {}
  515. template(typename U)(
  516. requires optional_should_convert<U, T> AND
  517. constructible_from<T, U const &> AND
  518. convertible_to<U const &, T>)
  519. optional(optional<U> const & that)
  520. {
  521. if(that.has_value())
  522. base_t::construct_from(*that);
  523. }
  524. template(typename U)(
  525. requires optional_should_convert<U, T> AND
  526. constructible_from<T, U const &> AND
  527. (!convertible_to<U const &, T>))
  528. explicit optional(optional<U> const & that)
  529. {
  530. if(that.has_value())
  531. base_t::construct_from(*that);
  532. }
  533. #endif
  534. template(typename U)(
  535. requires optional_should_convert<U, T> AND constructible_from<T, U> AND
  536. convertible_to<U, T>)
  537. optional(optional<U> && that)
  538. {
  539. if(that.has_value())
  540. base_t::construct_from(detail::move(*that));
  541. }
  542. template(typename U)(
  543. requires optional_should_convert<U, T> AND constructible_from<T, U> AND
  544. (!convertible_to<U, T>)) //
  545. explicit optional(optional<U> && that)
  546. {
  547. if(that.has_value())
  548. base_t::construct_from(detail::move(*that));
  549. }
  550. constexpr optional & operator=(nullopt_t) noexcept
  551. {
  552. reset();
  553. return *this;
  554. }
  555. optional & operator=(optional const &) = default;
  556. optional & operator=(optional &&) = default;
  557. template(typename U = T)(
  558. requires (!same_as<optional, detail::decay_t<U>>) AND
  559. (!(satisfies<T, std::is_scalar> && same_as<T, detail::decay_t<U>>)) AND
  560. constructible_from<T, U> AND
  561. assignable_from<T &, U>)
  562. constexpr optional & operator=(U && u) noexcept(
  563. std::is_nothrow_constructible<T, U>::value &&
  564. std::is_nothrow_assignable<T &, U>::value)
  565. {
  566. if(has_value())
  567. **this = static_cast<U &&>(u);
  568. else
  569. base_t::construct_from(static_cast<U &&>(u));
  570. return *this;
  571. }
  572. template(typename U)(
  573. requires optional_should_convert_assign<U, T> AND
  574. constructible_from<T, const U &> AND
  575. assignable_from<T &, const U &>)
  576. constexpr optional & operator=(optional<U> const & that)
  577. {
  578. base_t::assign_from(that);
  579. return *this;
  580. }
  581. template(typename U)(
  582. requires optional_should_convert_assign<U, T> AND
  583. constructible_from<T, U> AND
  584. assignable_from<T &, U>)
  585. constexpr optional & operator=(optional<U> && that)
  586. {
  587. base_t::assign_from(std::move(that));
  588. return *this;
  589. }
  590. template(typename I)(
  591. requires constructible_from<T, decltype(*std::declval<const I &>())>)
  592. T & emplace_deref(const I & it)
  593. {
  594. reset();
  595. return base_t::construct_from_deref(it);
  596. }
  597. template(typename... Args)(
  598. requires constructible_from<T, Args...>)
  599. T & emplace(Args &&... args) noexcept(
  600. std::is_nothrow_constructible<T, Args...>::value)
  601. {
  602. reset();
  603. return base_t::construct_from(static_cast<Args &&>(args)...);
  604. }
  605. template(typename E, typename... Args)(
  606. requires constructible_from<T, std::initializer_list<E> &, Args...>)
  607. T & emplace(std::initializer_list<E> il, Args &&... args) noexcept(
  608. std::is_nothrow_constructible<T, std::initializer_list<E> &, Args...>::value)
  609. {
  610. reset();
  611. return base_t::construct_from(il, static_cast<Args &&>(args)...);
  612. }
  613. using base_t::swap;
  614. using base_t::operator->;
  615. using base_t::operator*;
  616. constexpr explicit operator bool() const noexcept
  617. {
  618. return has_value();
  619. }
  620. using base_t::has_value;
  621. constexpr T const & value() const &
  622. {
  623. return (has_value() || detail::throw_bad_optional_access()), **this;
  624. }
  625. constexpr T & value() &
  626. {
  627. return (has_value() || detail::throw_bad_optional_access()), **this;
  628. }
  629. constexpr T const && value() const &&
  630. {
  631. return (has_value() || detail::throw_bad_optional_access()),
  632. detail::move(**this);
  633. }
  634. constexpr T && value() &&
  635. {
  636. return (has_value() || detail::throw_bad_optional_access()),
  637. detail::move(**this);
  638. }
  639. template(typename U)(
  640. requires copy_constructible<T> AND convertible_to<U, T>)
  641. constexpr T value_or(U && u) const &
  642. {
  643. return has_value() ? **this : static_cast<T>((U &&) u);
  644. }
  645. template(typename U)(
  646. requires move_constructible<T> AND convertible_to<U, T>)
  647. constexpr T value_or(U && u) &&
  648. {
  649. return has_value() ? detail::move(**this) : static_cast<T>((U &&) u);
  650. }
  651. using base_t::reset;
  652. };
  653. /// \cond
  654. namespace detail
  655. {
  656. namespace optional_adl
  657. {
  658. constexpr bool convert_bool(bool b) noexcept
  659. {
  660. return b;
  661. }
  662. // Relational operators [optional.relops]
  663. template<typename T, typename U>
  664. constexpr auto operator==(optional<T> const & x, optional<U> const & y) //
  665. noexcept(noexcept(convert_bool(*x == *y)))
  666. -> decltype(convert_bool(*x == *y))
  667. {
  668. return x.has_value() == y.has_value() && (!x || convert_bool(*x == *y));
  669. }
  670. template<typename T, typename U>
  671. constexpr auto operator!=(optional<T> const & x, optional<U> const & y) //
  672. noexcept(noexcept(convert_bool(*x != *y)))
  673. -> decltype(convert_bool(*x != *y))
  674. {
  675. return x.has_value() != y.has_value() || (x && convert_bool(*x != *y));
  676. }
  677. template<typename T, typename U>
  678. constexpr auto operator<(optional<T> const & x, optional<U> const & y) //
  679. noexcept(noexcept(convert_bool(*x < *y)))
  680. -> decltype(convert_bool(*x < *y))
  681. {
  682. return y && (!x || convert_bool(*x < *y));
  683. }
  684. template<typename T, typename U>
  685. constexpr auto operator>(optional<T> const & x, optional<U> const & y) //
  686. noexcept(noexcept(convert_bool(*x > *y)))
  687. -> decltype(convert_bool(*x > *y))
  688. {
  689. return x && (!y || convert_bool(*x > *y));
  690. }
  691. template<typename T, typename U>
  692. constexpr auto operator<=(optional<T> const & x, optional<U> const & y) //
  693. noexcept(noexcept(convert_bool(*x <= *y)))
  694. -> decltype(convert_bool(*x <= *y))
  695. {
  696. return !x || (y && convert_bool(*x <= *y));
  697. }
  698. template<typename T, typename U>
  699. constexpr auto operator>=(optional<T> const & x, optional<U> const & y) //
  700. noexcept(noexcept(convert_bool(*x >= *y)))
  701. -> decltype(convert_bool(*x >= *y))
  702. {
  703. return !y || (x && convert_bool(*x >= *y));
  704. }
  705. // Comparisons with nullopt [optional.nullops]
  706. template<typename T>
  707. constexpr bool operator==(optional<T> const & x, nullopt_t) noexcept
  708. {
  709. return !x;
  710. }
  711. template<typename T>
  712. constexpr bool operator==(nullopt_t, optional<T> const & x) noexcept
  713. {
  714. return !x;
  715. }
  716. template<typename T>
  717. constexpr bool operator!=(optional<T> const & x, nullopt_t) noexcept
  718. {
  719. return !!x;
  720. }
  721. template<typename T>
  722. constexpr bool operator!=(nullopt_t, optional<T> const & x) noexcept
  723. {
  724. return !!x;
  725. }
  726. template<typename T>
  727. constexpr bool operator<(optional<T> const &, nullopt_t) noexcept
  728. {
  729. return false;
  730. }
  731. template<typename T>
  732. constexpr bool operator<(nullopt_t, optional<T> const & x) noexcept
  733. {
  734. return !!x;
  735. }
  736. template<typename T>
  737. constexpr bool operator>(optional<T> const & x, nullopt_t) noexcept
  738. {
  739. return !!x;
  740. }
  741. template<typename T>
  742. constexpr bool operator>(nullopt_t, optional<T> const &) noexcept
  743. {
  744. return false;
  745. }
  746. template<typename T>
  747. constexpr bool operator<=(optional<T> const & x, nullopt_t) noexcept
  748. {
  749. return !x;
  750. }
  751. template<typename T>
  752. constexpr bool operator<=(nullopt_t, optional<T> const &) noexcept
  753. {
  754. return true;
  755. }
  756. template<typename T>
  757. constexpr bool operator>=(optional<T> const &, nullopt_t) noexcept
  758. {
  759. return true;
  760. }
  761. template<typename T>
  762. constexpr bool operator>=(nullopt_t, optional<T> const & x) noexcept
  763. {
  764. return !x;
  765. }
  766. // Comparisons with T [optional.comp_with_t]
  767. template<typename T, typename U>
  768. constexpr auto operator==(optional<T> const & x, U const & y) //
  769. noexcept(noexcept(convert_bool(*x == y))) //
  770. -> decltype(convert_bool(*x == y))
  771. {
  772. return x && convert_bool(*x == y);
  773. }
  774. template<typename T, typename U>
  775. constexpr auto operator==(T const & x, optional<U> const & y) //
  776. noexcept(noexcept(convert_bool(x == *y))) //
  777. -> decltype(convert_bool(x == *y))
  778. {
  779. return y && convert_bool(x == *y);
  780. }
  781. template<typename T, typename U>
  782. constexpr auto operator!=(optional<T> const & x, U const & y) //
  783. noexcept(noexcept(convert_bool(*x != y))) //
  784. -> decltype(convert_bool(*x != y))
  785. {
  786. return !x || convert_bool(*x != y);
  787. }
  788. template<typename T, typename U>
  789. constexpr auto operator!=(T const & x, optional<U> const & y) //
  790. noexcept(noexcept(convert_bool(x != *y))) //
  791. -> decltype(convert_bool(x != *y))
  792. {
  793. return !y || convert_bool(x != *y);
  794. }
  795. template<typename T, typename U>
  796. constexpr auto operator<(optional<T> const & x, U const & y) //
  797. noexcept(noexcept(convert_bool(*x < y))) //
  798. -> decltype(convert_bool(*x < y))
  799. {
  800. return !x || convert_bool(*x < y);
  801. }
  802. template<typename T, typename U>
  803. constexpr auto operator<(T const & x, optional<U> const & y) //
  804. noexcept(noexcept(convert_bool(x < *y))) //
  805. -> decltype(convert_bool(x < *y))
  806. {
  807. return y && convert_bool(x < *y);
  808. }
  809. template<typename T, typename U>
  810. constexpr auto operator>(optional<T> const & x, U const & y) //
  811. noexcept(noexcept(convert_bool(*x > y))) -> decltype(convert_bool(*x > y))
  812. {
  813. return x && convert_bool(*x > y);
  814. }
  815. template<typename T, typename U>
  816. constexpr auto operator>(T const & x, optional<U> const & y) //
  817. noexcept(noexcept(convert_bool(x > *y))) //
  818. -> decltype(convert_bool(x > *y))
  819. {
  820. return !y || convert_bool(x > *y);
  821. }
  822. template<typename T, typename U>
  823. constexpr auto operator<=(optional<T> const & x, U const & y) //
  824. noexcept(noexcept(convert_bool(*x <= y))) //
  825. -> decltype(convert_bool(*x <= y))
  826. {
  827. return !x || convert_bool(*x <= y);
  828. }
  829. template<typename T, typename U>
  830. constexpr auto operator<=(T const & x, optional<U> const & y) //
  831. noexcept(noexcept(convert_bool(x <= *y))) //
  832. -> decltype(convert_bool(x <= *y))
  833. {
  834. return y && convert_bool(x <= *y);
  835. }
  836. template<typename T, typename U>
  837. constexpr auto operator>=(optional<T> const & x, U const & y) //
  838. noexcept(noexcept(convert_bool(*x >= y))) //
  839. -> decltype(convert_bool(*x >= y))
  840. {
  841. return x && convert_bool(*x >= y);
  842. }
  843. template<typename T, typename U>
  844. constexpr auto operator>=(T const & x, optional<U> const & y) //
  845. noexcept(noexcept(convert_bool(x >= *y))) //
  846. -> decltype(convert_bool(x >= *y))
  847. {
  848. return !y || convert_bool(x >= *y);
  849. }
  850. // clang-format off
  851. template<typename T>
  852. auto CPP_auto_fun(swap)(optional<T> &x, optional<T> &y)
  853. (
  854. return x.swap(y)
  855. )
  856. // clang-format on
  857. } // namespace optional_adl
  858. } // namespace detail
  859. /// \endcond
  860. // clang-format off
  861. template<typename T>
  862. constexpr auto CPP_auto_fun(make_optional)(T &&t)
  863. (
  864. return optional<detail::decay_t<T>>{static_cast<T &&>(t)}
  865. )
  866. template<typename T, typename... Args>
  867. constexpr auto CPP_auto_fun(make_optional)(Args &&... args)
  868. (
  869. return optional<T>{in_place, static_cast<Args &&>(args)...}
  870. )
  871. template<typename T, typename U, typename... Args>
  872. constexpr auto CPP_auto_fun(make_optional)(std::initializer_list<U> il,
  873. Args &&... args)
  874. (
  875. return optional<T>{in_place, il, static_cast<Args &&>(args)...}
  876. )
  877. // clang-format on
  878. /// \cond
  879. namespace detail
  880. {
  881. template<typename T, typename Tag = void, bool Enable = true>
  882. struct non_propagating_cache : optional<T>
  883. {
  884. non_propagating_cache() = default;
  885. constexpr non_propagating_cache(nullopt_t) noexcept
  886. {}
  887. constexpr non_propagating_cache(non_propagating_cache const &) noexcept
  888. : optional<T>{}
  889. {}
  890. constexpr non_propagating_cache(non_propagating_cache && that) noexcept
  891. : optional<T>{}
  892. {
  893. that.optional<T>::reset();
  894. }
  895. constexpr non_propagating_cache & operator=(
  896. non_propagating_cache const &) noexcept
  897. {
  898. optional<T>::reset();
  899. return *this;
  900. }
  901. constexpr non_propagating_cache & operator=(
  902. non_propagating_cache && that) noexcept
  903. {
  904. that.optional<T>::reset();
  905. optional<T>::reset();
  906. return *this;
  907. }
  908. using optional<T>::operator=;
  909. template<class I>
  910. constexpr T & emplace_deref(const I & i)
  911. {
  912. return optional<T>::emplace(*i);
  913. }
  914. };
  915. template<typename T, typename Tag>
  916. struct non_propagating_cache<T, Tag, false>
  917. {};
  918. } // namespace detail
  919. /// \endcond
  920. } // namespace ranges
  921. #include <range/v3/detail/epilogue.hpp>
  922. #endif