blob: 27ac1c0516e00a495d632b2f3eb084930819a911 [file] [log] [blame]
Brian Silvermanda861352019-02-02 16:42:28 -08001
2///
3// optional - An implementation of std::optional with extensions
4// Written in 2017 by Simon Brand (@TartanLlama)
5//
6// To the extent possible under law, the author(s) have dedicated all
7// copyright and related and neighboring rights to this software to the
8// public domain worldwide. This software is distributed without any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software. If not, see
12// <http://creativecommons.org/publicdomain/zero/1.0/>.
13///
14
15#ifndef TL_OPTIONAL_HPP
16#define TL_OPTIONAL_HPP
17
18#define TL_OPTIONAL_VERSION_MAJOR 0
19#define TL_OPTIONAL_VERSION_MINOR 5
20
21#include <exception>
22#include <functional>
23#include <new>
24#include <type_traits>
25#include <utility>
26
27#if (defined(_MSC_VER) && _MSC_VER == 1900)
28#define TL_OPTIONAL_MSVC2015
29#endif
30
Brian Silverman019de8b2019-02-02 16:55:30 -080031// TODO(Brian): We use libstdc++ with clang too. Sort this out nicely.
Brian Silvermanda861352019-02-02 16:42:28 -080032#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
Brian Silverman019de8b2019-02-02 16:55:30 -080033 !(defined(__clang__) && defined(_LIBCPP_VERSION)))
Brian Silvermanda861352019-02-02 16:42:28 -080034#define TL_OPTIONAL_GCC49
35#endif
36
37#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \
38 !defined(__clang__))
39#define TL_OPTIONAL_GCC54
40#endif
41
42#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \
43 !defined(__clang__))
44#define TL_OPTIONAL_GCC55
45#endif
46
Brian Silverman019de8b2019-02-02 16:55:30 -080047#ifdef TL_OPTIONAL_GCC49
Brian Silvermanda861352019-02-02 16:42:28 -080048// GCC < 5 doesn't support overloading on const&& for member functions
49#define TL_OPTIONAL_NO_CONSTRR
50
51// GCC < 5 doesn't support some standard C++11 type traits
52#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
53 std::has_trivial_copy_constructor<T>::value
54#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
55
56// This one will be different for GCC 5.7 if it's ever supported
57#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
58
59// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks std::vector
60// for non-copyable types
61#elif (defined(__GNUC__) && __GNUC__ < 8 && \
62 !defined(__clang__))
63#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
64#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
65namespace tl {
66 namespace detail {
67 template<class T>
68 struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T>{};
69#ifdef _GLIBCXX_VECTOR
70 template<class T, class A>
71 struct is_trivially_copy_constructible<std::vector<T,A>>
72 : std::is_trivially_copy_constructible<T>{};
73#endif
74 }
75}
76#endif
77
78#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
79 tl::detail::is_trivially_copy_constructible<T>::value
80#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
81 std::is_trivially_copy_assignable<T>::value
82#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
83#else
84#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
85 std::is_trivially_copy_constructible<T>::value
86#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
87 std::is_trivially_copy_assignable<T>::value
88#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
89#endif
90
91#if __cplusplus > 201103L
Brian Silverman019de8b2019-02-02 16:55:30 -080092// TODO(Brian): Re-enable this once we have full C++14 support.
93//#define TL_OPTIONAL_CXX14
Brian Silvermanda861352019-02-02 16:42:28 -080094#endif
95
96// constexpr implies const in C++11, not C++14
97#if (__cplusplus == 201103L || defined(TL_OPTIONAL_MSVC2015) || \
98 defined(TL_OPTIONAL_GCC49))
99/// \exclude
100#define TL_OPTIONAL_11_CONSTEXPR
101#else
102/// \exclude
103#define TL_OPTIONAL_11_CONSTEXPR constexpr
104#endif
105
106namespace tl {
107#ifndef TL_MONOSTATE_INPLACE_MUTEX
108#define TL_MONOSTATE_INPLACE_MUTEX
109/// \brief Used to represent an optional with no data; essentially a bool
110class monostate {};
111
112/// \brief A tag type to tell optional to construct its value in-place
113struct in_place_t {
114 explicit in_place_t() = default;
115};
116/// \brief A tag to tell optional to construct its value in-place
117static constexpr in_place_t in_place{};
118#endif
119
120template <class T> class optional;
121
122/// \exclude
123namespace detail {
124#ifndef TL_TRAITS_MUTEX
125#define TL_TRAITS_MUTEX
126// C++14-style aliases for brevity
127template <class T> using remove_const_t = typename std::remove_const<T>::type;
128template <class T>
129using remove_reference_t = typename std::remove_reference<T>::type;
130template <class T> using decay_t = typename std::decay<T>::type;
131template <bool E, class T = void>
132using enable_if_t = typename std::enable_if<E, T>::type;
133template <bool B, class T, class F>
134using conditional_t = typename std::conditional<B, T, F>::type;
135
136// std::conjunction from C++17
137template <class...> struct conjunction : std::true_type {};
138template <class B> struct conjunction<B> : B {};
139template <class B, class... Bs>
140struct conjunction<B, Bs...>
141 : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
142
143#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
144#define TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
145#endif
146
147// In C++11 mode, there's an issue in libc++'s std::mem_fn
148// which results in a hard-error when using it in a noexcept expression
149// in some cases. This is a check to workaround the common failing case.
150#ifdef TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
151template <class T> struct is_pointer_to_non_const_member_func : std::false_type{};
152template <class T, class Ret, class... Args>
153struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...)> : std::true_type{};
154template <class T, class Ret, class... Args>
155struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...)&> : std::true_type{};
156template <class T, class Ret, class... Args>
157struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...)&&> : std::true_type{};
158template <class T, class Ret, class... Args>
159struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...) volatile> : std::true_type{};
160template <class T, class Ret, class... Args>
161struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...) volatile&> : std::true_type{};
162template <class T, class Ret, class... Args>
163struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...) volatile&&> : std::true_type{};
164
165template <class T> struct is_const_or_const_ref : std::false_type{};
166template <class T> struct is_const_or_const_ref<T const&> : std::true_type{};
167template <class T> struct is_const_or_const_ref<T const> : std::true_type{};
168#endif
169
170// std::invoke from C++17
171// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
172template <typename Fn, typename... Args,
173#ifdef TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
174 typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value
175 && is_const_or_const_ref<Args...>::value)>,
176#endif
177 typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
178 int = 0>
179constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
180 noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
181 -> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
182 return std::mem_fn(f)(std::forward<Args>(args)...);
183}
184
185template <typename Fn, typename... Args,
186 typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
187constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
188 noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
189 -> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
190 return std::forward<Fn>(f)(std::forward<Args>(args)...);
191}
192
193// std::invoke_result from C++17
194template <class F, class, class... Us> struct invoke_result_impl;
195
196template <class F, class... Us>
197struct invoke_result_impl<
198 F, decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()),
199 Us...> {
200 using type = decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
201};
202
203template <class F, class... Us>
204using invoke_result = invoke_result_impl<F, void, Us...>;
205
206template <class F, class... Us>
207using invoke_result_t = typename invoke_result<F, Us...>::type;
208#endif
209
210// std::void_t from C++17
211template <class...> struct voider { using type = void; };
212template <class... Ts> using void_t = typename voider<Ts...>::type;
213
214// Trait for checking if a type is a tl::optional
215template <class T> struct is_optional_impl : std::false_type {};
216template <class T> struct is_optional_impl<optional<T>> : std::true_type {};
217template <class T> using is_optional = is_optional_impl<decay_t<T>>;
218
219// Change void to tl::monostate
220template <class U>
221using fixup_void = conditional_t<std::is_void<U>::value, monostate, U>;
222
223template <class F, class U, class = invoke_result_t<F, U>>
224using get_map_return = optional<fixup_void<invoke_result_t<F, U>>>;
225
226// Check if invoking F for some Us returns void
227template <class F, class = void, class... U> struct returns_void_impl;
228template <class F, class... U>
229struct returns_void_impl<F, void_t<invoke_result_t<F, U...>>, U...>
230 : std::is_void<invoke_result_t<F, U...>> {};
231template <class F, class... U>
232using returns_void = returns_void_impl<F, void, U...>;
233
234template <class T, class... U>
235using enable_if_ret_void = enable_if_t<returns_void<T &&, U...>::value>;
236
237template <class T, class... U>
238using disable_if_ret_void = enable_if_t<!returns_void<T &&, U...>::value>;
239
240template <class T, class U>
241using enable_forward_value =
242 detail::enable_if_t<std::is_constructible<T, U &&>::value &&
243 !std::is_same<detail::decay_t<U>, in_place_t>::value &&
244 !std::is_same<optional<T>, detail::decay_t<U>>::value>;
245
246template <class T, class U, class Other>
247using enable_from_other = detail::enable_if_t<
248 std::is_constructible<T, Other>::value &&
249 !std::is_constructible<T, optional<U> &>::value &&
250 !std::is_constructible<T, optional<U> &&>::value &&
251 !std::is_constructible<T, const optional<U> &>::value &&
252 !std::is_constructible<T, const optional<U> &&>::value &&
253 !std::is_convertible<optional<U> &, T>::value &&
254 !std::is_convertible<optional<U> &&, T>::value &&
255 !std::is_convertible<const optional<U> &, T>::value &&
256 !std::is_convertible<const optional<U> &&, T>::value>;
257
258template <class T, class U>
259using enable_assign_forward = detail::enable_if_t<
260 !std::is_same<optional<T>, detail::decay_t<U>>::value &&
261 !detail::conjunction<std::is_scalar<T>,
262 std::is_same<T, detail::decay_t<U>>>::value &&
263 std::is_constructible<T, U>::value && std::is_assignable<T &, U>::value>;
264
265template <class T, class U, class Other>
266using enable_assign_from_other = detail::enable_if_t<
267 std::is_constructible<T, Other>::value &&
268 std::is_assignable<T &, Other>::value &&
269 !std::is_constructible<T, optional<U> &>::value &&
270 !std::is_constructible<T, optional<U> &&>::value &&
271 !std::is_constructible<T, const optional<U> &>::value &&
272 !std::is_constructible<T, const optional<U> &&>::value &&
273 !std::is_convertible<optional<U> &, T>::value &&
274 !std::is_convertible<optional<U> &&, T>::value &&
275 !std::is_convertible<const optional<U> &, T>::value &&
276 !std::is_convertible<const optional<U> &&, T>::value &&
277 !std::is_assignable<T &, optional<U> &>::value &&
278 !std::is_assignable<T &, optional<U> &&>::value &&
279 !std::is_assignable<T &, const optional<U> &>::value &&
280 !std::is_assignable<T &, const optional<U> &&>::value>;
281
282#ifdef _MSC_VER
283// TODO make a version which works with MSVC
284template <class T, class U = T> struct is_swappable : std::true_type {};
285
286template <class T, class U = T> struct is_nothrow_swappable : std::true_type {};
287#else
288// https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
289namespace swap_adl_tests {
290// if swap ADL finds this then it would call std::swap otherwise (same
291// signature)
292struct tag {};
293
294template <class T> tag swap(T &, T &);
295template <class T, std::size_t N> tag swap(T (&a)[N], T (&b)[N]);
296
297// helper functions to test if an unqualified swap is possible, and if it
298// becomes std::swap
299template <class, class> std::false_type can_swap(...) noexcept(false);
300template <class T, class U,
301 class = decltype(swap(std::declval<T &>(), std::declval<U &>()))>
302std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T &>(),
303 std::declval<U &>())));
304
305template <class, class> std::false_type uses_std(...);
306template <class T, class U>
307std::is_same<decltype(swap(std::declval<T &>(), std::declval<U &>())), tag>
308uses_std(int);
309
310template <class T>
311struct is_std_swap_noexcept
312 : std::integral_constant<bool,
313 std::is_nothrow_move_constructible<T>::value &&
314 std::is_nothrow_move_assignable<T>::value> {};
315
316template <class T, std::size_t N>
317struct is_std_swap_noexcept<T[N]> : is_std_swap_noexcept<T> {};
318
319template <class T, class U>
320struct is_adl_swap_noexcept
321 : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
322} // namespace swap_adl_tests
323
324template <class T, class U = T>
325struct is_swappable
326 : std::integral_constant<
327 bool,
328 decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
329 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
330 (std::is_move_assignable<T>::value &&
331 std::is_move_constructible<T>::value))> {};
332
333template <class T, std::size_t N>
334struct is_swappable<T[N], T[N]>
335 : std::integral_constant<
336 bool,
337 decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
338 (!decltype(
339 detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value ||
340 is_swappable<T, T>::value)> {};
341
342template <class T, class U = T>
343struct is_nothrow_swappable
344 : std::integral_constant<
345 bool,
346 is_swappable<T, U>::value &&
347 ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value
348 &&detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
349 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
350 detail::swap_adl_tests::is_adl_swap_noexcept<T,
351 U>::value))> {
352};
353#endif
354
355// The storage base manages the actual storage, and correctly propagates
356// trivial destruction from T. This case is for when T is not trivially
357// destructible.
358template <class T, bool = ::std::is_trivially_destructible<T>::value>
359struct optional_storage_base {
360 TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
361 : m_dummy(), m_has_value(false) {}
362
363 template <class... U>
364 TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
365 : m_value(std::forward<U>(u)...), m_has_value(true) {}
366
367 ~optional_storage_base() {
368 if (m_has_value) {
369 m_value.~T();
370 m_has_value = false;
371 }
372 }
373
374 struct dummy {};
375 union {
376 dummy m_dummy;
377 T m_value;
378 };
379
380 bool m_has_value;
381};
382
383// This case is for when T is trivially destructible.
384template <class T> struct optional_storage_base<T, true> {
385 TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
386 : m_dummy(), m_has_value(false) {}
387
388 template <class... U>
389 TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
390 : m_value(std::forward<U>(u)...), m_has_value(true) {}
391
392 // No destructor, so this class is trivially destructible
393
394 struct dummy {};
395 union {
396 dummy m_dummy;
397 T m_value;
398 };
399
400 bool m_has_value = false;
401};
402
403// This base class provides some handy member functions which can be used in
404// further derived classes
405template <class T> struct optional_operations_base : optional_storage_base<T> {
406 using optional_storage_base<T>::optional_storage_base;
407
408 void hard_reset() noexcept {
409 get().~T();
410 this->m_has_value = false;
411 }
412
413 template <class... Args> void construct(Args &&... args) noexcept {
414 new (std::addressof(this->m_value)) T(std::forward<Args>(args)...);
415 this->m_has_value = true;
416 }
417
418 template <class Opt> void assign(Opt &&rhs) {
419 if (this->has_value()) {
420 if (rhs.has_value()) {
421 this->m_value = std::forward<Opt>(rhs).get();
422 } else {
423 this->m_value.~T();
424 this->m_has_value = false;
425 }
426 }
427
428 else if (rhs.has_value()) {
429 construct(std::forward<Opt>(rhs).get());
430 }
431 }
432
433 bool has_value() const { return this->m_has_value; }
434
435 TL_OPTIONAL_11_CONSTEXPR T &get() & { return this->m_value; }
436 TL_OPTIONAL_11_CONSTEXPR const T &get() const & { return this->m_value; }
437 TL_OPTIONAL_11_CONSTEXPR T &&get() && { return std::move(this->m_value); }
438#ifndef TL_OPTIONAL_NO_CONSTRR
439 constexpr const T &&get() const && { return std::move(this->m_value); }
440#endif
441};
442
443// This class manages conditionally having a trivial copy constructor
444// This specialization is for when T is trivially copy constructible
445template <class T, bool = TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
446struct optional_copy_base : optional_operations_base<T> {
447 using optional_operations_base<T>::optional_operations_base;
448};
449
450// This specialization is for when T is not trivially copy constructible
451template <class T>
452struct optional_copy_base<T, false> : optional_operations_base<T> {
453 using optional_operations_base<T>::optional_operations_base;
454
455 optional_copy_base() = default;
456 optional_copy_base(const optional_copy_base &rhs) {
457 if (rhs.has_value()) {
458 this->construct(rhs.get());
459 } else {
460 this->m_has_value = false;
461 }
462 }
463
464 optional_copy_base(optional_copy_base &&rhs) = default;
465 optional_copy_base &operator=(const optional_copy_base &rhs) = default;
466 optional_copy_base &operator=(optional_copy_base &&rhs) = default;
467};
468
469// This class manages conditionally having a trivial move constructor
470// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
471// doesn't implement an analogue to std::is_trivially_move_constructible. We
472// have to make do with a non-trivial move constructor even if T is trivially
473// move constructible
474#ifndef TL_OPTIONAL_GCC49
475template <class T, bool = std::is_trivially_move_constructible<T>::value>
476struct optional_move_base : optional_copy_base<T> {
477 using optional_copy_base<T>::optional_copy_base;
478};
479#else
480template <class T, bool = false> struct optional_move_base;
481#endif
482template <class T> struct optional_move_base<T, false> : optional_copy_base<T> {
483 using optional_copy_base<T>::optional_copy_base;
484
485 optional_move_base() = default;
486 optional_move_base(const optional_move_base &rhs) = default;
487
488 optional_move_base(optional_move_base &&rhs) noexcept(
489 std::is_nothrow_move_constructible<T>::value) {
490 if (rhs.has_value()) {
491 this->construct(std::move(rhs.get()));
492 } else {
493 this->m_has_value = false;
494 }
495 }
496 optional_move_base &operator=(const optional_move_base &rhs) = default;
497 optional_move_base &operator=(optional_move_base &&rhs) = default;
498};
499
500// This class manages conditionally having a trivial copy assignment operator
501template <class T, bool = TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) &&
502 TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) &&
503 TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
504struct optional_copy_assign_base : optional_move_base<T> {
505 using optional_move_base<T>::optional_move_base;
506};
507
508template <class T>
509struct optional_copy_assign_base<T, false> : optional_move_base<T> {
510 using optional_move_base<T>::optional_move_base;
511
512 optional_copy_assign_base() = default;
513 optional_copy_assign_base(const optional_copy_assign_base &rhs) = default;
514
515 optional_copy_assign_base(optional_copy_assign_base &&rhs) = default;
516 optional_copy_assign_base &operator=(const optional_copy_assign_base &rhs) {
517 this->assign(rhs);
518 return *this;
519 }
520 optional_copy_assign_base &
521 operator=(optional_copy_assign_base &&rhs) = default;
522};
523
524// This class manages conditionally having a trivial move assignment operator
525// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
526// doesn't implement an analogue to std::is_trivially_move_assignable. We have
527// to make do with a non-trivial move assignment operator even if T is trivially
528// move assignable
529#ifndef TL_OPTIONAL_GCC49
530template <class T, bool = std::is_trivially_destructible<T>::value
531 &&std::is_trivially_move_constructible<T>::value
532 &&std::is_trivially_move_assignable<T>::value>
533struct optional_move_assign_base : optional_copy_assign_base<T> {
534 using optional_copy_assign_base<T>::optional_copy_assign_base;
535};
536#else
537template <class T, bool = false> struct optional_move_assign_base;
538#endif
539
540template <class T>
541struct optional_move_assign_base<T, false> : optional_copy_assign_base<T> {
542 using optional_copy_assign_base<T>::optional_copy_assign_base;
543
544 optional_move_assign_base() = default;
545 optional_move_assign_base(const optional_move_assign_base &rhs) = default;
546
547 optional_move_assign_base(optional_move_assign_base &&rhs) = default;
548
549 optional_move_assign_base &
550 operator=(const optional_move_assign_base &rhs) = default;
551
552 optional_move_assign_base &
553 operator=(optional_move_assign_base &&rhs) noexcept(
554 std::is_nothrow_move_constructible<T>::value
555 &&std::is_nothrow_move_assignable<T>::value) {
556 this->assign(std::move(rhs));
557 return *this;
558 }
559};
560
561// optional_delete_ctor_base will conditionally delete copy and move
562// constructors depending on whether T is copy/move constructible
563template <class T, bool EnableCopy = std::is_copy_constructible<T>::value,
564 bool EnableMove = std::is_move_constructible<T>::value>
565struct optional_delete_ctor_base {
566 optional_delete_ctor_base() = default;
567 optional_delete_ctor_base(const optional_delete_ctor_base &) = default;
568 optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = default;
569 optional_delete_ctor_base &
570 operator=(const optional_delete_ctor_base &) = default;
571 optional_delete_ctor_base &
572 operator=(optional_delete_ctor_base &&) noexcept = default;
573};
574
575template <class T> struct optional_delete_ctor_base<T, true, false> {
576 optional_delete_ctor_base() = default;
577 optional_delete_ctor_base(const optional_delete_ctor_base &) = default;
578 optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = delete;
579 optional_delete_ctor_base &
580 operator=(const optional_delete_ctor_base &) = default;
581 optional_delete_ctor_base &
582 operator=(optional_delete_ctor_base &&) noexcept = default;
583};
584
585template <class T> struct optional_delete_ctor_base<T, false, true> {
586 optional_delete_ctor_base() = default;
587 optional_delete_ctor_base(const optional_delete_ctor_base &) = delete;
588 optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = default;
589 optional_delete_ctor_base &
590 operator=(const optional_delete_ctor_base &) = default;
591 optional_delete_ctor_base &
592 operator=(optional_delete_ctor_base &&) noexcept = default;
593};
594
595template <class T> struct optional_delete_ctor_base<T, false, false> {
596 optional_delete_ctor_base() = default;
597 optional_delete_ctor_base(const optional_delete_ctor_base &) = delete;
598 optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = delete;
599 optional_delete_ctor_base &
600 operator=(const optional_delete_ctor_base &) = default;
601 optional_delete_ctor_base &
602 operator=(optional_delete_ctor_base &&) noexcept = default;
603};
604
605// optional_delete_assign_base will conditionally delete copy and move
606// constructors depending on whether T is copy/move constructible + assignable
607template <class T,
608 bool EnableCopy = (std::is_copy_constructible<T>::value &&
609 std::is_copy_assignable<T>::value),
610 bool EnableMove = (std::is_move_constructible<T>::value &&
611 std::is_move_assignable<T>::value)>
612struct optional_delete_assign_base {
613 optional_delete_assign_base() = default;
614 optional_delete_assign_base(const optional_delete_assign_base &) = default;
615 optional_delete_assign_base(optional_delete_assign_base &&) noexcept =
616 default;
617 optional_delete_assign_base &
618 operator=(const optional_delete_assign_base &) = default;
619 optional_delete_assign_base &
620 operator=(optional_delete_assign_base &&) noexcept = default;
621};
622
623template <class T> struct optional_delete_assign_base<T, true, false> {
624 optional_delete_assign_base() = default;
625 optional_delete_assign_base(const optional_delete_assign_base &) = default;
626 optional_delete_assign_base(optional_delete_assign_base &&) noexcept =
627 default;
628 optional_delete_assign_base &
629 operator=(const optional_delete_assign_base &) = default;
630 optional_delete_assign_base &
631 operator=(optional_delete_assign_base &&) noexcept = delete;
632};
633
634template <class T> struct optional_delete_assign_base<T, false, true> {
635 optional_delete_assign_base() = default;
636 optional_delete_assign_base(const optional_delete_assign_base &) = default;
637 optional_delete_assign_base(optional_delete_assign_base &&) noexcept =
638 default;
639 optional_delete_assign_base &
640 operator=(const optional_delete_assign_base &) = delete;
641 optional_delete_assign_base &
642 operator=(optional_delete_assign_base &&) noexcept = default;
643};
644
645template <class T> struct optional_delete_assign_base<T, false, false> {
646 optional_delete_assign_base() = default;
647 optional_delete_assign_base(const optional_delete_assign_base &) = default;
648 optional_delete_assign_base(optional_delete_assign_base &&) noexcept =
649 default;
650 optional_delete_assign_base &
651 operator=(const optional_delete_assign_base &) = delete;
652 optional_delete_assign_base &
653 operator=(optional_delete_assign_base &&) noexcept = delete;
654};
655
656} // namespace detail
657
658/// \brief A tag type to represent an empty optional
659struct nullopt_t {
660 struct do_not_use {};
661 constexpr explicit nullopt_t(do_not_use, do_not_use) noexcept {}
662};
663/// \brief Represents an empty optional
664/// \synopsis static constexpr nullopt_t nullopt;
665///
666/// *Examples*:
667/// ```
668/// tl::optional<int> a = tl::nullopt;
669/// void foo (tl::optional<int>);
670/// foo(tl::nullopt); //pass an empty optional
671/// ```
672static constexpr nullopt_t nullopt{nullopt_t::do_not_use{},
673 nullopt_t::do_not_use{}};
674
675class bad_optional_access : public std::exception {
676public:
677 bad_optional_access() = default;
678 const char *what() const noexcept { return "Optional has no value"; }
679};
680
681/// An optional object is an object that contains the storage for another
682/// object and manages the lifetime of this contained object, if any. The
683/// contained object may be initialized after the optional object has been
684/// initialized, and may be destroyed before the optional object has been
685/// destroyed. The initialization state of the contained object is tracked by
686/// the optional object.
687template <class T>
688class optional : private detail::optional_move_assign_base<T>,
689 private detail::optional_delete_ctor_base<T>,
690 private detail::optional_delete_assign_base<T> {
691 using base = detail::optional_move_assign_base<T>;
692
693 static_assert(!std::is_same<T, in_place_t>::value,
694 "instantiation of optional with in_place_t is ill-formed");
695 static_assert(!std::is_same<detail::decay_t<T>, nullopt_t>::value,
696 "instantiation of optional with nullopt_t is ill-formed");
697
698public:
699// The different versions for C++14 and 11 are needed because deduced return
700// types are not SFINAE-safe. This provides better support for things like
701// generic lambdas. C.f.
702// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html
703#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
704 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
705 /// \group and_then
706 /// Carries out some operation which returns an optional on the stored
707 /// object if there is one. \requires `std::invoke(std::forward<F>(f),
708 /// value())` returns a `std::optional<U>` for some `U`. \returns Let `U` be
709 /// the result of `std::invoke(std::forward<F>(f), value())`. Returns a
710 /// `std::optional<U>`. The return value is empty if `*this` is empty,
711 /// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
712 /// is returned.
713 /// \group and_then
714 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
715 template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) & {
716 using result = detail::invoke_result_t<F, T &>;
717 static_assert(detail::is_optional<result>::value,
718 "F must return an optional");
719
720 return has_value() ? detail::invoke(std::forward<F>(f), **this)
721 : result(nullopt);
722 }
723
724 /// \group and_then
725 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
726 template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) && {
727 using result = detail::invoke_result_t<F, T &&>;
728 static_assert(detail::is_optional<result>::value,
729 "F must return an optional");
730
731 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
732 : result(nullopt);
733 }
734
735 /// \group and_then
736 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
737 template <class F> constexpr auto and_then(F &&f) const & {
738 using result = detail::invoke_result_t<F, const T &>;
739 static_assert(detail::is_optional<result>::value,
740 "F must return an optional");
741
742 return has_value() ? detail::invoke(std::forward<F>(f), **this)
743 : result(nullopt);
744 }
745
746#ifndef TL_OPTIONAL_NO_CONSTRR
747 /// \group and_then
748 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
749 template <class F> constexpr auto and_then(F &&f) const && {
750 using result = detail::invoke_result_t<F, const T &&>;
751 static_assert(detail::is_optional<result>::value,
752 "F must return an optional");
753
754 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
755 : result(nullopt);
756 }
757#endif
758#else
759 /// \group and_then
760 /// Carries out some operation which returns an optional on the stored
761 /// object if there is one. \requires `std::invoke(std::forward<F>(f),
762 /// value())` returns a `std::optional<U>` for some `U`.
763 /// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
764 /// value())`. Returns a `std::optional<U>`. The return value is empty if
765 /// `*this` is empty, otherwise the return value of
766 /// `std::invoke(std::forward<F>(f), value())` is returned.
767 /// \group and_then
768 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
769 template <class F>
770 TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T &> and_then(F &&f) & {
771 using result = detail::invoke_result_t<F, T &>;
772 static_assert(detail::is_optional<result>::value,
773 "F must return an optional");
774
775 return has_value() ? detail::invoke(std::forward<F>(f), **this)
776 : result(nullopt);
777 }
778
779 /// \group and_then
780 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
781 template <class F>
782 TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T &&> and_then(F &&f) && {
783 using result = detail::invoke_result_t<F, T &&>;
784 static_assert(detail::is_optional<result>::value,
785 "F must return an optional");
786
787 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
788 : result(nullopt);
789 }
790
791 /// \group and_then
792 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
793 template <class F>
794 constexpr detail::invoke_result_t<F, const T &> and_then(F &&f) const & {
795 using result = detail::invoke_result_t<F, const T &>;
796 static_assert(detail::is_optional<result>::value,
797 "F must return an optional");
798
799 return has_value() ? detail::invoke(std::forward<F>(f), **this)
800 : result(nullopt);
801 }
802
803#ifndef TL_OPTIONAL_NO_CONSTRR
804 /// \group and_then
805 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
806 template <class F>
807 constexpr detail::invoke_result_t<F, const T &&> and_then(F &&f) const && {
808 using result = detail::invoke_result_t<F, const T &&>;
809 static_assert(detail::is_optional<result>::value,
810 "F must return an optional");
811
812 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
813 : result(nullopt);
814 }
815#endif
816#endif
817
818#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
819 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
820 /// \brief Carries out some operation on the stored object if there is one.
821 /// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
822 /// value())`. Returns a `std::optional<U>`. The return value is empty if
823 /// `*this` is empty, otherwise an `optional<U>` is constructed from the
824 /// return value of `std::invoke(std::forward<F>(f), value())` and is
825 /// returned.
826 ///
827 /// \group map
828 /// \synopsis template <class F> constexpr auto map(F &&f) &;
829 template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) & {
830 return optional_map_impl(*this, std::forward<F>(f));
831 }
832
833 /// \group map
834 /// \synopsis template <class F> constexpr auto map(F &&f) &&;
835 template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) && {
836 return optional_map_impl(std::move(*this), std::forward<F>(f));
837 }
838
839 /// \group map
840 /// \synopsis template <class F> constexpr auto map(F &&f) const&;
841 template <class F> constexpr auto map(F &&f) const & {
842 return optional_map_impl(*this, std::forward<F>(f));
843 }
844
845 /// \group map
846 /// \synopsis template <class F> constexpr auto map(F &&f) const&&;
847 template <class F> constexpr auto map(F &&f) const && {
848 return optional_map_impl(std::move(*this), std::forward<F>(f));
849 }
850#else
851 /// \brief Carries out some operation on the stored object if there is one.
852 /// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
853 /// value())`. Returns a `std::optional<U>`. The return value is empty if
854 /// `*this` is empty, otherwise an `optional<U>` is constructed from the
855 /// return value of `std::invoke(std::forward<F>(f), value())` and is
856 /// returned.
857 ///
858 /// \group map
859 /// \synopsis template <class F> auto map(F &&f) &;
860 template <class F>
861 TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional &>(),
862 std::declval<F &&>()))
863 map(F &&f) & {
864 return optional_map_impl(*this, std::forward<F>(f));
865 }
866
867 /// \group map
868 /// \synopsis template <class F> auto map(F &&f) &&;
869 template <class F>
870 TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional &&>(),
871 std::declval<F &&>()))
872 map(F &&f) && {
873 return optional_map_impl(std::move(*this), std::forward<F>(f));
874 }
875
876 /// \group map
877 /// \synopsis template <class F> auto map(F &&f) const&;
878 template <class F>
879 constexpr decltype(optional_map_impl(std::declval<const optional &>(),
880 std::declval<F &&>()))
881 map(F &&f) const & {
882 return optional_map_impl(*this, std::forward<F>(f));
883 }
884
885#ifndef TL_OPTIONAL_NO_CONSTRR
886 /// \group map
887 /// \synopsis template <class F> auto map(F &&f) const&&;
888 template <class F>
889 constexpr decltype(optional_map_impl(std::declval<const optional &&>(),
890 std::declval<F &&>()))
891 map(F &&f) const && {
892 return optional_map_impl(std::move(*this), std::forward<F>(f));
893 }
894#endif
895#endif
896
897 /// \brief Calls `f` if the optional is empty
898 /// \requires `std::invoke_result_t<F>` must be void or convertible to
899 /// `optional<T>`.
900 /// \effects If `*this` has a value, returns `*this`.
901 /// Otherwise, if `f` returns `void`, calls `std::forward<F>(f)` and returns
902 /// `std::nullopt`. Otherwise, returns `std::forward<F>(f)()`.
903 ///
904 /// \group or_else
905 /// \synopsis template <class F> optional<T> or_else (F &&f) &;
906 template <class F, detail::enable_if_ret_void<F> * = nullptr>
907 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & {
908 if (has_value())
909 return *this;
910
911 std::forward<F>(f)();
912 return nullopt;
913 }
914
915 /// \exclude
916 template <class F, detail::disable_if_ret_void<F> * = nullptr>
917 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & {
918 return has_value() ? *this : std::forward<F>(f)();
919 }
920
921 /// \group or_else
922 /// \synopsis template <class F> optional<T> or_else (F &&f) &&;
923 template <class F, detail::enable_if_ret_void<F> * = nullptr>
924 optional<T> or_else(F &&f) && {
925 if (has_value())
926 return std::move(*this);
927
928 std::forward<F>(f)();
929 return nullopt;
930 }
931
932 /// \exclude
933 template <class F, detail::disable_if_ret_void<F> * = nullptr>
934 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) && {
935 return has_value() ? std::move(*this) : std::forward<F>(f)();
936 }
937
938 /// \group or_else
939 /// \synopsis template <class F> optional<T> or_else (F &&f) const &;
940 template <class F, detail::enable_if_ret_void<F> * = nullptr>
941 optional<T> or_else(F &&f) const & {
942 if (has_value())
943 return *this;
944
945 std::forward<F>(f)();
946 return nullopt;
947 }
948
949 /// \exclude
950 template <class F, detail::disable_if_ret_void<F> * = nullptr>
951 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const & {
952 return has_value() ? *this : std::forward<F>(f)();
953 }
954
955#ifndef TL_OPTIONAL_NO_CONSTRR
956 /// \exclude
957 template <class F, detail::enable_if_ret_void<F> * = nullptr>
958 optional<T> or_else(F &&f) const && {
959 if (has_value())
960 return std::move(*this);
961
962 std::forward<F>(f)();
963 return nullopt;
964 }
965
966 /// \exclude
967 template <class F, detail::disable_if_ret_void<F> * = nullptr>
968 optional<T> or_else(F &&f) const && {
969 return has_value() ? std::move(*this) : std::forward<F>(f)();
970 }
971#endif
972
973 /// \brief Maps the stored value with `f` if there is one, otherwise returns
974 /// `u`.
975 ///
976 /// \details If there is a value stored, then `f` is called with `**this`
977 /// and the value is returned. Otherwise `u` is returned.
978 ///
979 /// \group map_or
980 template <class F, class U> U map_or(F &&f, U &&u) & {
981 return has_value() ? detail::invoke(std::forward<F>(f), **this)
982 : std::forward<U>(u);
983 }
984
985 /// \group map_or
986 template <class F, class U> U map_or(F &&f, U &&u) && {
987 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
988 : std::forward<U>(u);
989 }
990
991 /// \group map_or
992 template <class F, class U> U map_or(F &&f, U &&u) const & {
993 return has_value() ? detail::invoke(std::forward<F>(f), **this)
994 : std::forward<U>(u);
995 }
996
997#ifndef TL_OPTIONAL_NO_CONSTRR
998 /// \group map_or
999 template <class F, class U> U map_or(F &&f, U &&u) const && {
1000 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
1001 : std::forward<U>(u);
1002 }
1003#endif
1004
1005 /// \brief Maps the stored value with `f` if there is one, otherwise calls
1006 /// `u` and returns the result.
1007 ///
1008 /// \details If there is a value stored, then `f` is
1009 /// called with `**this` and the value is returned. Otherwise
1010 /// `std::forward<U>(u)()` is returned.
1011 ///
1012 /// \group map_or_else
1013 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u) &;
1014 template <class F, class U>
1015 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) & {
1016 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1017 : std::forward<U>(u)();
1018 }
1019
1020 /// \group map_or_else
1021 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u)
1022 /// &&;
1023 template <class F, class U>
1024 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) && {
1025 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
1026 : std::forward<U>(u)();
1027 }
1028
1029 /// \group map_or_else
1030 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u)
1031 /// const &;
1032 template <class F, class U>
1033 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) const & {
1034 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1035 : std::forward<U>(u)();
1036 }
1037
1038#ifndef TL_OPTIONAL_NO_CONSTRR
1039 /// \group map_or_else
1040 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u)
1041 /// const &&;
1042 template <class F, class U>
1043 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) const && {
1044 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
1045 : std::forward<U>(u)();
1046 }
1047#endif
1048
1049 /// \returns `u` if `*this` has a value, otherwise an empty optional.
1050 template <class U>
1051 constexpr optional<typename std::decay<U>::type> conjunction(U &&u) const {
1052 using result = optional<detail::decay_t<U>>;
1053 return has_value() ? result{u} : result{nullopt};
1054 }
1055
1056 /// \returns `rhs` if `*this` is empty, otherwise the current value.
1057 /// \group disjunction
1058 TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) & {
1059 return has_value() ? *this : rhs;
1060 }
1061
1062 /// \group disjunction
1063 constexpr optional disjunction(const optional &rhs) const & {
1064 return has_value() ? *this : rhs;
1065 }
1066
1067 /// \group disjunction
1068 TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) && {
1069 return has_value() ? std::move(*this) : rhs;
1070 }
1071
1072#ifndef TL_OPTIONAL_NO_CONSTRR
1073 /// \group disjunction
1074 constexpr optional disjunction(const optional &rhs) const && {
1075 return has_value() ? std::move(*this) : rhs;
1076 }
1077#endif
1078
1079 /// \group disjunction
1080 TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) & {
1081 return has_value() ? *this : std::move(rhs);
1082 }
1083
1084 /// \group disjunction
1085 constexpr optional disjunction(optional &&rhs) const & {
1086 return has_value() ? *this : std::move(rhs);
1087 }
1088
1089 /// \group disjunction
1090 TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) && {
1091 return has_value() ? std::move(*this) : std::move(rhs);
1092 }
1093
1094#ifndef TL_OPTIONAL_NO_CONSTRR
1095 /// \group disjunction
1096 constexpr optional disjunction(optional &&rhs) const && {
1097 return has_value() ? std::move(*this) : std::move(rhs);
1098 }
1099#endif
1100
1101 /// Takes the value out of the optional, leaving it empty
1102 /// \group take
1103 optional take() & {
1104 optional ret = *this;
1105 reset();
1106 return ret;
1107 }
1108
1109 /// \group take
1110 optional take() const & {
1111 optional ret = *this;
1112 reset();
1113 return ret;
1114 }
1115
1116 /// \group take
1117 optional take() && {
1118 optional ret = std::move(*this);
1119 reset();
1120 return ret;
1121 }
1122
1123#ifndef TL_OPTIONAL_NO_CONSTRR
1124 /// \group take
1125 optional take() const && {
1126 optional ret = std::move(*this);
1127 reset();
1128 return ret;
1129 }
1130#endif
1131
1132 using value_type = T;
1133
1134 /// Constructs an optional that does not contain a value.
1135 /// \group ctor_empty
1136 constexpr optional() noexcept = default;
1137
1138 /// \group ctor_empty
1139 constexpr optional(nullopt_t) noexcept {}
1140
1141 /// Copy constructor
1142 ///
1143 /// If `rhs` contains a value, the stored value is direct-initialized with
1144 /// it. Otherwise, the constructed optional is empty.
1145 TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs) = default;
1146
1147 /// Move constructor
1148 ///
1149 /// If `rhs` contains a value, the stored value is direct-initialized with
1150 /// it. Otherwise, the constructed optional is empty.
1151 TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs) = default;
1152
1153 /// Constructs the stored value in-place using the given arguments.
1154 /// \group in_place
1155 /// \synopsis template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);
1156 template <class... Args>
1157 constexpr explicit optional(
1158 detail::enable_if_t<std::is_constructible<T, Args...>::value, in_place_t>,
1159 Args &&... args)
1160 : base(in_place, std::forward<Args>(args)...) {}
1161
1162 /// \group in_place
1163 /// \synopsis template <class U, class... Args>\nconstexpr explicit optional(in_place_t, std::initializer_list<U>&, Args&&... args);
1164 template <class U, class... Args>
1165 TL_OPTIONAL_11_CONSTEXPR explicit optional(
1166 detail::enable_if_t<std::is_constructible<T, std::initializer_list<U> &,
1167 Args &&...>::value,
1168 in_place_t>,
1169 std::initializer_list<U> il, Args &&... args) {
1170 this->construct(il, std::forward<Args>(args)...);
1171 }
1172
1173 /// Constructs the stored value with `u`.
1174 /// \synopsis template <class U=T> constexpr optional(U &&u);
1175 template <
1176 class U = T,
1177 detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr,
1178 detail::enable_forward_value<T, U> * = nullptr>
1179 constexpr optional(U &&u) : base(in_place, std::forward<U>(u)) {}
1180
1181 /// \exclude
1182 template <
1183 class U = T,
1184 detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr,
1185 detail::enable_forward_value<T, U> * = nullptr>
1186 constexpr explicit optional(U &&u) : base(in_place, std::forward<U>(u)) {}
1187
1188 /// Converting copy constructor.
1189 /// \synopsis template <class U> optional(const optional<U> &rhs);
1190 template <
1191 class U, detail::enable_from_other<T, U, const U &> * = nullptr,
1192 detail::enable_if_t<std::is_convertible<const U &, T>::value> * = nullptr>
1193 optional(const optional<U> &rhs) {
1194 this->construct(*rhs);
1195 }
1196
1197 /// \exclude
1198 template <class U, detail::enable_from_other<T, U, const U &> * = nullptr,
1199 detail::enable_if_t<!std::is_convertible<const U &, T>::value> * =
1200 nullptr>
1201 explicit optional(const optional<U> &rhs) {
1202 this->construct(*rhs);
1203 }
1204
1205 /// Converting move constructor.
1206 /// \synopsis template <class U> optional(optional<U> &&rhs);
1207 template <
1208 class U, detail::enable_from_other<T, U, U &&> * = nullptr,
1209 detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr>
1210 optional(optional<U> &&rhs) {
1211 this->construct(std::move(*rhs));
1212 }
1213
1214 /// \exclude
1215 template <
1216 class U, detail::enable_from_other<T, U, U &&> * = nullptr,
1217 detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr>
1218 explicit optional(optional<U> &&rhs) {
1219 this->construct(std::move(*rhs));
1220 }
1221
1222 /// Destroys the stored value if there is one.
1223 ~optional() = default;
1224
1225 /// Assignment to empty.
1226 ///
1227 /// Destroys the current value if there is one.
1228 optional &operator=(nullopt_t) noexcept {
1229 if (has_value()) {
1230 this->m_value.~T();
1231 this->m_has_value = false;
1232 }
1233
1234 return *this;
1235 }
1236
1237 /// Copy assignment.
1238 ///
1239 /// Copies the value from `rhs` if there is one. Otherwise resets the stored
1240 /// value in `*this`.
1241 optional &operator=(const optional &rhs) = default;
1242
1243 /// Move assignment.
1244 ///
1245 /// Moves the value from `rhs` if there is one. Otherwise resets the stored
1246 /// value in `*this`.
1247 optional &operator=(optional &&rhs) = default;
1248
1249 /// Assigns the stored value from `u`, destroying the old value if there was
1250 /// one.
1251 /// \synopsis optional &operator=(U &&u);
1252 template <class U = T, detail::enable_assign_forward<T, U> * = nullptr>
1253 optional &operator=(U &&u) {
1254 if (has_value()) {
1255 this->m_value = std::forward<U>(u);
1256 } else {
1257 this->construct(std::forward<U>(u));
1258 }
1259
1260 return *this;
1261 }
1262
1263 /// Converting copy assignment operator.
1264 ///
1265 /// Copies the value from `rhs` if there is one. Otherwise resets the stored
1266 /// value in `*this`.
1267 /// \synopsis optional &operator=(const optional<U> & rhs);
1268 template <class U,
1269 detail::enable_assign_from_other<T, U, const U &> * = nullptr>
1270 optional &operator=(const optional<U> &rhs) {
1271 if (has_value()) {
1272 if (rhs.has_value()) {
1273 this->m_value = *rhs;
1274 } else {
1275 this->hard_reset();
1276 }
1277 }
1278
1279 if (rhs.has_value()) {
1280 this->construct(*rhs);
1281 }
1282
1283 return *this;
1284 }
1285
1286 // TODO check exception guarantee
1287 /// Converting move assignment operator.
1288 ///
1289 /// Moves the value from `rhs` if there is one. Otherwise resets the stored
1290 /// value in `*this`.
1291 /// \synopsis optional &operator=(optional<U> && rhs);
1292 template <class U, detail::enable_assign_from_other<T, U, U> * = nullptr>
1293 optional &operator=(optional<U> &&rhs) {
1294 if (has_value()) {
1295 if (rhs.has_value()) {
1296 this->m_value = std::move(*rhs);
1297 } else {
1298 this->hard_reset();
1299 }
1300 }
1301
1302 if (rhs.has_value()) {
1303 this->construct(std::move(*rhs));
1304 }
1305
1306 return *this;
1307 }
1308
1309 /// Constructs the value in-place, destroying the current one if there is
1310 /// one.
1311 /// \group emplace
1312 template <class... Args> T &emplace(Args &&... args) {
1313 static_assert(std::is_constructible<T, Args &&...>::value,
1314 "T must be constructible with Args");
1315
1316 *this = nullopt;
1317 this->construct(std::forward<Args>(args)...);
1318 return value();
1319 }
1320
1321 /// \group emplace
1322 /// \synopsis template <class U, class... Args>\nT& emplace(std::initializer_list<U> il, Args &&... args);
1323 template <class U, class... Args>
1324 detail::enable_if_t<
1325 std::is_constructible<T, std::initializer_list<U> &, Args &&...>::value,
1326 T &>
1327 emplace(std::initializer_list<U> il, Args &&... args) {
1328 *this = nullopt;
1329 this->construct(il, std::forward<Args>(args)...);
1330 return value();
1331 }
1332
1333 /// Swaps this optional with the other.
1334 ///
1335 /// If neither optionals have a value, nothing happens.
1336 /// If both have a value, the values are swapped.
1337 /// If one has a value, it is moved to the other and the movee is left
1338 /// valueless.
1339 void
1340 swap(optional &rhs) noexcept(std::is_nothrow_move_constructible<T>::value
1341 &&detail::is_nothrow_swappable<T>::value) {
1342 if (has_value()) {
1343 if (rhs.has_value()) {
1344 using std::swap;
1345 swap(**this, *rhs);
1346 } else {
1347 new (std::addressof(rhs.m_value)) T(std::move(this->m_value));
1348 this->m_value.T::~T();
1349 }
1350 } else if (rhs.has_value()) {
1351 new (std::addressof(this->m_value)) T(std::move(rhs.m_value));
1352 rhs.m_value.T::~T();
1353 }
1354 }
1355
1356 /// \returns a pointer to the stored value
1357 /// \requires a value is stored
1358 /// \group pointer
1359 /// \synopsis constexpr const T *operator->() const;
1360 constexpr const T *operator->() const {
1361 return std::addressof(this->m_value);
1362 }
1363
1364 /// \group pointer
1365 /// \synopsis constexpr T *operator->();
1366 TL_OPTIONAL_11_CONSTEXPR T *operator->() {
1367 return std::addressof(this->m_value);
1368 }
1369
1370 /// \returns the stored value
1371 /// \requires a value is stored
1372 /// \group deref
1373 /// \synopsis constexpr T &operator*();
1374 TL_OPTIONAL_11_CONSTEXPR T &operator*() & { return this->m_value; }
1375
1376 /// \group deref
1377 /// \synopsis constexpr const T &operator*() const;
1378 constexpr const T &operator*() const & { return this->m_value; }
1379
1380 /// \exclude
1381 TL_OPTIONAL_11_CONSTEXPR T &&operator*() && {
1382 return std::move(this->m_value);
1383 }
1384
1385#ifndef TL_OPTIONAL_NO_CONSTRR
1386 /// \exclude
1387 constexpr const T &&operator*() const && { return std::move(this->m_value); }
1388#endif
1389
1390 /// \returns whether or not the optional has a value
1391 /// \group has_value
1392 constexpr bool has_value() const noexcept { return this->m_has_value; }
1393
1394 /// \group has_value
1395 constexpr explicit operator bool() const noexcept {
1396 return this->m_has_value;
1397 }
1398
1399 /// \returns the contained value if there is one, otherwise throws
1400 /// [bad_optional_access]
1401 /// \group value
1402 /// \synopsis constexpr T &value();
1403 TL_OPTIONAL_11_CONSTEXPR T &value() & {
1404 if (has_value())
1405 return this->m_value;
1406 throw bad_optional_access();
1407 }
1408 /// \group value
1409 /// \synopsis constexpr const T &value() const;
1410 TL_OPTIONAL_11_CONSTEXPR const T &value() const & {
1411 if (has_value())
1412 return this->m_value;
1413 throw bad_optional_access();
1414 }
1415 /// \exclude
1416 TL_OPTIONAL_11_CONSTEXPR T &&value() && {
1417 if (has_value())
1418 return std::move(this->m_value);
1419 throw bad_optional_access();
1420 }
1421
1422#ifndef TL_OPTIONAL_NO_CONSTRR
1423 /// \exclude
1424 TL_OPTIONAL_11_CONSTEXPR const T &&value() const && {
1425 if (has_value())
1426 return std::move(this->m_value);
1427 throw bad_optional_access();
1428 }
1429#endif
1430
1431 /// \returns the stored value if there is one, otherwise returns `u`
1432 /// \group value_or
1433 template <class U> constexpr T value_or(U &&u) const & {
1434 static_assert(std::is_copy_constructible<T>::value &&
1435 std::is_convertible<U &&, T>::value,
1436 "T must be copy constructible and convertible from U");
1437 return has_value() ? **this : static_cast<T>(std::forward<U>(u));
1438 }
1439
1440 /// \group value_or
1441 template <class U> TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) && {
1442 static_assert(std::is_move_constructible<T>::value &&
1443 std::is_convertible<U &&, T>::value,
1444 "T must be move constructible and convertible from U");
1445 return has_value() ? **this : static_cast<T>(std::forward<U>(u));
1446 }
1447
1448 /// Destroys the stored value if one exists, making the optional empty
1449 void reset() noexcept {
1450 if (has_value()) {
1451 this->m_value.~T();
1452 this->m_has_value = false;
1453 }
1454 }
1455}; // namespace tl
1456
1457/// \group relop
1458/// \brief Compares two optional objects
1459/// \details If both optionals contain a value, they are compared with `T`s
1460/// relational operators. Otherwise `lhs` and `rhs` are equal only if they are
1461/// both empty, and `lhs` is less than `rhs` only if `rhs` is empty and `lhs`
1462/// is not.
1463template <class T, class U>
1464inline constexpr bool operator==(const optional<T> &lhs,
1465 const optional<U> &rhs) {
1466 return lhs.has_value() == rhs.has_value() &&
1467 (!lhs.has_value() || *lhs == *rhs);
1468}
1469/// \group relop
1470template <class T, class U>
1471inline constexpr bool operator!=(const optional<T> &lhs,
1472 const optional<U> &rhs) {
1473 return lhs.has_value() != rhs.has_value() ||
1474 (lhs.has_value() && *lhs != *rhs);
1475}
1476/// \group relop
1477template <class T, class U>
1478inline constexpr bool operator<(const optional<T> &lhs,
1479 const optional<U> &rhs) {
1480 return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs);
1481}
1482/// \group relop
1483template <class T, class U>
1484inline constexpr bool operator>(const optional<T> &lhs,
1485 const optional<U> &rhs) {
1486 return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs);
1487}
1488/// \group relop
1489template <class T, class U>
1490inline constexpr bool operator<=(const optional<T> &lhs,
1491 const optional<U> &rhs) {
1492 return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs);
1493}
1494/// \group relop
1495template <class T, class U>
1496inline constexpr bool operator>=(const optional<T> &lhs,
1497 const optional<U> &rhs) {
1498 return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs);
1499}
1500
1501/// \group relop_nullopt
1502/// \brief Compares an optional to a `nullopt`
1503/// \details Equivalent to comparing the optional to an empty optional
1504template <class T>
1505inline constexpr bool operator==(const optional<T> &lhs, nullopt_t) noexcept {
1506 return !lhs.has_value();
1507}
1508/// \group relop_nullopt
1509template <class T>
1510inline constexpr bool operator==(nullopt_t, const optional<T> &rhs) noexcept {
1511 return !rhs.has_value();
1512}
1513/// \group relop_nullopt
1514template <class T>
1515inline constexpr bool operator!=(const optional<T> &lhs, nullopt_t) noexcept {
1516 return lhs.has_value();
1517}
1518/// \group relop_nullopt
1519template <class T>
1520inline constexpr bool operator!=(nullopt_t, const optional<T> &rhs) noexcept {
1521 return rhs.has_value();
1522}
1523/// \group relop_nullopt
1524template <class T>
1525inline constexpr bool operator<(const optional<T> &, nullopt_t) noexcept {
1526 return false;
1527}
1528/// \group relop_nullopt
1529template <class T>
1530inline constexpr bool operator<(nullopt_t, const optional<T> &rhs) noexcept {
1531 return rhs.has_value();
1532}
1533/// \group relop_nullopt
1534template <class T>
1535inline constexpr bool operator<=(const optional<T> &lhs, nullopt_t) noexcept {
1536 return !lhs.has_value();
1537}
1538/// \group relop_nullopt
1539template <class T>
1540inline constexpr bool operator<=(nullopt_t, const optional<T> &) noexcept {
1541 return true;
1542}
1543/// \group relop_nullopt
1544template <class T>
1545inline constexpr bool operator>(const optional<T> &lhs, nullopt_t) noexcept {
1546 return lhs.has_value();
1547}
1548/// \group relop_nullopt
1549template <class T>
1550inline constexpr bool operator>(nullopt_t, const optional<T> &) noexcept {
1551 return false;
1552}
1553/// \group relop_nullopt
1554template <class T>
1555inline constexpr bool operator>=(const optional<T> &, nullopt_t) noexcept {
1556 return true;
1557}
1558/// \group relop_nullopt
1559template <class T>
1560inline constexpr bool operator>=(nullopt_t, const optional<T> &rhs) noexcept {
1561 return !rhs.has_value();
1562}
1563
1564/// \group relop_t
1565/// \brief Compares the optional with a value.
1566/// \details If the optional has a value, it is compared with the other value
1567/// using `T`s relational operators. Otherwise, the optional is considered
1568/// less than the value.
1569template <class T, class U>
1570inline constexpr bool operator==(const optional<T> &lhs, const U &rhs) {
1571 return lhs.has_value() ? *lhs == rhs : false;
1572}
1573/// \group relop_t
1574template <class T, class U>
1575inline constexpr bool operator==(const U &lhs, const optional<T> &rhs) {
1576 return rhs.has_value() ? lhs == *rhs : false;
1577}
1578/// \group relop_t
1579template <class T, class U>
1580inline constexpr bool operator!=(const optional<T> &lhs, const U &rhs) {
1581 return lhs.has_value() ? *lhs != rhs : true;
1582}
1583/// \group relop_t
1584template <class T, class U>
1585inline constexpr bool operator!=(const U &lhs, const optional<T> &rhs) {
1586 return rhs.has_value() ? lhs != *rhs : true;
1587}
1588/// \group relop_t
1589template <class T, class U>
1590inline constexpr bool operator<(const optional<T> &lhs, const U &rhs) {
1591 return lhs.has_value() ? *lhs < rhs : true;
1592}
1593/// \group relop_t
1594template <class T, class U>
1595inline constexpr bool operator<(const U &lhs, const optional<T> &rhs) {
1596 return rhs.has_value() ? lhs < *rhs : false;
1597}
1598/// \group relop_t
1599template <class T, class U>
1600inline constexpr bool operator<=(const optional<T> &lhs, const U &rhs) {
1601 return lhs.has_value() ? *lhs <= rhs : true;
1602}
1603/// \group relop_t
1604template <class T, class U>
1605inline constexpr bool operator<=(const U &lhs, const optional<T> &rhs) {
1606 return rhs.has_value() ? lhs <= *rhs : false;
1607}
1608/// \group relop_t
1609template <class T, class U>
1610inline constexpr bool operator>(const optional<T> &lhs, const U &rhs) {
1611 return lhs.has_value() ? *lhs > rhs : false;
1612}
1613/// \group relop_t
1614template <class T, class U>
1615inline constexpr bool operator>(const U &lhs, const optional<T> &rhs) {
1616 return rhs.has_value() ? lhs > *rhs : true;
1617}
1618/// \group relop_t
1619template <class T, class U>
1620inline constexpr bool operator>=(const optional<T> &lhs, const U &rhs) {
1621 return lhs.has_value() ? *lhs >= rhs : false;
1622}
1623/// \group relop_t
1624template <class T, class U>
1625inline constexpr bool operator>=(const U &lhs, const optional<T> &rhs) {
1626 return rhs.has_value() ? lhs >= *rhs : true;
1627}
1628
1629/// \synopsis template <class T>\nvoid swap(optional<T> &lhs, optional<T> &rhs);
1630template <class T,
1631 detail::enable_if_t<std::is_move_constructible<T>::value> * = nullptr,
1632 detail::enable_if_t<detail::is_swappable<T>::value> * = nullptr>
1633void swap(optional<T> &lhs,
1634 optional<T> &rhs) noexcept(noexcept(lhs.swap(rhs))) {
1635 return lhs.swap(rhs);
1636}
1637
1638namespace detail {
1639struct i_am_secret {};
1640} // namespace detail
1641
1642template <class T = detail::i_am_secret, class U,
1643 class Ret =
1644 detail::conditional_t<std::is_same<T, detail::i_am_secret>::value,
1645 detail::decay_t<U>, T>>
1646inline constexpr optional<Ret> make_optional(U &&v) {
1647 return optional<Ret>(std::forward<U>(v));
1648}
1649
1650template <class T, class... Args>
1651inline constexpr optional<T> make_optional(Args &&... args) {
1652 return optional<T>(in_place, std::forward<Args>(args)...);
1653}
1654template <class T, class U, class... Args>
1655inline constexpr optional<T> make_optional(std::initializer_list<U> il,
1656 Args &&... args) {
1657 return optional<T>(in_place, il, std::forward<Args>(args)...);
1658}
1659
1660#if __cplusplus >= 201703L
1661template <class T> optional(T)->optional<T>;
1662#endif
1663
1664/// \exclude
1665namespace detail {
1666#ifdef TL_OPTIONAL_CXX14
1667template <class Opt, class F,
1668 class Ret = decltype(detail::invoke(std::declval<F>(),
1669 *std::declval<Opt>())),
1670 detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
1671constexpr auto optional_map_impl(Opt &&opt, F &&f) {
1672 return opt.has_value()
1673 ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
1674 : optional<Ret>(nullopt);
1675}
1676
1677template <class Opt, class F,
1678 class Ret = decltype(detail::invoke(std::declval<F>(),
1679 *std::declval<Opt>())),
1680 detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
1681auto optional_map_impl(Opt &&opt, F &&f) {
1682 if (opt.has_value()) {
1683 detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
1684 return make_optional(monostate{});
1685 }
1686
1687 return optional<monostate>(nullopt);
1688}
1689#else
1690template <class Opt, class F,
1691 class Ret = decltype(detail::invoke(std::declval<F>(),
1692 *std::declval<Opt>())),
1693 detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
1694
1695constexpr auto optional_map_impl(Opt &&opt, F &&f) -> optional<Ret> {
1696 return opt.has_value()
1697 ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
1698 : optional<Ret>(nullopt);
1699}
1700
1701template <class Opt, class F,
1702 class Ret = decltype(detail::invoke(std::declval<F>(),
1703 *std::declval<Opt>())),
1704 detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
1705
1706auto optional_map_impl(Opt &&opt, F &&f) -> optional<monostate> {
1707 if (opt.has_value()) {
1708 detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
1709 return monostate{};
1710 }
1711
1712 return nullopt;
1713}
1714#endif
1715} // namespace detail
1716
1717/// Specialization for when `T` is a reference. `optional<T&>` acts similarly
1718/// to a `T*`, but provides more operations and shows intent more clearly.
1719///
1720/// *Examples*:
1721///
1722/// ```
1723/// int i = 42;
1724/// tl::optional<int&> o = i;
1725/// *o == 42; //true
1726/// i = 12;
1727/// *o = 12; //true
1728/// &*o == &i; //true
1729/// ```
1730///
1731/// Assignment has rebind semantics rather than assign-through semantics:
1732///
1733/// ```
1734/// int j = 8;
1735/// o = j;
1736///
1737/// &*o == &j; //true
1738/// ```
1739template <class T> class optional<T &> {
1740public:
1741// The different versions for C++14 and 11 are needed because deduced return
1742// types are not SFINAE-safe. This provides better support for things like
1743// generic lambdas. C.f.
1744// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html
1745#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
1746 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
1747 /// \group and_then
1748 /// Carries out some operation which returns an optional on the stored
1749 /// object if there is one. \requires `std::invoke(std::forward<F>(f),
1750 /// value())` returns a `std::optional<U>` for some `U`. \returns Let `U` be
1751 /// the result of `std::invoke(std::forward<F>(f), value())`. Returns a
1752 /// `std::optional<U>`. The return value is empty if `*this` is empty,
1753 /// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
1754 /// is returned.
1755 /// \group and_then
1756 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
1757 template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) & {
1758 using result = detail::invoke_result_t<F, T &>;
1759 static_assert(detail::is_optional<result>::value,
1760 "F must return an optional");
1761
1762 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1763 : result(nullopt);
1764 }
1765
1766 /// \group and_then
1767 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
1768 template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) && {
1769 using result = detail::invoke_result_t<F, T &>;
1770 static_assert(detail::is_optional<result>::value,
1771 "F must return an optional");
1772
1773 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1774 : result(nullopt);
1775 }
1776
1777 /// \group and_then
1778 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
1779 template <class F> constexpr auto and_then(F &&f) const & {
1780 using result = detail::invoke_result_t<F, const T &>;
1781 static_assert(detail::is_optional<result>::value,
1782 "F must return an optional");
1783
1784 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1785 : result(nullopt);
1786 }
1787
1788#ifndef TL_OPTIONAL_NO_CONSTRR
1789 /// \group and_then
1790 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
1791 template <class F> constexpr auto and_then(F &&f) const && {
1792 using result = detail::invoke_result_t<F, const T &>;
1793 static_assert(detail::is_optional<result>::value,
1794 "F must return an optional");
1795
1796 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1797 : result(nullopt);
1798 }
1799#endif
1800#else
1801 /// \group and_then
1802 /// Carries out some operation which returns an optional on the stored
1803 /// object if there is one. \requires `std::invoke(std::forward<F>(f),
1804 /// value())` returns a `std::optional<U>` for some `U`. \returns Let `U` be
1805 /// the result of `std::invoke(std::forward<F>(f), value())`. Returns a
1806 /// `std::optional<U>`. The return value is empty if `*this` is empty,
1807 /// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
1808 /// is returned.
1809 /// \group and_then
1810 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
1811 template <class F>
1812 TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T &> and_then(F &&f) & {
1813 using result = detail::invoke_result_t<F, T &>;
1814 static_assert(detail::is_optional<result>::value,
1815 "F must return an optional");
1816
1817 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1818 : result(nullopt);
1819 }
1820
1821 /// \group and_then
1822 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
1823 template <class F>
1824 TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T &> and_then(F &&f) && {
1825 using result = detail::invoke_result_t<F, T &>;
1826 static_assert(detail::is_optional<result>::value,
1827 "F must return an optional");
1828
1829 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1830 : result(nullopt);
1831 }
1832
1833 /// \group and_then
1834 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
1835 template <class F>
1836 constexpr detail::invoke_result_t<F, const T &> and_then(F &&f) const & {
1837 using result = detail::invoke_result_t<F, const T &>;
1838 static_assert(detail::is_optional<result>::value,
1839 "F must return an optional");
1840
1841 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1842 : result(nullopt);
1843 }
1844
1845#ifndef TL_OPTIONAL_NO_CONSTRR
1846 /// \group and_then
1847 /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
1848 template <class F>
1849 constexpr detail::invoke_result_t<F, const T &> and_then(F &&f) const && {
1850 using result = detail::invoke_result_t<F, const T &>;
1851 static_assert(detail::is_optional<result>::value,
1852 "F must return an optional");
1853
1854 return has_value() ? detail::invoke(std::forward<F>(f), **this)
1855 : result(nullopt);
1856 }
1857#endif
1858#endif
1859
1860#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
1861 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
1862 /// \brief Carries out some operation on the stored object if there is one.
1863 /// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
1864 /// value())`. Returns a `std::optional<U>`. The return value is empty if
1865 /// `*this` is empty, otherwise an `optional<U>` is constructed from the
1866 /// return value of `std::invoke(std::forward<F>(f), value())` and is
1867 /// returned.
1868 ///
1869 /// \group map
1870 /// \synopsis template <class F> constexpr auto map(F &&f) &;
1871 template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) & {
1872 return detail::optional_map_impl(*this, std::forward<F>(f));
1873 }
1874
1875 /// \group map
1876 /// \synopsis template <class F> constexpr auto map(F &&f) &&;
1877 template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) && {
1878 return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
1879 }
1880
1881 /// \group map
1882 /// \synopsis template <class F> constexpr auto map(F &&f) const&;
1883 template <class F> constexpr auto map(F &&f) const & {
1884 return detail::optional_map_impl(*this, std::forward<F>(f));
1885 }
1886
1887 /// \group map
1888 /// \synopsis template <class F> constexpr auto map(F &&f) const&&;
1889 template <class F> constexpr auto map(F &&f) const && {
1890 return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
1891 }
1892#else
1893 /// \brief Carries out some operation on the stored object if there is one.
1894 /// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
1895 /// value())`. Returns a `std::optional<U>`. The return value is empty if
1896 /// `*this` is empty, otherwise an `optional<U>` is constructed from the
1897 /// return value of `std::invoke(std::forward<F>(f), value())` and is
1898 /// returned.
1899 ///
1900 /// \group map
1901 /// \synopsis template <class F> auto map(F &&f) &;
1902 template <class F>
1903 TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional &>(),
1904 std::declval<F &&>()))
1905 map(F &&f) & {
1906 return detail::optional_map_impl(*this, std::forward<F>(f));
1907 }
1908
1909 /// \group map
1910 /// \synopsis template <class F> auto map(F &&f) &&;
1911 template <class F>
1912 TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional &&>(),
1913 std::declval<F &&>()))
1914 map(F &&f) && {
1915 return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
1916 }
1917
1918 /// \group map
1919 /// \synopsis template <class F> auto map(F &&f) const&;
1920 template <class F>
1921 constexpr decltype(detail::optional_map_impl(std::declval<const optional &>(),
1922 std::declval<F &&>()))
1923 map(F &&f) const & {
1924 return detail::optional_map_impl(*this, std::forward<F>(f));
1925 }
1926
1927#ifndef TL_OPTIONAL_NO_CONSTRR
1928 /// \group map
1929 /// \synopsis template <class F> auto map(F &&f) const&&;
1930 template <class F>
1931 constexpr decltype(detail::optional_map_impl(std::declval<const optional &&>(),
1932 std::declval<F &&>()))
1933 map(F &&f) const && {
1934 return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
1935 }
1936#endif
1937#endif
1938
1939 /// \brief Calls `f` if the optional is empty
1940 /// \requires `std::invoke_result_t<F>` must be void or convertible to
1941 /// `optional<T>`. \effects If `*this` has a value, returns `*this`.
1942 /// Otherwise, if `f` returns `void`, calls `std::forward<F>(f)` and returns
1943 /// `std::nullopt`. Otherwise, returns `std::forward<F>(f)()`.
1944 ///
1945 /// \group or_else
1946 /// \synopsis template <class F> optional<T> or_else (F &&f) &;
1947 template <class F, detail::enable_if_ret_void<F> * = nullptr>
1948 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & {
1949 if (has_value())
1950 return *this;
1951
1952 std::forward<F>(f)();
1953 return nullopt;
1954 }
1955
1956 /// \exclude
1957 template <class F, detail::disable_if_ret_void<F> * = nullptr>
1958 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & {
1959 return has_value() ? *this : std::forward<F>(f)();
1960 }
1961
1962 /// \group or_else
1963 /// \synopsis template <class F> optional<T> or_else (F &&f) &&;
1964 template <class F, detail::enable_if_ret_void<F> * = nullptr>
1965 optional<T> or_else(F &&f) && {
1966 if (has_value())
1967 return std::move(*this);
1968
1969 std::forward<F>(f)();
1970 return nullopt;
1971 }
1972
1973 /// \exclude
1974 template <class F, detail::disable_if_ret_void<F> * = nullptr>
1975 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) && {
1976 return has_value() ? std::move(*this) : std::forward<F>(f)();
1977 }
1978
1979 /// \group or_else
1980 /// \synopsis template <class F> optional<T> or_else (F &&f) const &;
1981 template <class F, detail::enable_if_ret_void<F> * = nullptr>
1982 optional<T> or_else(F &&f) const & {
1983 if (has_value())
1984 return *this;
1985
1986 std::forward<F>(f)();
1987 return nullopt;
1988 }
1989
1990 /// \exclude
1991 template <class F, detail::disable_if_ret_void<F> * = nullptr>
1992 optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const & {
1993 return has_value() ? *this : std::forward<F>(f)();
1994 }
1995
1996#ifndef TL_OPTIONAL_NO_CONSTRR
1997 /// \exclude
1998 template <class F, detail::enable_if_ret_void<F> * = nullptr>
1999 optional<T> or_else(F &&f) const && {
2000 if (has_value())
2001 return std::move(*this);
2002
2003 std::forward<F>(f)();
2004 return nullopt;
2005 }
2006
2007 /// \exclude
2008 template <class F, detail::disable_if_ret_void<F> * = nullptr>
2009 optional<T> or_else(F &&f) const && {
2010 return has_value() ? std::move(*this) : std::forward<F>(f)();
2011 }
2012#endif
2013
2014 /// \brief Maps the stored value with `f` if there is one, otherwise returns
2015 /// `u`.
2016 ///
2017 /// \details If there is a value stored, then `f` is called with `**this`
2018 /// and the value is returned. Otherwise `u` is returned.
2019 ///
2020 /// \group map_or
2021 template <class F, class U> U map_or(F &&f, U &&u) & {
2022 return has_value() ? detail::invoke(std::forward<F>(f), **this)
2023 : std::forward<U>(u);
2024 }
2025
2026 /// \group map_or
2027 template <class F, class U> U map_or(F &&f, U &&u) && {
2028 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
2029 : std::forward<U>(u);
2030 }
2031
2032 /// \group map_or
2033 template <class F, class U> U map_or(F &&f, U &&u) const & {
2034 return has_value() ? detail::invoke(std::forward<F>(f), **this)
2035 : std::forward<U>(u);
2036 }
2037
2038#ifndef TL_OPTIONAL_NO_CONSTRR
2039 /// \group map_or
2040 template <class F, class U> U map_or(F &&f, U &&u) const && {
2041 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
2042 : std::forward<U>(u);
2043 }
2044#endif
2045
2046 /// \brief Maps the stored value with `f` if there is one, otherwise calls
2047 /// `u` and returns the result.
2048 ///
2049 /// \details If there is a value stored, then `f` is
2050 /// called with `**this` and the value is returned. Otherwise
2051 /// `std::forward<U>(u)()` is returned.
2052 ///
2053 /// \group map_or_else
2054 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u) &;
2055 template <class F, class U>
2056 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) & {
2057 return has_value() ? detail::invoke(std::forward<F>(f), **this)
2058 : std::forward<U>(u)();
2059 }
2060
2061 /// \group map_or_else
2062 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u)
2063 /// &&;
2064 template <class F, class U>
2065 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) && {
2066 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
2067 : std::forward<U>(u)();
2068 }
2069
2070 /// \group map_or_else
2071 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u)
2072 /// const &;
2073 template <class F, class U>
2074 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) const & {
2075 return has_value() ? detail::invoke(std::forward<F>(f), **this)
2076 : std::forward<U>(u)();
2077 }
2078
2079#ifndef TL_OPTIONAL_NO_CONSTRR
2080 /// \group map_or_else
2081 /// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u)
2082 /// const &&;
2083 template <class F, class U>
2084 detail::invoke_result_t<U> map_or_else(F &&f, U &&u) const && {
2085 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
2086 : std::forward<U>(u)();
2087 }
2088#endif
2089
2090 /// \returns `u` if `*this` has a value, otherwise an empty optional.
2091 template <class U>
2092 constexpr optional<typename std::decay<U>::type> conjunction(U &&u) const {
2093 using result = optional<detail::decay_t<U>>;
2094 return has_value() ? result{u} : result{nullopt};
2095 }
2096
2097 /// \returns `rhs` if `*this` is empty, otherwise the current value.
2098 /// \group disjunction
2099 TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) & {
2100 return has_value() ? *this : rhs;
2101 }
2102
2103 /// \group disjunction
2104 constexpr optional disjunction(const optional &rhs) const & {
2105 return has_value() ? *this : rhs;
2106 }
2107
2108 /// \group disjunction
2109 TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) && {
2110 return has_value() ? std::move(*this) : rhs;
2111 }
2112
2113#ifndef TL_OPTIONAL_NO_CONSTRR
2114 /// \group disjunction
2115 constexpr optional disjunction(const optional &rhs) const && {
2116 return has_value() ? std::move(*this) : rhs;
2117 }
2118#endif
2119
2120 /// \group disjunction
2121 TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) & {
2122 return has_value() ? *this : std::move(rhs);
2123 }
2124
2125 /// \group disjunction
2126 constexpr optional disjunction(optional &&rhs) const & {
2127 return has_value() ? *this : std::move(rhs);
2128 }
2129
2130 /// \group disjunction
2131 TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) && {
2132 return has_value() ? std::move(*this) : std::move(rhs);
2133 }
2134
2135#ifndef TL_OPTIONAL_NO_CONSTRR
2136 /// \group disjunction
2137 constexpr optional disjunction(optional &&rhs) const && {
2138 return has_value() ? std::move(*this) : std::move(rhs);
2139 }
2140#endif
2141
2142 /// Takes the value out of the optional, leaving it empty
2143 /// \group take
2144 optional take() & {
2145 optional ret = *this;
2146 reset();
2147 return ret;
2148 }
2149
2150 /// \group take
2151 optional take() const & {
2152 optional ret = *this;
2153 reset();
2154 return ret;
2155 }
2156
2157 /// \group take
2158 optional take() && {
2159 optional ret = std::move(*this);
2160 reset();
2161 return ret;
2162 }
2163
2164#ifndef TL_OPTIONAL_NO_CONSTRR
2165 /// \group take
2166 optional take() const && {
2167 optional ret = std::move(*this);
2168 reset();
2169 return ret;
2170 }
2171#endif
2172
2173 using value_type = T &;
2174
2175 /// Constructs an optional that does not contain a value.
2176 /// \group ctor_empty
2177 constexpr optional() noexcept : m_value(nullptr) {}
2178
2179 /// \group ctor_empty
2180 constexpr optional(nullopt_t) noexcept : m_value(nullptr) {}
2181
2182 /// Copy constructor
2183 ///
2184 /// If `rhs` contains a value, the stored value is direct-initialized with
2185 /// it. Otherwise, the constructed optional is empty.
2186 TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs) noexcept = default;
2187
2188 /// Move constructor
2189 ///
2190 /// If `rhs` contains a value, the stored value is direct-initialized with
2191 /// it. Otherwise, the constructed optional is empty.
2192 TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs) = default;
2193
2194 /// Constructs the stored value with `u`.
2195 /// \synopsis template <class U=T> constexpr optional(U &&u);
2196 template <class U = T,
2197 detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
2198 * = nullptr>
2199 constexpr optional(U &&u) : m_value(std::addressof(u)) {
2200 static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
2201 }
2202
2203 /// \exclude
2204 template <class U>
2205 constexpr explicit optional(const optional<U> &rhs) : optional(*rhs) {}
2206
2207 /// No-op
2208 ~optional() = default;
2209
2210 /// Assignment to empty.
2211 ///
2212 /// Destroys the current value if there is one.
2213 optional &operator=(nullopt_t) noexcept {
2214 m_value = nullptr;
2215 return *this;
2216 }
2217
2218 /// Copy assignment.
2219 ///
2220 /// Rebinds this optional to the referee of `rhs` if there is one. Otherwise
2221 /// resets the stored value in `*this`.
2222 optional &operator=(const optional &rhs) = default;
2223
2224 /// Rebinds this optional to `u`.
2225 ///
2226 /// \requires `U` must be an lvalue reference.
2227 /// \synopsis optional &operator=(U &&u);
2228 template <class U = T,
2229 detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
2230 * = nullptr>
2231 optional &operator=(U &&u) {
2232 static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
2233 m_value = std::addressof(u);
2234 return *this;
2235 }
2236
2237 /// Converting copy assignment operator.
2238 ///
2239 /// Rebinds this optional to the referee of `rhs` if there is one. Otherwise
2240 /// resets the stored value in `*this`.
2241 template <class U> optional &operator=(const optional<U> &rhs) {
2242 m_value = std::addressof(rhs.value());
2243 return *this;
2244 }
2245
2246 /// Constructs the value in-place, destroying the current one if there is
2247 /// one.
2248 ///
2249 /// \group emplace
2250 template <class... Args> T &emplace(Args &&... args) noexcept {
2251 static_assert(std::is_constructible<T, Args &&...>::value,
2252 "T must be constructible with Args");
2253
2254 *this = nullopt;
2255 this->construct(std::forward<Args>(args)...);
2256 return value();
2257 }
2258
2259 /// Swaps this optional with the other.
2260 ///
2261 /// If neither optionals have a value, nothing happens.
2262 /// If both have a value, the values are swapped.
2263 /// If one has a value, it is moved to the other and the movee is left
2264 /// valueless.
2265 void swap(optional &rhs) noexcept { std::swap(m_value, rhs.m_value); }
2266
2267 /// \returns a pointer to the stored value
2268 /// \requires a value is stored
2269 /// \group pointer
2270 /// \synopsis constexpr const T *operator->() const;
2271 constexpr const T *operator->() const { return m_value; }
2272
2273 /// \group pointer
2274 /// \synopsis constexpr T *operator->();
2275 TL_OPTIONAL_11_CONSTEXPR T *operator->() { return m_value; }
2276
2277 /// \returns the stored value
2278 /// \requires a value is stored
2279 /// \group deref
2280 /// \synopsis constexpr T &operator*();
2281 TL_OPTIONAL_11_CONSTEXPR T &operator*() { return *m_value; }
2282
2283 /// \group deref
2284 /// \synopsis constexpr const T &operator*() const;
2285 constexpr const T &operator*() const { return *m_value; }
2286
2287 /// \returns whether or not the optional has a value
2288 /// \group has_value
2289 constexpr bool has_value() const noexcept { return m_value != nullptr; }
2290
2291 /// \group has_value
2292 constexpr explicit operator bool() const noexcept {
2293 return m_value != nullptr;
2294 }
2295
2296 /// \returns the contained value if there is one, otherwise throws
2297 /// [bad_optional_access]
2298 /// \group value
2299 /// synopsis constexpr T &value();
2300 TL_OPTIONAL_11_CONSTEXPR T &value() {
2301 if (has_value())
2302 return *m_value;
2303 throw bad_optional_access();
2304 }
2305 /// \group value
2306 /// \synopsis constexpr const T &value() const;
2307 TL_OPTIONAL_11_CONSTEXPR const T &value() const {
2308 if (has_value())
2309 return *m_value;
2310 throw bad_optional_access();
2311 }
2312
2313 /// \returns the stored value if there is one, otherwise returns `u`
2314 /// \group value_or
2315 template <class U> constexpr T value_or(U &&u) const & {
2316 static_assert(std::is_copy_constructible<T>::value &&
2317 std::is_convertible<U &&, T>::value,
2318 "T must be copy constructible and convertible from U");
2319 return has_value() ? **this : static_cast<T>(std::forward<U>(u));
2320 }
2321
2322 /// \group value_or
2323 template <class U> TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) && {
2324 static_assert(std::is_move_constructible<T>::value &&
2325 std::is_convertible<U &&, T>::value,
2326 "T must be move constructible and convertible from U");
2327 return has_value() ? **this : static_cast<T>(std::forward<U>(u));
2328 }
2329
2330 /// Destroys the stored value if one exists, making the optional empty
2331 void reset() noexcept { m_value = nullptr; }
2332
2333private:
2334 T *m_value;
2335}; // namespace tl
2336
2337
2338
2339} // namespace tl
2340
2341namespace std {
2342// TODO SFINAE
2343template <class T> struct hash<tl::optional<T>> {
2344 ::std::size_t operator()(const tl::optional<T> &o) const {
2345 if (!o.has_value())
2346 return 0;
2347
2348 return std::hash<tl::detail::remove_const_t<T>>()(*o);
2349 }
2350};
2351} // namespace std
2352
2353#endif