17#ifndef TL_OPTIONAL_HPP
18#define TL_OPTIONAL_HPP
20#define TL_OPTIONAL_VERSION_MAJOR 1
21#define TL_OPTIONAL_VERSION_MINOR 1
22#define TL_OPTIONAL_VERSION_PATCH 0
30#if (defined(_MSC_VER) && _MSC_VER == 1900)
31#define TL_OPTIONAL_MSVC2015
34#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
36#define TL_OPTIONAL_GCC49
39#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \
41#define TL_OPTIONAL_GCC54
44#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \
46#define TL_OPTIONAL_GCC55
49#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
52#define TL_OPTIONAL_NO_CONSTRR
55#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
56 std::has_trivial_copy_constructor<T>::value
57#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
58 std::has_trivial_copy_assign<T>::value
61#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \
62 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
72struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T>
75template<
class T,
class A>
76struct is_trivially_copy_constructible<
std::vector<T, A>>
77 : std::is_trivially_copy_constructible<T>
84#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
85 tl::detail::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) \
89 std::is_trivially_destructible<T>::value
91#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
92 std::is_trivially_copy_constructible<T>::value
93#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
94 std::is_trivially_copy_assignable<T>::value
95#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \
96 std::is_trivially_destructible<T>::value
99#if __cplusplus > 201103L
100#define TL_OPTIONAL_CXX14
104#if (__cplusplus == 201103L || defined(TL_OPTIONAL_MSVC2015) || \
105 defined(TL_OPTIONAL_GCC49))
106#define TL_OPTIONAL_11_CONSTEXPR
108#define TL_OPTIONAL_11_CONSTEXPR constexpr
112#ifndef TL_MONOSTATE_INPLACE_MUTEX
113#define TL_MONOSTATE_INPLACE_MUTEX
131#ifndef TL_TRAITS_MUTEX
132#define TL_TRAITS_MUTEX
140template<
bool E,
class T =
void>
142template<
bool B,
class T,
class F>
152template<
class B,
class...
Bs>
154 : std::conditional<bool(B::value), conjunction<Bs...>, B>::type
157#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
158#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
164#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
168template<
class T,
class Ret,
class...
Args>
171template<
class T,
class Ret,
class... Args>
172struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)&>
175template<
class T,
class Ret,
class... Args>
176struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&>
179template<
class T,
class Ret,
class... Args>
180struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile>
183template<
class T,
class Ret,
class... Args>
184struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&>
187template<
class T,
class Ret,
class... Args>
188struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&&>
193struct is_const_or_const_ref : std::false_type
196struct is_const_or_const_ref<T const&> : std::true_type
199struct is_const_or_const_ref<T const> : std::true_type
208#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
209 typename =
enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value &&
210 is_const_or_const_ref<Args...>::value)>,
212 typename =
enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
216 noexcept(std::mem_fn(
f)(std::forward<Args>(
args)...)))
217 ->
decltype(std::mem_fn(
f)(std::forward<Args>(
args)...))
219 return std::mem_fn(
f)(std::forward<Args>(
args)...);
227 noexcept(std::forward<Fn>(
f)(std::forward<Args>(
args)...)))
228 ->
decltype(std::forward<Fn>(
f)(std::forward<Args>(
args)...))
230 return std::forward<Fn>(
f)(std::forward<Args>(
args)...);
234template<
class F,
class,
class...
Us>
237template<
class F,
class...
Us>
240 decltype(detail::
invoke(std::declval<F>(), std::declval<Us>()...), void()),
244 decltype(
detail::invoke(std::declval<F>(), std::declval<Us>()...));
247template<
class F,
class...
Us>
250template<
class F,
class...
Us>
253#if defined(_MSC_VER) && _MSC_VER <= 1900
255template<
class T,
class U = T>
259template<
class T,
class U = T>
260struct is_nothrow_swappable : std::true_type
264namespace swap_adl_tests {
273template<
class T, std::
size_t N>
278template<
class,
class>
296 :
std::integral_constant<
bool,
301template<
class T, std::
size_t N>
305template<
class T,
class U>
307 : std::integral_constant<bool, noexcept(can_swap<T, U>(0))>
311template<
class T,
class U = T>
313 : std::integral_constant<
315 decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
316 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
317 (std::is_move_assignable<T>::value &&
318 std::is_move_constructible<T>::value))>
321template<
class T, std::
size_t N>
323 : std::integral_constant<
325 decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
326 (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value ||
327 is_swappable<T, T>::value)>
330template<
class T,
class U = T>
332 : std::integral_constant<
334 is_swappable<T, U>::value &&
335 ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
336 detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
337 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
338 detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))>
366template<
class F,
class U,
class = invoke_result_t<F, U>>
370template<
class F,
class = void,
class...
U>
372template<
class F,
class...
U>
374 : std::is_void<invoke_result_t<F, U...>>
376template<
class F,
class...
U>
379template<
class T,
class...
U>
382template<
class T,
class...
U>
385template<
class T,
class U>
388 !std::is_same<detail::decay_t<U>,
in_place_t>::value &&
391template<
class T,
class U,
class Other>
394 !std::is_constructible<T, optional<U>&>::value &&
395 !std::is_constructible<T, optional<U>&&>::value &&
396 !std::is_constructible<T, const optional<U>&>::value &&
397 !std::is_constructible<T, const optional<U>&&>::value &&
398 !std::is_convertible<optional<U>&, T>::value &&
399 !std::is_convertible<optional<U>&&, T>::value &&
400 !std::is_convertible<const optional<U>&, T>::value &&
401 !std::is_convertible<const optional<U>&&, T>::value>;
403template<
class T,
class U>
407 std::is_same<T, detail::decay_t<U>>>::value &&
408 std::is_constructible<T, U>::value && std::is_assignable<T&, U>::value>;
410template<
class T,
class U,
class Other>
413 std::is_assignable<T&, Other>::value &&
414 !std::is_constructible<T, optional<U>&>::value &&
415 !std::is_constructible<T, optional<U>&&>::value &&
416 !std::is_constructible<T, const optional<U>&>::value &&
417 !std::is_constructible<T, const optional<U>&&>::value &&
418 !std::is_convertible<optional<U>&, T>::value &&
419 !std::is_convertible<optional<U>&&, T>::value &&
420 !std::is_convertible<const optional<U>&, T>::value &&
421 !std::is_convertible<const optional<U>&&, T>::value &&
422 !std::is_assignable<T&, optional<U>&>::value &&
423 !std::is_assignable<T&, optional<U>&&>::value &&
424 !std::is_assignable<T&, const optional<U>&>::value &&
425 !std::is_assignable<T&, const optional<U>&&>::value>;
508 template<
class...
Args>
511 new (std::addressof(this->
m_value)) T(std::forward<Args>(
args)...);
519 if (rhs.has_value()) {
520 this->
m_value = std::forward<Opt>(rhs).get();
527 else if (rhs.has_value()) {
537#ifndef TL_OPTIONAL_NO_CONSTRR
544template<
class T,
bool = TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
577#ifndef TL_OPTIONAL_GCC49
584template<
class T,
bool = false>
596 std::is_nothrow_move_constructible<T>::value)
598 if (rhs.has_value()) {
641#ifndef TL_OPTIONAL_GCC49
643 bool = std::is_trivially_destructible<T>::value &&
644 std::is_trivially_move_constructible<T>::value &&
645 std::is_trivially_move_assignable<T>::value>
651template<
class T,
bool = false>
670 std::is_nothrow_move_constructible<T>::value &&
671 std::is_nothrow_move_assignable<T>::value)
673 this->
assign(std::move(rhs));
681 bool EnableCopy = std::is_copy_constructible<T>::value,
682 bool EnableMove = std::is_move_constructible<T>::value>
818 static_assert(!std::is_same<T, in_place_t>::value,
819 "instantiation of optional with in_place_t is ill-formed");
820 static_assert(!std::is_same<detail::decay_t<T>,
nullopt_t>::value,
821 "instantiation of optional with nullopt_t is ill-formed");
828#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
829 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
837 "F must return an optional");
839 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
848 "F must return an optional");
850 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
855 constexpr auto and_then(
F&&
f)
const&
859 "F must return an optional");
861 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
865#ifndef TL_OPTIONAL_NO_CONSTRR
867 constexpr auto and_then(
F&&
f)
const&&
871 "F must return an optional");
873 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
885 "F must return an optional");
887 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
896 "F must return an optional");
898 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
907 "F must return an optional");
909 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
913#ifndef TL_OPTIONAL_NO_CONSTRR
919 "F must return an optional");
921 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
927#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
928 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
933 return optional_map_impl(*
this, std::forward<F>(
f));
939 return optional_map_impl(std::move(*
this), std::forward<F>(f));
943 constexpr auto map(F&& f)
const&
949 constexpr auto map(F&& f)
const&&
957 std::declval<F&&>()))
960 return optional_map_impl(*
this, std::forward<F>(
f));
965 std::declval<optional&&>(),
966 std::declval<F&&>()))
969 return optional_map_impl(std::move(*
this), std::forward<F>(
f));
973 constexpr decltype(optional_map_impl(std::declval<const optional&>(),
974 std::declval<F&&>()))
977 return optional_map_impl(*
this, std::forward<F>(
f));
980#ifndef TL_OPTIONAL_NO_CONSTRR
982 constexpr decltype(optional_map_impl(std::declval<const optional&&>(),
983 std::declval<F&&>()))
986 return optional_map_impl(std::move(*
this), std::forward<F>(
f));
991#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
992 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
997 return optional_map_impl(*
this, std::forward<F>(
f));
1003 return optional_map_impl(std::move(*
this), std::forward<F>(f));
1007 constexpr auto transform(F&& f)
const&
1013 constexpr auto transform(F&& f)
const&&
1021 std::declval<F&&>()))
1024 return optional_map_impl(*
this, std::forward<F>(
f));
1029 std::declval<optional&&>(),
1030 std::declval<F&&>()))
1033 return optional_map_impl(std::move(*
this), std::forward<F>(
f));
1037 constexpr decltype(optional_map_impl(std::declval<const optional&>(),
1038 std::declval<F&&>()))
1041 return optional_map_impl(*
this, std::forward<F>(
f));
1044#ifndef TL_OPTIONAL_NO_CONSTRR
1046 constexpr decltype(optional_map_impl(std::declval<const optional&&>(),
1047 std::declval<F&&>()))
1050 return optional_map_impl(std::move(*
this), std::forward<F>(
f));
1056 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
1062 std::forward<F>(
f)();
1066 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
1069 return has_value() ? *
this : std::forward<F>(
f)();
1072 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
1076 return std::move(*
this);
1078 std::forward<F>(
f)();
1082 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
1085 return has_value() ? std::move(*
this) : std::forward<F>(
f)();
1088 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
1094 std::forward<F>(
f)();
1098 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
1101 return has_value() ? *
this : std::forward<F>(
f)();
1104#ifndef TL_OPTIONAL_NO_CONSTRR
1105 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
1109 return std::move(*
this);
1111 std::forward<F>(
f)();
1115 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
1118 return has_value() ? std::move(*
this) : std::forward<F>(
f)();
1123 template<
class F,
class U>
1126 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
1127 : std::forward<U>(u);
1130 template<
class F,
class U>
1133 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
1134 : std::forward<U>(u);
1137 template<
class F,
class U>
1140 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
1141 : std::forward<U>(u);
1144#ifndef TL_OPTIONAL_NO_CONSTRR
1145 template<
class F,
class U>
1148 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
1149 : std::forward<U>(u);
1155 template<
class F,
class U>
1158 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
1159 : std::forward<U>(u)();
1162 template<
class F,
class U>
1165 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
1166 : std::forward<U>(u)();
1169 template<
class F,
class U>
1172 return has_value() ? detail::invoke(std::forward<F>(
f), **
this)
1173 : std::forward<U>(u)();
1176#ifndef TL_OPTIONAL_NO_CONSTRR
1177 template<
class F,
class U>
1180 return has_value() ? detail::invoke(std::forward<F>(
f), std::move(**
this))
1181 : std::forward<U>(u)();
1196 return has_value() ? *
this : rhs;
1201 return has_value() ? *
this : rhs;
1206 return has_value() ? std::move(*
this) : rhs;
1209#ifndef TL_OPTIONAL_NO_CONSTRR
1212 return has_value() ? std::move(*
this) : rhs;
1218 return has_value() ? *
this : std::move(rhs);
1223 return has_value() ? *
this : std::move(rhs);
1228 return has_value() ? std::move(*
this) : std::move(rhs);
1231#ifndef TL_OPTIONAL_NO_CONSTRR
1234 return has_value() ? std::move(*
this) : std::move(rhs);
1266 template<
class...
Args>
1274 template<
class U,
class...
Args>
1277 std::is_constructible<T, std::initializer_list<U>&,
Args&&...>::value,
1279 std::initializer_list<U>
il,
1282 this->construct(
il, std::forward<Args>(
args)...);
1286 template<
class U = T,
1294 template<
class U = T,
1310 this->construct(*rhs);
1321 this->construct(*rhs);
1331 if (rhs.has_value()) {
1332 this->construct(std::move(*rhs));
1341 if (rhs.has_value()) {
1342 this->construct(std::move(*rhs));
1356 this->m_has_value =
false;
1376 template<
class U = T, detail::enable_assign_forward<T, U>* =
nullptr>
1380 this->m_value = std::forward<U>(u);
1382 this->construct(std::forward<U>(u));
1392 template<
class U, detail::enable_assign_from_other<T, U, const U&>* =
nullptr>
1397 this->m_value = *rhs;
1404 this->construct(*rhs);
1415 template<
class U, detail::enable_assign_from_other<T, U, U>* =
nullptr>
1419 if (rhs.has_value()) {
1420 this->m_value = std::move(*rhs);
1426 else if (rhs.has_value()) {
1427 this->construct(std::move(*rhs));
1435 template<
class...
Args>
1438 static_assert(std::is_constructible<T,
Args&&...>::value,
1439 "T must be constructible with Args");
1442 this->construct(std::forward<Args>(
args)...);
1446 template<
class U,
class...
Args>
1448 std::is_constructible<T, std::initializer_list<U>&,
Args&&...>::value,
1453 this->construct(
il, std::forward<Args>(
args)...);
1464 std::is_nothrow_move_constructible<T>::value &&
1469 if (rhs.has_value()) {
1472 new (std::addressof(rhs.m_value)) T(std::move(this->m_value));
1473 this->m_value.T::~T();
1475 }
else if (rhs.has_value()) {
1476 new (std::addressof(this->m_value)) T(std::move(rhs.m_value));
1477 rhs.m_value.T::~T();
1479 swap(this->m_has_value, rhs.m_has_value);
1485 return std::addressof(this->m_value);
1490 return std::addressof(this->m_value);
1500 return std::move(this->m_value);
1503#ifndef TL_OPTIONAL_NO_CONSTRR
1512 return this->m_has_value;
1520 return this->m_value;
1526 return this->m_value;
1532 return std::move(this->m_value);
1536#ifndef TL_OPTIONAL_NO_CONSTRR
1540 return std::move(this->m_value);
1549 static_assert(std::is_copy_constructible<T>::value &&
1550 std::is_convertible<U&&, T>::value,
1551 "T must be copy constructible and convertible from U");
1552 return has_value() ? **
this :
static_cast<T
>(std::forward<U>(u));
1558 static_assert(std::is_move_constructible<T>::value &&
1559 std::is_convertible<U&&, T>::value,
1560 "T must be move constructible and convertible from U");
1561 return has_value() ? std::move(**
this) :
static_cast<T
>(std::forward<U>(u));
1569 this->m_has_value =
false;
1575template<
class T,
class U>
1576inline constexpr bool
1582template<
class T,
class U>
1583inline constexpr bool
1589template<
class T,
class U>
1590inline constexpr bool
1595template<
class T,
class U>
1596inline constexpr bool
1601template<
class T,
class U>
1602inline constexpr bool
1607template<
class T,
class U>
1608inline constexpr bool
1616inline constexpr bool
1622inline constexpr bool
1628inline constexpr bool
1634inline constexpr bool
1640inline constexpr bool
1646inline constexpr bool
1652inline constexpr bool
1658inline constexpr bool
1664inline constexpr bool
1670inline constexpr bool
1676inline constexpr bool
1682inline constexpr bool
1689template<
class T,
class U>
1690inline constexpr bool
1695template<
class T,
class U>
1696inline constexpr bool
1701template<
class T,
class U>
1702inline constexpr bool
1707template<
class T,
class U>
1708inline constexpr bool
1713template<
class T,
class U>
1714inline constexpr bool
1719template<
class T,
class U>
1720inline constexpr bool
1725template<
class T,
class U>
1726inline constexpr bool
1731template<
class T,
class U>
1732inline constexpr bool
1737template<
class T,
class U>
1738inline constexpr bool
1743template<
class T,
class U>
1744inline constexpr bool
1749template<
class T,
class U>
1750inline constexpr bool
1755template<
class T,
class U>
1756inline constexpr bool
1763 detail::enable_if_t<std::is_move_constructible<T>::value>* =
nullptr,
1764 detail::enable_if_t<detail::is_swappable<T>::value>* =
nullptr>
1788template<
class T,
class... Args>
1789inline constexpr optional<T>
1794template<
class T,
class U,
class... Args>
1795inline constexpr optional<T>
1801#if __cplusplus >= 201703L
1803optional(T) -> optional<T>;
1808#ifdef TL_OPTIONAL_CXX14
1811 class Ret =
decltype(detail::invoke(std::declval<F>(),
1812 *std::declval<Opt>())),
1813 detail::enable_if_t<!std::is_void<Ret>::value>* =
nullptr>
1815optional_map_impl(Opt&& opt, F&& f)
1818 ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
1819 : optional<Ret>(nullopt);
1824 class Ret =
decltype(detail::invoke(std::declval<F>(),
1825 *std::declval<Opt>())),
1826 detail::enable_if_t<std::is_void<Ret>::value>* =
nullptr>
1830 if (opt.has_value()) {
1831 detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
1835 return optional<monostate>(nullopt);
1840 class Ret =
decltype(detail::invoke(std::declval<F>(),
1841 *std::declval<Opt>())),
1842 detail::enable_if_t<!std::is_void<Ret>::value>* =
nullptr>
1848 ? detail::invoke(std::forward<F>(
f), *std::forward<Opt>(
opt))
1854 class Ret =
decltype(detail::invoke(std::declval<F>(),
1855 *std::declval<Opt>())),
1862 detail::invoke(std::forward<F>(
f), *std::forward<Opt>(
opt));
1881#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
1882 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
1891 "F must return an optional");
1902 "F must return an optional");
1909 constexpr auto and_then(
F&&
f)
const&
1913 "F must return an optional");
1919#ifndef TL_OPTIONAL_NO_CONSTRR
1921 constexpr auto and_then(
F&&
f)
const&&
1925 "F must return an optional");
1939 "F must return an optional");
1950 "F must return an optional");
1961 "F must return an optional");
1967#ifndef TL_OPTIONAL_NO_CONSTRR
1973 "F must return an optional");
1975 return has_value() ?
detail::invoke(std::forward<F>(
f), std::move(**
this))
1981#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
1982 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
1997 constexpr auto map(F&& f)
const&
2003 constexpr auto map(F&& f)
const&&
2011 std::declval<optional&>(),
2012 std::declval<F&&>()))
2020 std::declval<optional&&>(),
2021 std::declval<F&&>()))
2029 std::declval<F&&>()))
2035#ifndef TL_OPTIONAL_NO_CONSTRR
2038 std::declval<F&&>()))
2046#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
2047 !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
2062 constexpr auto transform(F&& f)
const&
2068 constexpr auto transform(F&& f)
const&&
2076 std::declval<optional&>(),
2077 std::declval<F&&>()))
2087 std::declval<optional&&>(),
2088 std::declval<F&&>()))
2096 std::declval<F&&>()))
2102#ifndef TL_OPTIONAL_NO_CONSTRR
2105 std::declval<F&&>()))
2114 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
2120 std::forward<F>(
f)();
2124 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
2127 return has_value() ? *
this : std::forward<F>(
f)();
2130 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
2134 return std::move(*
this);
2136 std::forward<F>(
f)();
2140 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
2143 return has_value() ? std::move(*
this) : std::forward<F>(
f)();
2146 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
2152 std::forward<F>(
f)();
2156 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
2159 return has_value() ? *
this : std::forward<F>(
f)();
2162#ifndef TL_OPTIONAL_NO_CONSTRR
2163 template<
class F, detail::enable_if_ret_
void<F>* =
nullptr>
2167 return std::move(*
this);
2169 std::forward<F>(
f)();
2173 template<
class F, detail::disable_if_ret_
void<F>* =
nullptr>
2176 return has_value() ? std::move(*
this) : std::forward<F>(
f)();
2181 template<
class F,
class U>
2185 : std::forward<U>(u);
2188 template<
class F,
class U>
2191 return has_value() ?
detail::invoke(std::forward<F>(
f), std::move(**
this))
2192 : std::forward<U>(u);
2195 template<
class F,
class U>
2199 : std::forward<U>(u);
2202#ifndef TL_OPTIONAL_NO_CONSTRR
2203 template<
class F,
class U>
2206 return has_value() ?
detail::invoke(std::forward<F>(
f), std::move(**
this))
2207 : std::forward<U>(u);
2213 template<
class F,
class U>
2217 : std::forward<U>(u)();
2220 template<
class F,
class U>
2223 return has_value() ?
detail::invoke(std::forward<F>(
f), std::move(**
this))
2224 : std::forward<U>(u)();
2227 template<
class F,
class U>
2231 : std::forward<U>(u)();
2234#ifndef TL_OPTIONAL_NO_CONSTRR
2235 template<
class F,
class U>
2238 return has_value() ?
detail::invoke(std::forward<F>(
f), std::move(**
this))
2239 : std::forward<U>(u)();
2254 return has_value() ? *
this : rhs;
2259 return has_value() ? *
this : rhs;
2264 return has_value() ? std::move(*
this) : rhs;
2267#ifndef TL_OPTIONAL_NO_CONSTRR
2270 return has_value() ? std::move(*
this) : rhs;
2276 return has_value() ? *
this : std::move(rhs);
2281 return has_value() ? *
this : std::move(rhs);
2286 return has_value() ? std::move(*
this) : std::move(rhs);
2289#ifndef TL_OPTIONAL_NO_CONSTRR
2292 return has_value() ? std::move(*
this) : std::move(rhs);
2330 template<
class U = T,
2334 : m_value(std::addressof(u))
2336 static_assert(std::is_lvalue_reference<U>::value,
"U must be an lvalue");
2364 template<
class U = T,
2369 static_assert(std::is_lvalue_reference<U>::value,
"U must be an lvalue");
2370 m_value = std::addressof(u);
2381 m_value = std::addressof(rhs.value());
2386 template<
class U = T,
2391 return *
this = std::forward<U>(u);
2410 return m_value !=
nullptr;
2432 static_assert(std::is_copy_constructible<T>::value &&
2433 std::is_convertible<U&&, T>::value,
2434 "T must be copy constructible and convertible from U");
2435 return has_value() ? **
this :
static_cast<T
>(std::forward<U>(u));
2442 static_assert(std::is_move_constructible<T>::value &&
2443 std::is_convertible<U&&, T>::value,
2444 "T must be move constructible and convertible from U");
2445 return has_value() ? **
this :
static_cast<T
>(std::forward<U>(u));
2460struct hash<
tl::optional<T>>
2467 return std::hash<tl::detail::remove_const_t<T>>()(*o);
bad_optional_access()=default
const char * what() const noexcept
Used to represent an optional with no data; essentially a bool.
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &&
constexpr optional(const optional< U > &rhs) noexcept
U map_or(F &&f, U &&u) const &
constexpr optional() noexcept
Constructs an optional that does not contain a value.
TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval< optional && >(), std::declval< F && >())) map(F &&f) &&
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &&
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &
~optional()=default
No-op.
constexpr optional disjunction(const optional &rhs) const &&
constexpr decltype(detail::optional_map_impl(std::declval< const optional && >(), std::declval< F && >())) transform(F &&f) const &&
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &
Calls f if the optional is empty.
constexpr optional(nullopt_t) noexcept
constexpr decltype(detail::optional_map_impl(std::declval< const optional && >(), std::declval< F && >())) map(F &&f) const &&
constexpr decltype(detail::optional_map_impl(std::declval< const optional & >(), std::declval< F && >())) transform(F &&f) const &
TL_OPTIONAL_11_CONSTEXPR T & operator*() noexcept
Returns the stored value.
optional & operator=(const optional &rhs)=default
TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) &&noexcept
\group value_or
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &
TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs) noexcept=default
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 disjunction(optional &&rhs) const &
TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &&
U map_or(F &&f, U &&u) const &&
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 T * operator->() noexcept
optional< T > or_else(F &&f) const &
TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs)=default
optional & operator=(const optional< U > &rhs) noexcept
optional & operator=(nullopt_t) noexcept
constexpr decltype(detail::optional_map_impl(std::declval< const optional & >(), std::declval< F && >())) map(F &&f) const &
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const &
optional< T > or_else(F &&f) &&
TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval< optional && >(), std::declval< F && >())) transform(F &&f) &&
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
optional & operator=(U &&u)
Rebinds this optional to u.
TL_OPTIONAL_11_CONSTEXPR T & value()
TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &&
U map_or(F &&f, U &&u) &&
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &
TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &&
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 const T & value() const
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &
TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &
Returns rhs if *this is empty, otherwise the current value.
constexpr optional disjunction(optional &&rhs) const &&
constexpr bool has_value() const noexcept
constexpr T value_or(U &&u) const &noexcept
Returns the stored value if there is one, otherwise returns u
optional take()
Takes the value out of the optional, leaving it empty.
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &&
U map_or(F &&f, U &&u) &
Maps the stored value with f if there is one, otherwise returns u
constexpr const T * operator->() const noexcept
Returns a pointer to the stored value.
constexpr const T & operator*() const noexcept
optional & emplace(U &&u) noexcept
Rebinds this optional to u.
void swap(optional &rhs) noexcept
constexpr optional disjunction(const optional &rhs) const &
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &&
optional< T > or_else(F &&f) const &&
constexpr optional() noexcept=default
Constructs an optional that does not contain a value.
constexpr optional disjunction(const optional &rhs) const &
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &&
constexpr decltype(optional_map_impl(std::declval< const optional & >(), std::declval< F && >())) map(F &&f) const &
TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &&
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &
TL_OPTIONAL_11_CONSTEXPR T && value() &&
TL_OPTIONAL_11_CONSTEXPR T & operator*() &
Returns the stored value.
TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs)=default
constexpr decltype(optional_map_impl(std::declval< const optional && >(), std::declval< F && >())) map(F &&f) const &&
TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &
Returns rhs if *this is empty, otherwise the current value.
T & emplace(Args &&... args)
TL_OPTIONAL_11_CONSTEXPR const T && value() const &&
optional & operator=(optional &&rhs)=default
U map_or(F &&f, U &&u) const &
TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval< optional && >(), std::declval< F && >())) map(F &&f) &&
TL_OPTIONAL_11_CONSTEXPR T & value() &
optional(const optional< U > &rhs)
Converting copy constructor.
constexpr optional disjunction(optional &&rhs) const &
constexpr bool has_value() const noexcept
Returns whether or not the optional has a value.
TL_OPTIONAL_11_CONSTEXPR T * operator->()
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.
optional & operator=(U &&u)
optional< T > or_else(F &&f) const &&
TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval< optional && >(), std::declval< F && >())) transform(F &&f) &&
constexpr const T * operator->() const
Returns a pointer to the stored value.
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.
TL_OPTIONAL_11_CONSTEXPR 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)
constexpr decltype(optional_map_impl(std::declval< const optional & >(), std::declval< F && >())) transform(F &&f) const &
TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs)=default
U map_or(F &&f, U &&u) const &&
void swap(optional &rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&detail::is_nothrow_swappable< T >::value)
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &
U map_or(F &&f, U &&u) &&
TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) &&
TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &
~optional()=default
Destroys the stored value if there is one.
constexpr detail::invoke_result_t< F, const T && > and_then(F &&f) const &&
optional< T > or_else(F &&f) const &
detail::enable_if_t< std::is_constructible< T, std::initializer_list< U > &, Args &&... >::value, T & > emplace(std::initializer_list< U > il, Args &&... args)
constexpr const T & operator*() const &
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T && > and_then(F &&f) &&
TL_OPTIONAL_11_CONSTEXPR const T & value() const &
constexpr optional disjunction(optional &&rhs) const &&
constexpr T value_or(U &&u) const &
Returns the stored value if there is one, otherwise returns u
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &
optional take()
Takes the value out of the optional, leaving it empty.
optional & operator=(optional< U > &&rhs)
constexpr optional(U &&u)
Constructs the stored value with u.
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< U > &rhs)
TL_OPTIONAL_11_CONSTEXPR T && operator*() &&
optional(optional< U > &&rhs)
Converting move constructor.
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
constexpr const T && operator*() const &&
constexpr optional disjunction(const optional &rhs) const &&
U map_or(F &&f, U &&u) &
Maps the stored value with f if there is one, otherwise returns u.
optional & operator=(const optional &rhs)=default
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.
optional & operator=(nullopt_t) noexcept
optional< T > or_else(F &&f) &&
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &&
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &&
TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &&
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &
Calls f if the optional is empty.
constexpr decltype(optional_map_impl(std::declval< const optional && >(), std::declval< F && >())) transform(F &&f) const &&
optional< T > TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const &
std::false_type uses_std(...)
std::false_type can_swap(...) noexcept(false)
detail::enable_if_t< std::is_constructible< T, Other >::value && std::is_assignable< T &, Other >::value && !std::is_constructible< T, optional< U > & >::value && !std::is_constructible< T, optional< U > && >::value && !std::is_constructible< T, const optional< U > & >::value && !std::is_constructible< T, const optional< U > && >::value && !std::is_convertible< optional< U > &, T >::value && !std::is_convertible< optional< U > &&, T >::value && !std::is_convertible< const optional< U > &, T >::value && !std::is_convertible< const optional< U > &&, T >::value && !std::is_assignable< T &, optional< U > & >::value && !std::is_assignable< T &, optional< U > && >::value && !std::is_assignable< T &, const optional< U > & >::value && !std::is_assignable< T &, const optional< U > && >::value > enable_assign_from_other
typename std::remove_reference< T >::type remove_reference_t
detail::enable_if_t< !std::is_same< optional< T >, detail::decay_t< U > >::value && !detail::conjunction< std::is_scalar< T >, std::is_same< T, detail::decay_t< U > > >::value && std::is_constructible< T, U >::value &&std::is_assignable< T &, U >::value > enable_assign_forward
typename std::enable_if< E, T >::type enable_if_t
typename std::decay< T >::type decay_t
detail::enable_if_t< std::is_constructible< T, U && >::value && !std::is_same< detail::decay_t< U >, in_place_t >::value && !std::is_same< optional< T >, detail::decay_t< U > >::value > enable_forward_value
typename std::remove_const< T >::type remove_const_t
constexpr auto invoke(Fn &&f, Args &&... args) noexcept(noexcept(std::mem_fn(f)(std::forward< Args >(args)...))) -> decltype(std::mem_fn(f)(std::forward< Args >(args)...))
constexpr auto optional_map_impl(Opt &&opt, F &&f) -> optional< Ret >
typename std::conditional< B, T, F >::type conditional_t
typename voider< Ts... >::type void_t
typename invoke_result< F, Us... >::type invoke_result_t
detail::enable_if_t< std::is_constructible< T, Other >::value && !std::is_constructible< T, optional< U > & >::value && !std::is_constructible< T, optional< U > && >::value && !std::is_constructible< T, const optional< U > & >::value && !std::is_constructible< T, const optional< U > && >::value && !std::is_convertible< optional< U > &, T >::value && !std::is_convertible< optional< U > &&, T >::value && !std::is_convertible< const optional< U > &, T >::value && !std::is_convertible< const optional< U > &&, T >::value > enable_from_other
constexpr bool operator==(const optional< T > &lhs, const optional< U > &rhs)
Compares two optional objects.
static constexpr nullopt_t nullopt
Represents an empty optional.
constexpr bool operator!=(const optional< T > &lhs, const optional< U > &rhs)
constexpr bool operator>=(const optional< T > &lhs, const optional< U > &rhs)
constexpr bool operator<(const optional< T > &lhs, const optional< U > &rhs)
static constexpr in_place_t in_place
A tag to tell optional to construct its value in-place.
constexpr optional< Ret > make_optional(U &&v)
constexpr bool operator>(const optional< T > &lhs, const optional< U > &rhs)
constexpr bool operator<=(const optional< T > &lhs, const optional< U > &rhs)
void swap(optional< T > &lhs, optional< T > &rhs) noexcept(noexcept(lhs.swap(rhs)))
::std::size_t operator()(const tl::optional< T > &o) const
decltype(detail::invoke(std::declval< F >(), std::declval< Us >()...)) type
optional_copy_assign_base(const optional_copy_assign_base &rhs)=default
optional_copy_assign_base & operator=(const optional_copy_assign_base &rhs)
optional_copy_assign_base()=default
optional_copy_assign_base & operator=(optional_copy_assign_base &&rhs)=default
optional_copy_assign_base(optional_copy_assign_base &&rhs)=default
optional_copy_base()=default
optional_copy_base & operator=(const optional_copy_base &rhs)=default
optional_copy_base(const optional_copy_base &rhs)
optional_copy_base & operator=(optional_copy_base &&rhs)=default
optional_copy_base(optional_copy_base &&rhs)=default
optional_delete_assign_base(const optional_delete_assign_base &)=default
optional_delete_assign_base()=default
optional_delete_assign_base(optional_delete_assign_base &&) noexcept=default
optional_delete_assign_base(optional_delete_assign_base &&) noexcept=default
optional_delete_assign_base()=default
optional_delete_assign_base(const optional_delete_assign_base &)=default
optional_delete_assign_base()=default
optional_delete_assign_base(const optional_delete_assign_base &)=default
optional_delete_assign_base(optional_delete_assign_base &&) noexcept=default
optional_delete_assign_base(optional_delete_assign_base &&) noexcept=default
optional_delete_assign_base()=default
optional_delete_assign_base(const optional_delete_assign_base &)=default
optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept=delete
optional_delete_ctor_base(const optional_delete_ctor_base &)=delete
optional_delete_ctor_base()=default
optional_delete_ctor_base(const optional_delete_ctor_base &)=delete
optional_delete_ctor_base()=default
optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept=default
optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept=delete
optional_delete_ctor_base()=default
optional_delete_ctor_base(const optional_delete_ctor_base &)=default
optional_delete_ctor_base(const optional_delete_ctor_base &)=default
optional_delete_ctor_base()=default
optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept=default
optional_move_assign_base & operator=(optional_move_assign_base &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&std::is_nothrow_move_assignable< T >::value)
optional_move_assign_base(const optional_move_assign_base &rhs)=default
optional_move_assign_base & operator=(const optional_move_assign_base &rhs)=default
optional_move_assign_base(optional_move_assign_base &&rhs)=default
optional_move_assign_base()=default
optional_move_base & operator=(const optional_move_base &rhs)=default
optional_move_base(const optional_move_base &rhs)=default
optional_move_base(optional_move_base &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value)
optional_move_base & operator=(optional_move_base &&rhs)=default
optional_move_base()=default
constexpr const T && get() const &&
TL_OPTIONAL_11_CONSTEXPR T && get() &&
void construct(Args &&... args)
TL_OPTIONAL_11_CONSTEXPR T & get() &
TL_OPTIONAL_11_CONSTEXPR const T & get() const &
void hard_reset() noexcept
TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
A tag type to tell optional to construct its value in-place.
A tag type to represent an empty optional.
constexpr nullopt_t(do_not_use, do_not_use) noexcept
#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T)
#define TL_OPTIONAL_11_CONSTEXPR
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)