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