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