19#if __cplusplus > 201402L
25#ifndef TL_OPTIONAL_HPP
26#define TL_OPTIONAL_HPP
28#define TL_OPTIONAL_VERSION_MAJOR 1
29#define TL_OPTIONAL_VERSION_MINOR 1
30#define TL_OPTIONAL_VERSION_PATCH 0
37#if(defined(_MSC_VER) && _MSC_VER == 1900)
38#define TL_OPTIONAL_MSVC2015
41#if(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
42#define TL_OPTIONAL_GCC49
45#if(defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && !defined(__clang__))
46#define TL_OPTIONAL_GCC54
49#if(defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && !defined(__clang__))
50#define TL_OPTIONAL_GCC55
53#if(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
55#define TL_OPTIONAL_NO_CONSTRR
58#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::has_trivial_copy_constructor<T>::value
59#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
62#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
66#elif(defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
67#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
68#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
71template <
class T>
struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T> {};
73template <
class T,
class A>
struct is_trivially_copy_constructible<std::vector<T, A>> : std::is_trivially_copy_constructible<T> {};
79#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) nonstd::detail::is_trivially_copy_constructible<T>::value
80#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
81#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
83#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::is_trivially_copy_constructible<T>::value
84#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
85#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
88#if __cplusplus > 201103L
89#define TL_OPTIONAL_CXX14
93#if(__cplusplus == 201103L || defined(TL_OPTIONAL_MSVC2015) || defined(TL_OPTIONAL_GCC49))
94#define TL_OPTIONAL_11_CONSTEXPR
96#define TL_OPTIONAL_11_CONSTEXPR constexpr
100#ifndef TL_MONOSTATE_INPLACE_MUTEX
101#define TL_MONOSTATE_INPLACE_MUTEX
107 explicit in_place_t() =
default;
113template <
class T>
class optional;
116#ifndef TL_TRAITS_MUTEX
117#define TL_TRAITS_MUTEX
119template <
class T>
using remove_const_t =
typename std::remove_const<T>::type;
120template <
class T>
using remove_reference_t =
typename std::remove_reference<T>::type;
121template <
class T>
using decay_t =
typename std::decay<T>::type;
122template <
bool E,
class T =
void>
using enable_if_t =
typename std::enable_if<E, T>::type;
123template <
bool B,
class T,
class F>
using conditional_t =
typename std::conditional<B, T, F>::type;
128template <
class B,
class... Bs>
struct conjunction<B, Bs...> : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
130#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
131#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
137#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
138template <
class T>
struct is_pointer_to_non_const_member_func : std::false_type {};
139template <
class T,
class Ret,
class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)> : std::true_type {};
140template <
class T,
class Ret,
class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)&> : std::true_type {};
141template <
class T,
class Ret,
class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&> : std::true_type {};
142template <
class T,
class Ret,
class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile> : std::true_type {};
143template <
class T,
class Ret,
class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&> : std::true_type {};
144template <
class T,
class Ret,
class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&&> : std::true_type {};
146template <
class T>
struct is_const_or_const_ref : std::false_type {};
147template <
class T>
struct is_const_or_const_ref<T const&> : std::true_type {};
148template <
class T>
struct is_const_or_const_ref<T const> : std::true_type {};
153template <
typename Fn,
typename... Args,
154#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
155 typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value && is_const_or_const_ref<Args...>::value)>,
157 typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
int = 0>
158constexpr auto invoke(Fn&& f, Args&&... args)
noexcept(
noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
159 ->
decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
160 return std::mem_fn(f)(std::forward<Args>(args)...);
163template <
typename Fn,
typename... Args,
typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
164constexpr auto invoke(Fn&& f, Args&&... args)
noexcept(
noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
165 ->
decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
166 return std::forward<Fn>(f)(std::forward<Args>(args)...);
172template <
class F,
class... Us>
174 using type =
decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
177template <
class F,
class... Us>
using invoke_result =
invoke_result_impl<F, void, Us...>;
179template <
class F,
class... Us>
using invoke_result_t =
typename invoke_result<F, Us...>::type;
181#if defined(_MSC_VER) && _MSC_VER <= 1900
183template <
class T,
class U = T>
struct is_swappable : std::true_type {};
185template <
class T,
class U = T>
struct is_nothrow_swappable : std::true_type {};
188namespace swap_adl_tests {
193template <
class T>
tag swap(T&, T&);
194template <
class T, std::
size_t N>
tag swap(T (&a)[N], T (&b)[N]);
198template <
class,
class> std::false_type can_swap(...) noexcept(false);
199template <class T, class U, class = decltype(swap(std::declval<T&>(), std::declval<U&>()))>
200std::true_type can_swap(
int) noexcept(noexcept(swap(std::declval<T&>(), std::declval<U&>())));
202template <class, class> std::false_type uses_std(...);
203template <class T, class U> std::is_same<decltype(swap(std::declval<T&>(), std::declval<U&>())),
tag> uses_std(
int);
207: std::integral_constant<
bool, std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value> {};
211template <
class T,
class U>
struct is_adl_swap_noexcept : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
214template <
class T,
class U = T>
215struct is_swappable : std::integral_constant<bool, decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
216 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
217 (std::is_move_assignable<T>::value && std::is_move_constructible<T>::value))> {};
219template <
class T, std::
size_t N>
221: std::integral_constant<bool, decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
222 (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value || is_swappable<T, T>::value)> {};
224template <
class T,
class U = T>
226: std::integral_constant<bool, is_swappable<T, U>::value && ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
227 detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
228 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
229 detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> {};
234template <
class...>
struct voider {
using type = void; };
235template <
class... Ts>
using void_t =
typename voider<Ts...>::type;
243template <
class U>
using fixup_void = conditional_t<std::is_void<U>::value,
monostate, U>;
249template <
class F,
class... U>
250struct returns_void_impl<F, void_t<invoke_result_t<F, U...>>, U...> : std::is_void<invoke_result_t<F, U...>> {};
251template <
class F,
class... U>
using returns_void =
returns_void_impl<F, void, U...>;
253template <
class T,
class... U>
using enable_if_ret_void = enable_if_t<returns_void<T&&, U...>::value>;
255template <
class T,
class... U>
using disable_if_ret_void = enable_if_t<!returns_void<T&&, U...>::value>;
257template <
class T,
class U>
258using enable_forward_value =
259 detail::enable_if_t<std::is_constructible<T, U&&>::value && !std::is_same<detail::decay_t<U>,
in_place_t>::value &&
260 !std::is_same<optional<T>, detail::decay_t<U>>::value>;
262template <
class T,
class U,
class Other>
263using enable_from_other =
264 detail::enable_if_t<std::is_constructible<T, Other>::value && !std::is_constructible<T, optional<U>&>::value &&
265 !std::is_constructible<T, optional<U>&&>::value && !std::is_constructible<T, const optional<U>&>::value &&
266 !std::is_constructible<T, const optional<U>&&>::value && !std::is_convertible<optional<U>&, T>::value &&
267 !std::is_convertible<optional<U>&&, T>::value && !std::is_convertible<const optional<U>&, T>::value &&
268 !std::is_convertible<const optional<U>&&, T>::value>;
270template <
class T,
class U>
271using enable_assign_forward = detail::enable_if_t<!std::is_same<optional<T>, detail::decay_t<U>>::value &&
273 std::is_constructible<T, U>::value && std::is_assignable<T&, U>::value>;
275template <
class T,
class U,
class Other>
276using enable_assign_from_other =
277 detail::enable_if_t<std::is_constructible<T, Other>::value && std::is_assignable<T&, Other>::value &&
278 !std::is_constructible<T, optional<U>&>::value && !std::is_constructible<T, optional<U>&&>::value &&
279 !std::is_constructible<T, const optional<U>&>::value && !std::is_constructible<T, const optional<U>&&>::value &&
280 !std::is_convertible<optional<U>&, T>::value && !std::is_convertible<optional<U>&&, T>::value &&
281 !std::is_convertible<const optional<U>&, T>::value && !std::is_convertible<const optional<U>&&, T>::value &&
282 !std::is_assignable<T&, optional<U>&>::value && !std::is_assignable<T&, optional<U>&&>::value &&
283 !std::is_assignable<T&, const optional<U>&>::value && !std::is_assignable<T&, const optional<U>&&>::value>;
288template <class T, bool = ::std::is_trivially_destructible<T>::value>
struct optional_storage_base {
289 TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
291 , m_has_value(
false) {}
293 template <
class... U>
294 TL_OPTIONAL_11_CONSTEXPR optional_storage_base(
in_place_t, U&&... u)
295 : m_value(std::forward<U>(u)...)
296 , m_has_value(
true) {}
298 ~optional_storage_base() {
315template <
class T>
struct optional_storage_base<T, true> {
316 TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
318 , m_has_value(
false) {}
320 template <
class... U>
321 TL_OPTIONAL_11_CONSTEXPR optional_storage_base(
in_place_t, U&&... u)
322 : m_value(std::forward<U>(u)...)
323 , m_has_value(
true) {}
333 bool m_has_value =
false;
339 using optional_storage_base<T>::optional_storage_base;
341 void hard_reset()
noexcept {
343 this->m_has_value =
false;
346 template <
class... Args>
void construct(Args&&... args) {
347 new(std::addressof(this->m_value)) T(std::forward<Args>(args)...);
348 this->m_has_value =
true;
351 template <
class Opt>
void assign(Opt&& rhs) {
352 if(this->has_value()) {
353 if(rhs.has_value()) {
354 this->m_value = std::forward<Opt>(rhs).get();
357 this->m_has_value =
false;
361 else if(rhs.has_value()) {
362 construct(std::forward<Opt>(rhs).get());
366 bool has_value()
const {
return this->m_has_value; }
368 TL_OPTIONAL_11_CONSTEXPR T& get() & {
return this->m_value; }
369 TL_OPTIONAL_11_CONSTEXPR
const T& get()
const& {
return this->m_value; }
370 TL_OPTIONAL_11_CONSTEXPR T&& get() && {
return std::move(this->m_value); }
371#ifndef TL_OPTIONAL_NO_CONSTRR
372 constexpr const T&& get()
const&& {
return std::move(this->m_value); }
386 optional_copy_base() =
default;
387 optional_copy_base(
const optional_copy_base& rhs)
389 if(rhs.has_value()) {
390 this->construct(rhs.get());
392 this->m_has_value =
false;
396 optional_copy_base(optional_copy_base&& rhs) =
default;
397 optional_copy_base& operator=(
const optional_copy_base& rhs) =
default;
398 optional_copy_base& operator=(optional_copy_base&& rhs) =
default;
406#ifndef TL_OPTIONAL_GCC49
416 optional_move_base() =
default;
417 optional_move_base(
const optional_move_base& rhs) =
default;
419 optional_move_base(optional_move_base&& rhs)
noexcept(std::is_nothrow_move_constructible<T>::value) {
420 if(rhs.has_value()) {
421 this->construct(std::move(rhs.get()));
423 this->m_has_value =
false;
426 optional_move_base& operator=(
const optional_move_base& rhs) =
default;
427 optional_move_base& operator=(optional_move_base&& rhs) =
default;
431template <
class T,
bool = TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) && TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) &&
432 TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
440 optional_copy_assign_base() =
default;
441 optional_copy_assign_base(
const optional_copy_assign_base& rhs) =
default;
443 optional_copy_assign_base(optional_copy_assign_base&& rhs) =
default;
444 optional_copy_assign_base& operator=(
const optional_copy_assign_base& rhs) {
448 optional_copy_assign_base& operator=(optional_copy_assign_base&& rhs) =
default;
456#ifndef TL_OPTIONAL_GCC49
457template <class T, bool = std::is_trivially_destructible<T>::value&& std::is_trivially_move_constructible<T>::value&&
458 std::is_trivially_move_assignable<T>::value>
469 optional_move_assign_base() =
default;
470 optional_move_assign_base(
const optional_move_assign_base& rhs) =
default;
472 optional_move_assign_base(optional_move_assign_base&& rhs) =
default;
474 optional_move_assign_base& operator=(
const optional_move_assign_base& rhs) =
default;
476 optional_move_assign_base& operator=(optional_move_assign_base&& rhs)
noexcept(
477 std::is_nothrow_move_constructible<T>::value&& std::is_nothrow_move_assignable<T>::value) {
478 this->assign(std::move(rhs));
485template <class T, bool EnableCopy = std::is_copy_constructible<T>::value,
bool EnableMove = std::is_move_constructible<T>::value>
486struct optional_delete_ctor_base {
487 optional_delete_ctor_base() =
default;
488 optional_delete_ctor_base(
const optional_delete_ctor_base&) =
default;
489 optional_delete_ctor_base(optional_delete_ctor_base&&)
noexcept =
default;
490 optional_delete_ctor_base& operator=(
const optional_delete_ctor_base&) =
default;
491 optional_delete_ctor_base& operator=(optional_delete_ctor_base&&)
noexcept =
default;
494template <
class T>
struct optional_delete_ctor_base<T, true, false> {
495 optional_delete_ctor_base() =
default;
496 optional_delete_ctor_base(
const optional_delete_ctor_base&) =
default;
497 optional_delete_ctor_base(optional_delete_ctor_base&&)
noexcept =
delete;
498 optional_delete_ctor_base& operator=(
const optional_delete_ctor_base&) =
default;
499 optional_delete_ctor_base& operator=(optional_delete_ctor_base&&)
noexcept =
default;
502template <
class T>
struct optional_delete_ctor_base<T, false, true> {
503 optional_delete_ctor_base() =
default;
504 optional_delete_ctor_base(
const optional_delete_ctor_base&) =
delete;
505 optional_delete_ctor_base(optional_delete_ctor_base&&)
noexcept =
default;
506 optional_delete_ctor_base& operator=(
const optional_delete_ctor_base&) =
default;
507 optional_delete_ctor_base& operator=(optional_delete_ctor_base&&)
noexcept =
default;
510template <
class T>
struct optional_delete_ctor_base<T, false, false> {
511 optional_delete_ctor_base() =
default;
512 optional_delete_ctor_base(
const optional_delete_ctor_base&) =
delete;
513 optional_delete_ctor_base(optional_delete_ctor_base&&)
noexcept =
delete;
514 optional_delete_ctor_base& operator=(
const optional_delete_ctor_base&) =
default;
515 optional_delete_ctor_base& operator=(optional_delete_ctor_base&&)
noexcept =
default;
520template <
class T,
bool EnableCopy = (std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value),
521 bool EnableMove = (std::is_move_constructible<T>::value && std::is_move_assignable<T>::value)>
522struct optional_delete_assign_base {
523 optional_delete_assign_base() =
default;
524 optional_delete_assign_base(
const optional_delete_assign_base&) =
default;
525 optional_delete_assign_base(optional_delete_assign_base&&)
noexcept =
default;
526 optional_delete_assign_base& operator=(
const optional_delete_assign_base&) =
default;
527 optional_delete_assign_base& operator=(optional_delete_assign_base&&)
noexcept =
default;
530template <
class T>
struct optional_delete_assign_base<T, true, false> {
531 optional_delete_assign_base() =
default;
532 optional_delete_assign_base(
const optional_delete_assign_base&) =
default;
533 optional_delete_assign_base(optional_delete_assign_base&&)
noexcept =
default;
534 optional_delete_assign_base& operator=(
const optional_delete_assign_base&) =
default;
535 optional_delete_assign_base& operator=(optional_delete_assign_base&&)
noexcept =
delete;
538template <
class T>
struct optional_delete_assign_base<T, false, true> {
539 optional_delete_assign_base() =
default;
540 optional_delete_assign_base(
const optional_delete_assign_base&) =
default;
541 optional_delete_assign_base(optional_delete_assign_base&&)
noexcept =
default;
542 optional_delete_assign_base& operator=(
const optional_delete_assign_base&) =
delete;
543 optional_delete_assign_base& operator=(optional_delete_assign_base&&)
noexcept =
default;
546template <
class T>
struct optional_delete_assign_base<T, false, false> {
547 optional_delete_assign_base() =
default;
548 optional_delete_assign_base(
const optional_delete_assign_base&) =
default;
549 optional_delete_assign_base(optional_delete_assign_base&&)
noexcept =
default;
550 optional_delete_assign_base& operator=(
const optional_delete_assign_base&) =
delete;
551 optional_delete_assign_base& operator=(optional_delete_assign_base&&)
noexcept =
delete;
564class bad_optional_access :
public std::exception {
566 bad_optional_access() =
default;
567 const char* what()
const noexcept {
return "Optional has no value"; }
582 static_assert(!std::is_same<T, in_place_t>::value,
"instantiation of optional with in_place_t is ill-formed");
583 static_assert(!std::is_same<detail::decay_t<T>,
nullopt_t>
::value,
"instantiation of optional with nullopt_t is ill-formed");
590#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
593 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto and_then(F&& f) & {
594 using result = detail::invoke_result_t<F, T&>;
595 static_assert(detail::is_optional<result>::value,
"F must return an optional");
597 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
600 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto and_then(F&& f) && {
601 using result = detail::invoke_result_t<F, T&&>;
602 static_assert(detail::is_optional<result>::value,
"F must return an optional");
604 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : result(nullopt);
607 template <
class F>
constexpr auto and_then(F&& f)
const& {
608 using result = detail::invoke_result_t<F, const T&>;
609 static_assert(detail::is_optional<result>::value,
"F must return an optional");
611 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
614#ifndef TL_OPTIONAL_NO_CONSTRR
615 template <
class F>
constexpr auto and_then(F&& f)
const&& {
616 using result = detail::invoke_result_t<F, const T&&>;
617 static_assert(detail::is_optional<result>::value,
"F must return an optional");
619 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : result(nullopt);
625 template <
class F> TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&>
and_then(F&& f) & {
626 using result = detail::invoke_result_t<F, T&>;
627 static_assert(detail::is_optional<result>::value,
"F must return an optional");
629 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
632 template <
class F> TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&&>
and_then(F&& f) && {
633 using result = detail::invoke_result_t<F, T&&>;
634 static_assert(detail::is_optional<result>::value,
"F must return an optional");
636 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : result(nullopt);
639 template <
class F>
constexpr detail::invoke_result_t<F, const T&>
and_then(F&& f)
const& {
640 using result = detail::invoke_result_t<F, const T&>;
641 static_assert(detail::is_optional<result>::value,
"F must return an optional");
643 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
646#ifndef TL_OPTIONAL_NO_CONSTRR
647 template <
class F>
constexpr detail::invoke_result_t<F, const T&&>
and_then(F&& f)
const&& {
648 using result = detail::invoke_result_t<F, const T&&>;
649 static_assert(detail::is_optional<result>::value,
"F must return an optional");
651 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : result(nullopt);
656#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
658 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto map(F&& f) & {
return optional_map_impl(*
this, std::forward<F>(f)); }
660 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto map(F&& f) && {
return optional_map_impl(std::move(*
this), std::forward<F>(f)); }
662 template <
class F>
constexpr auto map(F&& f)
const& {
return optional_map_impl(*
this, std::forward<F>(f)); }
664 template <
class F>
constexpr auto map(F&& f)
const&& {
return optional_map_impl(std::move(*
this), std::forward<F>(f)); }
667 template <
class F> TL_OPTIONAL_11_CONSTEXPR
decltype(optional_map_impl(std::declval<optional&>(), std::declval<F&&>()))
map(F&& f) & {
668 return optional_map_impl(*
this, std::forward<F>(f));
671 template <
class F> TL_OPTIONAL_11_CONSTEXPR
decltype(optional_map_impl(std::declval<optional&&>(), std::declval<F&&>()))
map(F&& f) && {
672 return optional_map_impl(std::move(*
this), std::forward<F>(f));
675 template <
class F>
constexpr decltype(optional_map_impl(std::declval<const optional&>(), std::declval<F&&>()))
map(F&& f)
const& {
676 return optional_map_impl(*
this, std::forward<F>(f));
679#ifndef TL_OPTIONAL_NO_CONSTRR
680 template <
class F>
constexpr decltype(optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>()))
map(F&& f)
const&& {
681 return optional_map_impl(std::move(*
this), std::forward<F>(f));
686#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
688 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto transform(F&& f) & {
return optional_map_impl(*
this, std::forward<F>(f)); }
690 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto transform(F&& f) && {
return optional_map_impl(std::move(*
this), std::forward<F>(f)); }
692 template <
class F>
constexpr auto transform(F&& f)
const& {
return optional_map_impl(*
this, std::forward<F>(f)); }
694 template <
class F>
constexpr auto transform(F&& f)
const&& {
return optional_map_impl(std::move(*
this), std::forward<F>(f)); }
698 TL_OPTIONAL_11_CONSTEXPR
decltype(optional_map_impl(std::declval<optional&>(), std::declval<F&&>()))
transform(F&& f) & {
699 return optional_map_impl(*
this, std::forward<F>(f));
703 TL_OPTIONAL_11_CONSTEXPR
decltype(optional_map_impl(std::declval<optional&&>(), std::declval<F&&>()))
transform(F&& f) && {
704 return optional_map_impl(std::move(*
this), std::forward<F>(f));
707 template <
class F>
constexpr decltype(optional_map_impl(std::declval<const optional&>(), std::declval<F&&>()))
transform(F&& f)
const& {
708 return optional_map_impl(*
this, std::forward<F>(f));
711#ifndef TL_OPTIONAL_NO_CONSTRR
713 constexpr decltype(optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>()))
transform(F&& f)
const&& {
714 return optional_map_impl(std::move(*
this), std::forward<F>(f));
720 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR
or_else(F&& f) & {
724 std::forward<F>(f)();
728 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR
or_else(F&& f) & {
729 return has_value() ? *this : std::forward<F>(f)();
732 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
optional<T> or_else(F&& f) && {
734 return std::move(*
this);
736 std::forward<F>(f)();
740 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR
or_else(F&& f) && {
741 return has_value() ? std::move(*
this) : std::forward<F>(f)();
744 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
optional<T> or_else(F&& f)
const& {
748 std::forward<F>(f)();
752 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR
or_else(F&& f)
const& {
753 return has_value() ? *this : std::forward<F>(f)();
756#ifndef TL_OPTIONAL_NO_CONSTRR
757 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
optional<T> or_else(F&& f)
const&& {
759 return std::move(*
this);
761 std::forward<F>(f)();
765 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> or_else(F&& f)
const&& {
766 return has_value() ? std::move(*
this) : std::forward<F>(f)();
771 template <
class F,
class U> U
map_or(F&& f, U&& u) & {
772 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u);
775 template <
class F,
class U> U
map_or(F&& f, U&& u) && {
776 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u);
779 template <
class F,
class U> U
map_or(F&& f, U&& u)
const& {
780 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u);
783#ifndef TL_OPTIONAL_NO_CONSTRR
784 template <
class F,
class U> U
map_or(F&& f, U&& u)
const&& {
785 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u);
791 template <
class F,
class U> detail::invoke_result_t<U>
map_or_else(F&& f, U&& u) & {
792 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u)();
795 template <
class F,
class U> detail::invoke_result_t<U>
map_or_else(F&& f, U&& u) && {
796 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u)();
799 template <
class F,
class U> detail::invoke_result_t<U>
map_or_else(F&& f, U&& u)
const& {
800 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u)();
803#ifndef TL_OPTIONAL_NO_CONSTRR
804 template <
class F,
class U> detail::invoke_result_t<U>
map_or_else(F&& f, U&& u)
const&& {
805 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u)();
812 return has_value() ? result{u} : result{nullopt};
822#ifndef TL_OPTIONAL_NO_CONSTRR
832#ifndef TL_OPTIONAL_NO_CONSTRR
843 using value_type = T;
863 template <
class... Args>
864 constexpr explicit optional(detail::enable_if_t<std::is_constructible<T, Args...>::value,
in_place_t>, Args&&... args)
865 : base(in_place, std::forward<Args>(args)...) {}
867 template <
class U,
class... Args>
868 TL_OPTIONAL_11_CONSTEXPR
explicit optional(
869 detail::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>
::value,
in_place_t>, std::initializer_list<U> il,
871 this->construct(il, std::forward<Args>(args)...);
875 template <class U = T, detail::enable_if_t<std::is_convertible<U&&, T>::value>* =
nullptr,
876 detail::enable_forward_value<T, U>* =
nullptr>
878 : base(in_place, std::forward<U>(u)) {}
880 template <class U = T, detail::enable_if_t<!std::is_convertible<U&&, T>::value>* =
nullptr,
881 detail::enable_forward_value<T, U>* =
nullptr>
883 : base(in_place, std::forward<U>(u)) {}
886 template <
class U, detail::enable_from_other<T, U, const U&>* =
nullptr,
887 detail::enable_if_t<std::is_convertible<const U&, T>::value>* =
nullptr>
890 this->construct(*rhs);
894 template <
class U, detail::enable_from_other<T, U, const U&>* =
nullptr,
895 detail::enable_if_t<!std::is_convertible<const U&, T>::value>* =
nullptr>
898 this->construct(*rhs);
903 template <
class U, detail::enable_from_other<T, U, U&&>* =
nullptr, detail::enable_if_t<std::is_convertible<U&&, T>::value>* =
nullptr>
906 this->construct(std::move(*rhs));
910 template <
class U, detail::enable_from_other<T, U, U&&>* =
nullptr, detail::enable_if_t<!std::is_convertible<U&&, T>::value>* =
nullptr>
913 this->construct(std::move(*rhs));
926 this->m_has_value =
false;
946 template <
class U = T, detail::enable_assign_forward<T, U>* =
nullptr>
optional&
operator=(U&& u) {
948 this->m_value = std::forward<U>(u);
950 this->construct(std::forward<U>(u));
963 this->m_value = *rhs;
970 this->construct(*rhs);
984 this->m_value = std::move(*rhs);
991 this->construct(std::move(*rhs));
999 template <
class... Args> T&
emplace(Args&&... args) {
1000 static_assert(std::is_constructible<T, Args&&...>
::value,
"T must be constructible with Args");
1003 this->construct(std::forward<Args>(args)...);
1007 template <
class U,
class... Args>
1008 detail::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>
::value, T&>
emplace(std::initializer_list<U> il,
1011 this->construct(il, std::forward<Args>(args)...);
1027 new(std::addressof(rhs.m_value)) T(std::move(this->m_value));
1028 this->m_value.T::~T();
1031 new(std::addressof(this->m_value)) T(std::move(rhs.m_value));
1032 rhs.m_value.T::~T();
1034 swap(this->m_has_value, rhs.m_has_value);
1038 constexpr const T*
operator->()
const {
return std::addressof(this->m_value); }
1040 TL_OPTIONAL_11_CONSTEXPR T*
operator->() {
return std::addressof(this->m_value); }
1043 TL_OPTIONAL_11_CONSTEXPR T&
operator*() & {
return this->m_value; }
1045 constexpr const T&
operator*() const& {
return this->m_value; }
1047 TL_OPTIONAL_11_CONSTEXPR T&&
operator*() && {
return std::move(this->m_value); }
1049#ifndef TL_OPTIONAL_NO_CONSTRR
1050 constexpr const T&&
operator*() const&& {
return std::move(this->m_value); }
1054 constexpr bool has_value() const noexcept {
return this->m_has_value; }
1056 constexpr explicit operator bool() const noexcept {
return this->m_has_value; }
1061 return this->m_value;
1064 TL_OPTIONAL_11_CONSTEXPR
const T&
value() const& {
1066 return this->m_value;
1069 TL_OPTIONAL_11_CONSTEXPR T&&
value() && {
1071 return std::move(this->m_value);
1072 throw bad_optional_access();
1075#ifndef TL_OPTIONAL_NO_CONSTRR
1076 TL_OPTIONAL_11_CONSTEXPR
const T&&
value() const&& {
1078 return std::move(this->m_value);
1079 throw bad_optional_access();
1084 template <
class U>
constexpr T
value_or(U&& u)
const& {
1085 static_assert(std::is_copy_constructible<T>::value && std::is_convertible<U&&, T>::value,
1086 "T must be copy constructible and convertible from U");
1087 return has_value() ? **this :
static_cast<T
>(std::forward<U>(u));
1090 template <
class U> TL_OPTIONAL_11_CONSTEXPR T
value_or(U&& u) && {
1091 static_assert(std::is_move_constructible<T>::value && std::is_convertible<U&&, T>::value,
1092 "T must be move constructible and convertible from U");
1093 return has_value() ? std::move(**
this) : static_cast<T>(std::forward<U>(u));
1100 this->m_has_value =
false;
1106template <
class T,
class U>
inline constexpr bool operator==(
const optional<T>& lhs,
const optional<U>& rhs) {
1107 return lhs.has_value() == rhs.has_value() && (!lhs.has_value() || *lhs == *rhs);
1109template <
class T,
class U>
inline constexpr bool operator!=(
const optional<T>& lhs,
const optional<U>& rhs) {
1110 return lhs.has_value() != rhs.has_value() || (lhs.has_value() && *lhs != *rhs);
1112template <
class T,
class U>
inline constexpr bool operator<(
const optional<T>& lhs,
const optional<U>& rhs) {
1113 return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs);
1115template <
class T,
class U>
inline constexpr bool operator>(
const optional<T>& lhs,
const optional<U>& rhs) {
1116 return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs);
1118template <
class T,
class U>
inline constexpr bool operator<=(
const optional<T>& lhs,
const optional<U>& rhs) {
1119 return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs);
1121template <
class T,
class U>
inline constexpr bool operator>=(
const optional<T>& lhs,
const optional<U>& rhs) {
1122 return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs);
1126template <
class T>
inline constexpr bool operator==(
const optional<T>& lhs,
nullopt_t)
noexcept {
return !lhs.has_value(); }
1127template <
class T>
inline constexpr bool operator==(
nullopt_t,
const optional<T>& rhs)
noexcept {
return !rhs.has_value(); }
1128template <
class T>
inline constexpr bool operator!=(
const optional<T>& lhs,
nullopt_t)
noexcept {
return lhs.has_value(); }
1129template <
class T>
inline constexpr bool operator!=(
nullopt_t,
const optional<T>& rhs)
noexcept {
return rhs.has_value(); }
1130template <
class T>
inline constexpr bool operator<(
const optional<T>&,
nullopt_t)
noexcept {
return false; }
1131template <
class T>
inline constexpr bool operator<(
nullopt_t,
const optional<T>& rhs)
noexcept {
return rhs.has_value(); }
1132template <
class T>
inline constexpr bool operator<=(
const optional<T>& lhs,
nullopt_t)
noexcept {
return !lhs.has_value(); }
1133template <
class T>
inline constexpr bool operator<=(
nullopt_t,
const optional<T>&)
noexcept {
return true; }
1134template <
class T>
inline constexpr bool operator>(
const optional<T>& lhs,
nullopt_t)
noexcept {
return lhs.has_value(); }
1135template <
class T>
inline constexpr bool operator>(
nullopt_t,
const optional<T>&)
noexcept {
return false; }
1136template <
class T>
inline constexpr bool operator>=(
const optional<T>&,
nullopt_t)
noexcept {
return true; }
1137template <
class T>
inline constexpr bool operator>=(
nullopt_t,
const optional<T>& rhs)
noexcept {
return !rhs.has_value(); }
1140template <
class T,
class U>
inline constexpr bool operator==(
const optional<T>& lhs,
const U& rhs) {
1141 return lhs.has_value() ? *lhs == rhs :
false;
1143template <
class T,
class U>
inline constexpr bool operator==(
const U& lhs,
const optional<T>& rhs) {
1144 return rhs.has_value() ? lhs == *rhs :
false;
1146template <
class T,
class U>
inline constexpr bool operator!=(
const optional<T>& lhs,
const U& rhs) {
1147 return lhs.has_value() ? *lhs != rhs :
true;
1149template <
class T,
class U>
inline constexpr bool operator!=(
const U& lhs,
const optional<T>& rhs) {
1150 return rhs.has_value() ? lhs != *rhs :
true;
1152template <
class T,
class U>
inline constexpr bool operator<(
const optional<T>& lhs,
const U& rhs) {
1153 return lhs.has_value() ? *lhs < rhs :
true;
1155template <
class T,
class U>
inline constexpr bool operator<(
const U& lhs,
const optional<T>& rhs) {
1156 return rhs.has_value() ? lhs < *rhs :
false;
1158template <
class T,
class U>
inline constexpr bool operator<=(
const optional<T>& lhs,
const U& rhs) {
1159 return lhs.has_value() ? *lhs <= rhs :
true;
1161template <
class T,
class U>
inline constexpr bool operator<=(
const U& lhs,
const optional<T>& rhs) {
1162 return rhs.has_value() ? lhs <= *rhs :
false;
1164template <
class T,
class U>
inline constexpr bool operator>(
const optional<T>& lhs,
const U& rhs) {
1165 return lhs.has_value() ? *lhs > rhs :
false;
1167template <
class T,
class U>
inline constexpr bool operator>(
const U& lhs,
const optional<T>& rhs) {
1168 return rhs.has_value() ? lhs > *rhs :
true;
1170template <
class T,
class U>
inline constexpr bool operator>=(
const optional<T>& lhs,
const U& rhs) {
1171 return lhs.has_value() ? *lhs >= rhs :
false;
1173template <
class T,
class U>
inline constexpr bool operator>=(
const U& lhs,
const optional<T>& rhs) {
1174 return rhs.has_value() ? lhs >= *rhs :
true;
1177template <class T, detail::enable_if_t<std::is_move_constructible<T>::value>* =
nullptr,
1178 detail::enable_if_t<detail::is_swappable<T>::value>* =
nullptr>
1180 return lhs.swap(rhs);
1188 class Ret = detail::conditional_t<std::is_same<T, detail::i_am_secret>::value, detail::decay_t<U>, T>>
1193template <
class T,
class... Args>
inline constexpr optional<T> make_optional(Args&&... args) {
1194 return optional<T>(in_place, std::forward<Args>(args)...);
1196template <
class T,
class U,
class... Args>
inline constexpr optional<T> make_optional(std::initializer_list<U> il, Args&&... args) {
1197 return optional<T>(in_place, il, std::forward<Args>(args)...);
1200#if __cplusplus >= 201703L
1206#ifdef TL_OPTIONAL_CXX14
1207template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
1208 detail::enable_if_t<!std::is_void<Ret>::value>* =
nullptr>
1209constexpr auto optional_map_impl(Opt&& opt, F&& f) {
1210 return opt.has_value() ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt)) : optional<Ret>(nullopt);
1213template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
1214 detail::enable_if_t<std::is_void<Ret>::value>* =
nullptr>
1215auto optional_map_impl(Opt&& opt, F&& f) {
1216 if(opt.has_value()) {
1217 detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
1218 return make_optional(monostate{});
1221 return optional<monostate>(nullopt);
1224template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
1225 detail::enable_if_t<!std::is_void<Ret>::value>* =
nullptr>
1227constexpr auto optional_map_impl(Opt&& opt, F&& f) -> optional<Ret> {
1228 return opt.has_value() ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt)) : optional<Ret>(nullopt);
1231template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
1232 detail::enable_if_t<std::is_void<Ret>::value>* =
nullptr>
1234auto optional_map_impl(Opt&& opt, F&& f) -> optional<monostate> {
1235 if(opt.has_value()) {
1236 detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
1253#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
1257 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto and_then(F&& f) & {
1258 using result = detail::invoke_result_t<F, T&>;
1259 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1261 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
1264 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto and_then(F&& f) && {
1265 using result = detail::invoke_result_t<F, T&>;
1266 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1268 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
1271 template <
class F>
constexpr auto and_then(F&& f)
const& {
1272 using result = detail::invoke_result_t<F, const T&>;
1273 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1275 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
1278#ifndef TL_OPTIONAL_NO_CONSTRR
1279 template <
class F>
constexpr auto and_then(F&& f)
const&& {
1280 using result = detail::invoke_result_t<F, const T&>;
1281 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1283 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
1289 template <
class F> TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&>
and_then(F&& f) & {
1290 using result = detail::invoke_result_t<F, T&>;
1291 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1293 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
1296 template <
class F> TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&> and_then(F&& f) && {
1297 using result = detail::invoke_result_t<F, T&>;
1298 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1300 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
1303 template <
class F>
constexpr detail::invoke_result_t<F, const T&> and_then(F&& f)
const& {
1304 using result = detail::invoke_result_t<F, const T&>;
1305 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1307 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : result(nullopt);
1310#ifndef TL_OPTIONAL_NO_CONSTRR
1311 template <
class F>
constexpr detail::invoke_result_t<F, const T&> and_then(F&& f)
const&& {
1312 using result = detail::invoke_result_t<F, const T&>;
1313 static_assert(detail::is_optional<result>::value,
"F must return an optional");
1315 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : result(nullopt);
1320#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
1322 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto map(F&& f) & {
return detail::optional_map_impl(*
this, std::forward<F>(f)); }
1324 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto map(F&& f) && {
1325 return detail::optional_map_impl(std::move(*
this), std::forward<F>(f));
1328 template <
class F>
constexpr auto map(F&& f)
const& {
return detail::optional_map_impl(*
this, std::forward<F>(f)); }
1330 template <
class F>
constexpr auto map(F&& f)
const&& {
return detail::optional_map_impl(std::move(*
this), std::forward<F>(f)); }
1334 TL_OPTIONAL_11_CONSTEXPR
decltype(detail::optional_map_impl(std::declval<optional&>(), std::declval<F&&>()))
map(F&& f) & {
1335 return detail::optional_map_impl(*
this, std::forward<F>(f));
1339 TL_OPTIONAL_11_CONSTEXPR
decltype(detail::optional_map_impl(std::declval<optional&&>(), std::declval<F&&>())) map(F&& f) && {
1340 return detail::optional_map_impl(std::move(*
this), std::forward<F>(f));
1344 constexpr decltype(detail::optional_map_impl(std::declval<const optional&>(), std::declval<F&&>())) map(F&& f)
const& {
1345 return detail::optional_map_impl(*
this, std::forward<F>(f));
1348#ifndef TL_OPTIONAL_NO_CONSTRR
1350 constexpr decltype(detail::optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>())) map(F&& f)
const&& {
1351 return detail::optional_map_impl(std::move(*
this), std::forward<F>(f));
1356#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
1358 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto transform(F&& f) & {
return detail::optional_map_impl(*
this, std::forward<F>(f)); }
1360 template <
class F> TL_OPTIONAL_11_CONSTEXPR
auto transform(F&& f) && {
1361 return detail::optional_map_impl(std::move(*
this), std::forward<F>(f));
1364 template <
class F>
constexpr auto transform(F&& f)
const& {
return detail::optional_map_impl(*
this, std::forward<F>(f)); }
1366 template <
class F>
constexpr auto transform(F&& f)
const&& {
return detail::optional_map_impl(std::move(*
this), std::forward<F>(f)); }
1370 TL_OPTIONAL_11_CONSTEXPR
decltype(detail::optional_map_impl(std::declval<optional&>(), std::declval<F&&>()))
transform(F&& f) & {
1371 return detail::optional_map_impl(*
this, std::forward<F>(f));
1377 TL_OPTIONAL_11_CONSTEXPR
decltype(detail::optional_map_impl(std::declval<optional&&>(), std::declval<F&&>()))
transform(F&& f) && {
1378 return detail::optional_map_impl(std::move(*
this), std::forward<F>(f));
1382 constexpr decltype(detail::optional_map_impl(std::declval<const optional&>(), std::declval<F&&>())) transform(F&& f)
const& {
1383 return detail::optional_map_impl(*
this, std::forward<F>(f));
1386#ifndef TL_OPTIONAL_NO_CONSTRR
1388 constexpr decltype(detail::optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>())) transform(F&& f)
const&& {
1389 return detail::optional_map_impl(std::move(*
this), std::forward<F>(f));
1395 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR
or_else(F&& f) & {
1399 std::forward<F>(f)();
1403 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & {
1404 return has_value() ? *this : std::forward<F>(f)();
1407 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr> optional<T> or_else(F&& f) && {
1409 return std::move(*
this);
1411 std::forward<F>(f)();
1415 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) && {
1416 return has_value() ? std::move(*
this) : std::forward<F>(f)();
1419 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
optional<T> or_else(F&& f)
const& {
1423 std::forward<F>(f)();
1427 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f)
const& {
1428 return has_value() ? *this : std::forward<F>(f)();
1431#ifndef TL_OPTIONAL_NO_CONSTRR
1432 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
optional<T> or_else(F&& f)
const&& {
1434 return std::move(*
this);
1436 std::forward<F>(f)();
1440 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
optional<T> or_else(F&& f)
const&& {
1441 return has_value() ? std::move(*
this) : std::forward<F>(f)();
1446 template <
class F,
class U> U
map_or(F&& f, U&& u) & {
1447 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u);
1450 template <
class F,
class U> U map_or(F&& f, U&& u) && {
1451 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u);
1454 template <
class F,
class U> U map_or(F&& f, U&& u)
const& {
1455 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u);
1458#ifndef TL_OPTIONAL_NO_CONSTRR
1459 template <
class F,
class U> U map_or(F&& f, U&& u)
const&& {
1460 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u);
1466 template <
class F,
class U> detail::invoke_result_t<U>
map_or_else(F&& f, U&& u) & {
1467 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u)();
1470 template <
class F,
class U> detail::invoke_result_t<U> map_or_else(F&& f, U&& u) && {
1471 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u)();
1474 template <
class F,
class U> detail::invoke_result_t<U> map_or_else(F&& f, U&& u)
const& {
1475 return has_value() ? detail::invoke(std::forward<F>(f), **
this) : std::forward<U>(u)();
1478#ifndef TL_OPTIONAL_NO_CONSTRR
1479 template <
class F,
class U> detail::invoke_result_t<U> map_or_else(F&& f, U&& u)
const&& {
1480 return has_value() ? detail::invoke(std::forward<F>(f), std::move(**
this)) : std::forward<U>(u)();
1487 return has_value() ? result{u} : result{nullopt};
1493 constexpr optional disjunction(
const optional& rhs)
const& {
return has_value() ? *this : rhs; }
1495 TL_OPTIONAL_11_CONSTEXPR optional disjunction(
const optional& rhs) && {
return has_value() ? std::move(*
this) : rhs; }
1497#ifndef TL_OPTIONAL_NO_CONSTRR
1498 constexpr optional disjunction(
const optional& rhs)
const&& {
return has_value() ? std::move(*
this) : rhs; }
1501 TL_OPTIONAL_11_CONSTEXPR
optional disjunction(
optional&& rhs) & {
return has_value() ? *this : std::move(rhs); }
1503 constexpr optional disjunction(
optional&& rhs)
const& {
return has_value() ? *this : std::move(rhs); }
1505 TL_OPTIONAL_11_CONSTEXPR
optional disjunction(
optional&& rhs) && {
return has_value() ? std::move(*
this) : std::move(rhs); }
1507#ifndef TL_OPTIONAL_NO_CONSTRR
1508 constexpr optional disjunction(
optional&& rhs)
const&& {
return has_value() ? std::move(*
this) : std::move(rhs); }
1518 using value_type = T&;
1522 : m_value(
nullptr) {}
1525 : m_value(
nullptr) {}
1540 template <
class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* =
nullptr>
1542 : m_value(std::addressof(u)) {
1543 static_assert(std::is_lvalue_reference<U>::value,
"U must be an lvalue");
1568 template <
class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* =
nullptr>
optional&
operator=(U&& u) {
1569 static_assert(std::is_lvalue_reference<U>::value,
"U must be an lvalue");
1570 m_value = std::addressof(u);
1579 m_value = std::addressof(rhs.value());
1584 template <
class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* =
nullptr>
1586 return *
this = std::forward<U>(u);
1589 void swap(
optional& rhs)
noexcept { std::swap(m_value, rhs.m_value); }
1592 constexpr const T*
operator->() const noexcept {
return m_value; }
1594 TL_OPTIONAL_11_CONSTEXPR T* operator->() noexcept {
return m_value; }
1597 TL_OPTIONAL_11_CONSTEXPR T&
operator*() noexcept {
return *m_value; }
1599 constexpr const T& operator*() const noexcept {
return *m_value; }
1601 constexpr bool has_value() const noexcept {
return m_value !=
nullptr; }
1603 constexpr explicit operator bool() const noexcept {
return m_value !=
nullptr; }
1611 TL_OPTIONAL_11_CONSTEXPR
const T& value()
const {
1618 template <
class U>
constexpr T
value_or(U&& u)
const&
noexcept {
1619 static_assert(std::is_copy_constructible<T>::value && std::is_convertible<U&&, T>::value,
1620 "T must be copy constructible and convertible from U");
1621 return has_value() ? **this :
static_cast<T
>(std::forward<U>(u));
1625 template <
class U> TL_OPTIONAL_11_CONSTEXPR T
value_or(U&& u) &&
noexcept {
1626 static_assert(std::is_move_constructible<T>::value && std::is_convertible<U&&, T>::value,
1627 "T must be move constructible and convertible from U");
1628 return has_value() ? **this :
static_cast<T
>(std::forward<U>(u));
1632 void reset() noexcept { m_value =
nullptr; }
1642template <
class T>
struct hash<nonstd::optional<T>> {
1647 return std::hash<nonstd::detail::remove_const_t<T>>()(*o);
Used to represent an optional with no data; essentially a bool.
TL_OPTIONAL_11_CONSTEXPR T & value()
Returns the contained value if there is one, otherwise throws bad_optional_access.
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &
Calls f if the optional is empty.
optional & operator=(nullopt_t) noexcept
TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) &&noexcept
\group value_or
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &
optional & operator=(const optional< U > &rhs) noexcept
optional & operator=(U &&u)
Rebinds this optional to u.
TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &
Returns rhs if *this is empty, otherwise the current value.
TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval< optional && >(), std::declval< F && >())) transform(F &&f) &&
constexpr const T * operator->() const noexcept
Returns a pointer to the stored value.
TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval< optional & >(), std::declval< F && >())) transform(F &&f) &
Carries out some operation on the stored object if there is one.
constexpr optional< typename std::decay< U >::type > conjunction(U &&u) const
Returns u if *this has a value, otherwise an empty optional.
optional & operator=(const optional &rhs)=default
TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs)=default
TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval< optional & >(), std::declval< F && >())) map(F &&f) &
Carries out some operation on the stored object if there is one.
constexpr optional(U &&u) noexcept
Constructs the stored value with u.
TL_OPTIONAL_11_CONSTEXPR T & operator*() noexcept
Returns the stored value.
constexpr T value_or(U &&u) const &noexcept
Returns the stored value if there is one, otherwise returns u.
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &
optional take()
Takes the value out of the optional, leaving it empty.
~optional()=default
No-op.
U map_or(F &&f, U &&u) &
Maps the stored value with f if there is one, otherwise returns u.
optional & emplace(U &&u) noexcept
Rebinds this optional to u.
constexpr optional() noexcept
Constructs an optional that does not contain a value.
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs) noexcept=default
constexpr const T * operator->() const
Returns a pointer to the stored value.
optional(optional< U > &&rhs)
Converting move constructor.
void swap(optional &rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&detail::is_nothrow_swappable< T >::value)
TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs)=default
optional & operator=(const optional< U > &rhs)
constexpr T value_or(U &&u) const &
Returns the stored value if there is one, otherwise returns u.
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
U map_or(F &&f, U &&u) &
Maps the stored value with f if there is one, otherwise returns u.
T & emplace(Args &&... args)
TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval< optional & >(), std::declval< F && >())) map(F &&f) &
Carries out some operation on the stored object if there is one.
constexpr optional() noexcept=default
Constructs an optional that does not contain a value.
optional & operator=(optional< U > &&rhs)
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &
constexpr optional< typename std::decay< U >::type > conjunction(U &&u) const
Returns u if *this has a value, otherwise an empty optional.
TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs)=default
TL_OPTIONAL_11_CONSTEXPR T & value() &
Returns the contained value if there is one, otherwise throws bad_optional_access.
optional & operator=(optional &&rhs)=default
optional & operator=(const optional &rhs)=default
optional & operator=(U &&u)
TL_OPTIONAL_11_CONSTEXPR T & operator*() &
Returns the stored value.
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &
Calls f if the optional is empty.
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &
optional(const optional< U > &rhs)
Converting copy constructor.
TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval< optional & >(), std::declval< F && >())) transform(F &&f) &
Carries out some operation on the stored object if there is one.
optional take()
Takes the value out of the optional, leaving it empty.
~optional()=default
Destroys the stored value if there is one.
TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &
Returns rhs if *this is empty, otherwise the current value.
constexpr optional(U &&u)
Constructs the stored value with u.
constexpr optional(detail::enable_if_t< std::is_constructible< T, Args... >::value, in_place_t >, Args &&... args)
Constructs the stored value in-place using the given arguments.
constexpr bool has_value() const noexcept
Returns whether or not the optional has a value.
optional & operator=(nullopt_t) noexcept
A tag type to tell optional to construct its value in-place.
A tag type to represent an empty optional.