diff --git a/misc/style/run-clang-tidy.py b/misc/style/run-clang-tidy.py
index 9218e65289..90ad7a31d4 100755
--- a/misc/style/run-clang-tidy.py
+++ b/misc/style/run-clang-tidy.py
@@ -29,7 +29,7 @@ def check_search_code_with_clang_tidy():
src_files = utils.get_src_files(search_dir, (".h", ".cc"))
compile_commands = [{
"directory": os.path.join(build_dir, "search"),
- "command": "g++ -I{}/ext -std=c++11 -c {}".format(search_dir, src_file),
+ "command": "g++ -std=c++20 -c {}".format(src_file),
"file": src_file}
for src_file in src_files
]
@@ -82,8 +82,6 @@ def check_search_code_with_clang_tidy():
"-quiet",
"-p", build_dir,
"-clang-tidy-binary=clang-tidy-12",
- # Include all non-system headers (.*) except the ones from search/ext/.
- "-header-filter=.*,-tree.hh,-tree_util.hh",
"-checks=-*," + ",".join(checks)]
print("Running clang-tidy: " + " ".join(pipes.quote(x) for x in cmd))
print()
diff --git a/src/search/CMakeLists.txt b/src/search/CMakeLists.txt
index 7de536ebf9..79579c2480 100644
--- a/src/search/CMakeLists.txt
+++ b/src/search/CMakeLists.txt
@@ -29,10 +29,6 @@ fast_downward_set_linker_flags()
include("${CMAKE_CURRENT_SOURCE_DIR}/DownwardFiles.cmake")
add_executable(downward ${PLANNER_SOURCES})
-## == Includes ==
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ext)
-
## == Libraries ==
# On Linux, find the rt library for clock_gettime().
diff --git a/src/search/ext/optional.hh b/src/search/ext/optional.hh
deleted file mode 100644
index 15302fb444..0000000000
--- a/src/search/ext/optional.hh
+++ /dev/null
@@ -1,2359 +0,0 @@
-//
-// optional - An implementation of std::optional with extensions
-// Written in 2017 by Simon Brand (tartanllama@gmail.com, @TartanLlama)
-//
-// To the extent possible under law, the author(s) have dedicated all
-// copyright and related and neighboring rights to this software to the
-// public domain worldwide. This software is distributed without any warranty.
-//
-// You should have received a copy of the CC0 Public Domain Dedication
-// along with this software. If not, see
-// .
-///
-
-#ifndef TL_OPTIONAL_HPP
-#define TL_OPTIONAL_HPP
-
-#define TL_OPTIONAL_VERSION_MAJOR 0
-#define TL_OPTIONAL_VERSION_MINOR 5
-
-#include
-#include
-#include
-#include
-#include
-
-#if (defined(_MSC_VER) && _MSC_VER == 1900)
-#define TL_OPTIONAL_MSVC2015
-#endif
-
-#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
- !defined(__clang__))
-#define TL_OPTIONAL_GCC49
-#endif
-
-#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \
- !defined(__clang__))
-#define TL_OPTIONAL_GCC54
-#endif
-
-#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \
- !defined(__clang__))
-#define TL_OPTIONAL_GCC55
-#endif
-
-#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
- !defined(__clang__))
-// GCC < 5 doesn't support overloading on const&& for member functions
-#define TL_OPTIONAL_NO_CONSTRR
-
-// GCC < 5 doesn't support some standard C++11 type traits
-#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
- std::has_trivial_copy_constructor::value
-#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign::value
-
-// This one will be different for GCC 5.7 if it's ever supported
-#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible::value
-
-// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks std::vector
-// for non-copyable types
-#elif (defined(__GNUC__) && __GNUC__ < 8 && \
- !defined(__clang__))
-#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
-#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
-namespace tl {
- namespace detail {
- template
- struct is_trivially_copy_constructible : std::is_trivially_copy_constructible{};
-#ifdef _GLIBCXX_VECTOR
- template
- struct is_trivially_copy_constructible>
- : std::is_trivially_copy_constructible{};
-#endif
- }
-}
-#endif
-
-#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
- tl::detail::is_trivially_copy_constructible::value
-#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
- std::is_trivially_copy_assignable::value
-#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible::value
-#else
-#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
- std::is_trivially_copy_constructible::value
-#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
- std::is_trivially_copy_assignable::value
-#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible::value
-#endif
-
-#if __cplusplus > 201103L
-#define TL_OPTIONAL_CXX14
-#endif
-
-// constexpr implies const in C++11, not C++14
-#if (__cplusplus == 201103L || defined(TL_OPTIONAL_MSVC2015) || \
- defined(TL_OPTIONAL_GCC49))
-/// \exclude
-#define TL_OPTIONAL_11_CONSTEXPR
-#else
-/// \exclude
-#define TL_OPTIONAL_11_CONSTEXPR constexpr
-#endif
-
-namespace tl {
-#ifndef TL_MONOSTATE_INPLACE_MUTEX
-#define TL_MONOSTATE_INPLACE_MUTEX
-/// \brief Used to represent an optional with no data; essentially a bool
-class monostate {};
-
-/// \brief A tag type to tell optional to construct its value in-place
-struct in_place_t {
- explicit in_place_t() = default;
-};
-/// \brief A tag to tell optional to construct its value in-place
-static constexpr in_place_t in_place{};
-#endif
-
-template class optional;
-
-/// \exclude
-namespace detail {
-#ifndef TL_TRAITS_MUTEX
-#define TL_TRAITS_MUTEX
-// C++14-style aliases for brevity
-template using remove_const_t = typename std::remove_const::type;
-template
-using remove_reference_t = typename std::remove_reference::type;
-template using decay_t = typename std::decay::type;
-template
-using enable_if_t = typename std::enable_if::type;
-template
-using conditional_t = typename std::conditional::type;
-
-// std::conjunction from C++17
-template struct conjunction : std::true_type {};
-template struct conjunction : B {};
-template
-struct conjunction
- : std::conditional, B>::type {};
-
-#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
-#define TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
-#endif
-
-// In C++11 mode, there's an issue in libc++'s std::mem_fn
-// which results in a hard-error when using it in a noexcept expression
-// in some cases. This is a check to workaround the common failing case.
-#ifdef TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
-template struct is_pointer_to_non_const_member_func : std::false_type{};
-template
-struct is_pointer_to_non_const_member_func : std::true_type{};
-template
-struct is_pointer_to_non_const_member_func : std::true_type{};
-template
-struct is_pointer_to_non_const_member_func : std::true_type{};
-template
-struct is_pointer_to_non_const_member_func : std::true_type{};
-template
-struct is_pointer_to_non_const_member_func : std::true_type{};
-template
-struct is_pointer_to_non_const_member_func : std::true_type{};
-
-template struct is_const_or_const_ref : std::false_type{};
-template struct is_const_or_const_ref : std::true_type{};
-template struct is_const_or_const_ref : std::true_type{};
-#endif
-
-// std::invoke from C++17
-// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
-template ::value
- && is_const_or_const_ref::value)>,
-#endif
- typename = enable_if_t>::value>,
- int = 0>
-constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
- noexcept(std::mem_fn(f)(std::forward(args)...)))
- -> decltype(std::mem_fn(f)(std::forward(args)...)) {
- return std::mem_fn(f)(std::forward(args)...);
-}
-
-template >::value>>
-constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
- noexcept(std::forward(f)(std::forward(args)...)))
- -> decltype(std::forward(f)(std::forward(args)...)) {
- return std::forward(f)(std::forward(args)...);
-}
-
-// std::invoke_result from C++17
-template struct invoke_result_impl;
-
-template
-struct invoke_result_impl<
- F, decltype(detail::invoke(std::declval(), std::declval()...), void()),
- Us...> {
- using type = decltype(detail::invoke(std::declval(), std::declval()...));
-};
-
-template
-using invoke_result = invoke_result_impl;
-
-template
-using invoke_result_t = typename invoke_result::type;
-#endif
-
-// std::void_t from C++17
-template struct voider { using type = void; };
-template using void_t = typename voider::type;
-
-// Trait for checking if a type is a tl::optional
-template struct is_optional_impl : std::false_type {};
-template struct is_optional_impl> : std::true_type {};
-template using is_optional = is_optional_impl>;
-
-// Change void to tl::monostate
-template
-using fixup_void = conditional_t::value, monostate, U>;
-
-template >
-using get_map_return = optional>>;
-
-// Check if invoking F for some Us returns void
-template struct returns_void_impl;
-template
-struct returns_void_impl>, U...>
- : std::is_void> {};
-template
-using returns_void = returns_void_impl;
-
-template
-using enable_if_ret_void = enable_if_t::value>;
-
-template
-using disable_if_ret_void = enable_if_t::value>;
-
-template
-using enable_forward_value =
- detail::enable_if_t::value &&
- !std::is_same, in_place_t>::value &&
- !std::is_same, detail::decay_t>::value>;
-
-template
-using enable_from_other = detail::enable_if_t<
- std::is_constructible::value &&
- !std::is_constructible &>::value &&
- !std::is_constructible &&>::value &&
- !std::is_constructible &>::value &&
- !std::is_constructible &&>::value &&
- !std::is_convertible &, T>::value &&
- !std::is_convertible &&, T>::value &&
- !std::is_convertible &, T>::value &&
- !std::is_convertible &&, T>::value>;
-
-template
-using enable_assign_forward = detail::enable_if_t<
- !std::is_same, detail::decay_t>::value &&
- !detail::conjunction,
- std::is_same>>::value &&
- std::is_constructible::value && std::is_assignable::value>;
-
-template
-using enable_assign_from_other = detail::enable_if_t<
- std::is_constructible::value &&
- std::is_assignable::value &&
- !std::is_constructible &>::value &&
- !std::is_constructible &&>::value &&
- !std::is_constructible &>::value &&
- !std::is_constructible &&>::value &&
- !std::is_convertible &, T>::value &&
- !std::is_convertible &&, T>::value &&
- !std::is_convertible &, T>::value &&
- !std::is_convertible &&, T>::value &&
- !std::is_assignable &>::value &&
- !std::is_assignable &&>::value &&
- !std::is_assignable &>::value &&
- !std::is_assignable &&>::value>;
-
-#ifdef _MSC_VER
-// TODO make a version which works with MSVC
-template struct is_swappable : std::true_type {};
-
-template struct is_nothrow_swappable : std::true_type {};
-#else
-// https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
-namespace swap_adl_tests {
-// if swap ADL finds this then it would call std::swap otherwise (same
-// signature)
-struct tag {};
-
-template tag swap(T &, T &);
-template tag swap(T (&a)[N], T (&b)[N]);
-
-// helper functions to test if an unqualified swap is possible, and if it
-// becomes std::swap
-template std::false_type can_swap(...) noexcept(false);
-template (), std::declval()))>
-std::true_type can_swap(int) noexcept(noexcept(swap(std::declval(),
- std::declval())));
-
-template std::false_type uses_std(...);
-template
-std::is_same(), std::declval())), tag>
-uses_std(int);
-
-template
-struct is_std_swap_noexcept
- : std::integral_constant::value &&
- std::is_nothrow_move_assignable::value> {};
-
-template
-struct is_std_swap_noexcept : is_std_swap_noexcept {};
-
-template
-struct is_adl_swap_noexcept
- : std::integral_constant(0))> {};
-} // namespace swap_adl_tests
-
-template
-struct is_swappable
- : std::integral_constant<
- bool,
- decltype(detail::swap_adl_tests::can_swap(0))::value &&
- (!decltype(detail::swap_adl_tests::uses_std(0))::value ||
- (std::is_move_assignable::value &&
- std::is_move_constructible::value))> {};
-
-template
-struct is_swappable
- : std::integral_constant<
- bool,
- decltype(detail::swap_adl_tests::can_swap(0))::value &&
- (!decltype(
- detail::swap_adl_tests::uses_std(0))::value ||
- is_swappable::value)> {};
-
-template
-struct is_nothrow_swappable
- : std::integral_constant<
- bool,
- is_swappable::value &&
- ((decltype(detail::swap_adl_tests::uses_std(0))::value
- &&detail::swap_adl_tests::is_std_swap_noexcept::value) ||
- (!decltype(detail::swap_adl_tests::uses_std(0))::value &&
- detail::swap_adl_tests::is_adl_swap_noexcept::value))> {
-};
-#endif
-
-// The storage base manages the actual storage, and correctly propagates
-// trivial destruction from T. This case is for when T is not trivially
-// destructible.
-template ::value>
-struct optional_storage_base {
- TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
- : m_dummy(), m_has_value(false) {}
-
- template
- TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
- : m_value(std::forward(u)...), m_has_value(true) {}
-
- ~optional_storage_base() {
- if (m_has_value) {
- m_value.~T();
- m_has_value = false;
- }
- }
-
- struct dummy {};
- union {
- dummy m_dummy;
- T m_value;
- };
-
- bool m_has_value;
-};
-
-// This case is for when T is trivially destructible.
-template struct optional_storage_base {
- TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
- : m_dummy(), m_has_value(false) {}
-
- template
- TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
- : m_value(std::forward(u)...), m_has_value(true) {}
-
- // No destructor, so this class is trivially destructible
-
- struct dummy {};
- union {
- dummy m_dummy;
- T m_value;
- };
-
- bool m_has_value = false;
-};
-
-// This base class provides some handy member functions which can be used in
-// further derived classes
-template struct optional_operations_base : optional_storage_base {
- using optional_storage_base::optional_storage_base;
-
- void hard_reset() noexcept {
- get().~T();
- this->m_has_value = false;
- }
-
- template void construct(Args &&... args) noexcept {
- new (std::addressof(this->m_value)) T(std::forward(args)...);
- this->m_has_value = true;
- }
-
- template void assign(Opt &&rhs) {
- if (this->has_value()) {
- if (rhs.has_value()) {
- this->m_value = std::forward(rhs).get();
- } else {
- this->m_value.~T();
- this->m_has_value = false;
- }
- }
-
- else if (rhs.has_value()) {
- construct(std::forward(rhs).get());
- }
- }
-
- bool has_value() const { return this->m_has_value; }
-
- TL_OPTIONAL_11_CONSTEXPR T &get() & { return this->m_value; }
- TL_OPTIONAL_11_CONSTEXPR const T &get() const & { return this->m_value; }
- TL_OPTIONAL_11_CONSTEXPR T &&get() && { return std::move(this->m_value); }
-#ifndef TL_OPTIONAL_NO_CONSTRR
- constexpr const T &&get() const && { return std::move(this->m_value); }
-#endif
-};
-
-// This class manages conditionally having a trivial copy constructor
-// This specialization is for when T is trivially copy constructible
-template
-struct optional_copy_base : optional_operations_base {
- using optional_operations_base::optional_operations_base;
-};
-
-// This specialization is for when T is not trivially copy constructible
-template
-struct optional_copy_base : optional_operations_base {
- using optional_operations_base::optional_operations_base;
-
- optional_copy_base() = default;
- optional_copy_base(const optional_copy_base &rhs) {
- if (rhs.has_value()) {
- this->construct(rhs.get());
- } else {
- this->m_has_value = false;
- }
- }
-
- optional_copy_base(optional_copy_base &&rhs) = default;
- optional_copy_base &operator=(const optional_copy_base &rhs) = default;
- optional_copy_base &operator=(optional_copy_base &&rhs) = default;
-};
-
-// This class manages conditionally having a trivial move constructor
-// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
-// doesn't implement an analogue to std::is_trivially_move_constructible. We
-// have to make do with a non-trivial move constructor even if T is trivially
-// move constructible
-#ifndef TL_OPTIONAL_GCC49
-template ::value>
-struct optional_move_base : optional_copy_base {
- using optional_copy_base::optional_copy_base;
-};
-#else
-template struct optional_move_base;
-#endif
-template struct optional_move_base : optional_copy_base {
- using optional_copy_base::optional_copy_base;
-
- optional_move_base() = default;
- optional_move_base(const optional_move_base &rhs) = default;
-
- optional_move_base(optional_move_base &&rhs) noexcept(
- std::is_nothrow_move_constructible::value) {
- if (rhs.has_value()) {
- this->construct(std::move(rhs.get()));
- } else {
- this->m_has_value = false;
- }
- }
- optional_move_base &operator=(const optional_move_base &rhs) = default;
- optional_move_base &operator=(optional_move_base &&rhs) = default;
-};
-
-// This class manages conditionally having a trivial copy assignment operator
-template
-struct optional_copy_assign_base : optional_move_base {
- using optional_move_base::optional_move_base;
-};
-
-template
-struct optional_copy_assign_base : optional_move_base {
- using optional_move_base::optional_move_base;
-
- optional_copy_assign_base() = default;
- optional_copy_assign_base(const optional_copy_assign_base &rhs) = default;
-
- optional_copy_assign_base(optional_copy_assign_base &&rhs) = default;
- optional_copy_assign_base &operator=(const optional_copy_assign_base &rhs) {
- this->assign(rhs);
- return *this;
- }
- optional_copy_assign_base &
- operator=(optional_copy_assign_base &&rhs) = default;
-};
-
-// This class manages conditionally having a trivial move assignment operator
-// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
-// doesn't implement an analogue to std::is_trivially_move_assignable. We have
-// to make do with a non-trivial move assignment operator even if T is trivially
-// move assignable
-#ifndef TL_OPTIONAL_GCC49
-template ::value
- &&std::is_trivially_move_constructible::value
- &&std::is_trivially_move_assignable::value>
-struct optional_move_assign_base : optional_copy_assign_base {
- using optional_copy_assign_base::optional_copy_assign_base;
-};
-#else
-template struct optional_move_assign_base;
-#endif
-
-template
-struct optional_move_assign_base : optional_copy_assign_base {
- using optional_copy_assign_base::optional_copy_assign_base;
-
- optional_move_assign_base() = default;
- optional_move_assign_base(const optional_move_assign_base &rhs) = default;
-
- optional_move_assign_base(optional_move_assign_base &&rhs) = default;
-
- optional_move_assign_base &
- operator=(const optional_move_assign_base &rhs) = default;
-
- optional_move_assign_base &
- operator=(optional_move_assign_base &&rhs) noexcept(
- std::is_nothrow_move_constructible::value
- &&std::is_nothrow_move_assignable::value) {
- this->assign(std::move(rhs));
- return *this;
- }
-};
-
-// optional_delete_ctor_base will conditionally delete copy and move
-// constructors depending on whether T is copy/move constructible
-template ::value,
- bool EnableMove = std::is_move_constructible::value>
-struct optional_delete_ctor_base {
- optional_delete_ctor_base() = default;
- optional_delete_ctor_base(const optional_delete_ctor_base &) = default;
- optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = default;
- optional_delete_ctor_base &
- operator=(const optional_delete_ctor_base &) = default;
- optional_delete_ctor_base &
- operator=(optional_delete_ctor_base &&) noexcept = default;
-};
-
-template struct optional_delete_ctor_base {
- optional_delete_ctor_base() = default;
- optional_delete_ctor_base(const optional_delete_ctor_base &) = default;
- optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = delete;
- optional_delete_ctor_base &
- operator=(const optional_delete_ctor_base &) = default;
- optional_delete_ctor_base &
- operator=(optional_delete_ctor_base &&) noexcept = default;
-};
-
-template struct optional_delete_ctor_base {
- optional_delete_ctor_base() = default;
- optional_delete_ctor_base(const optional_delete_ctor_base &) = delete;
- optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = default;
- optional_delete_ctor_base &
- operator=(const optional_delete_ctor_base &) = default;
- optional_delete_ctor_base &
- operator=(optional_delete_ctor_base &&) noexcept = default;
-};
-
-template struct optional_delete_ctor_base {
- optional_delete_ctor_base() = default;
- optional_delete_ctor_base(const optional_delete_ctor_base &) = delete;
- optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = delete;
- optional_delete_ctor_base &
- operator=(const optional_delete_ctor_base &) = default;
- optional_delete_ctor_base &
- operator=(optional_delete_ctor_base &&) noexcept = default;
-};
-
-// optional_delete_assign_base will conditionally delete copy and move
-// constructors depending on whether T is copy/move constructible + assignable
-template ::value &&
- std::is_copy_assignable::value),
- bool EnableMove = (std::is_move_constructible::value &&
- std::is_move_assignable::value)>
-struct optional_delete_assign_base {
- 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 &
- operator=(const optional_delete_assign_base &) = default;
- optional_delete_assign_base &
- operator=(optional_delete_assign_base &&) noexcept = default;
-};
-
-template struct optional_delete_assign_base {
- 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 &
- operator=(const optional_delete_assign_base &) = default;
- optional_delete_assign_base &
- operator=(optional_delete_assign_base &&) noexcept = delete;
-};
-
-template struct optional_delete_assign_base {
- 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 &
- operator=(const optional_delete_assign_base &) = delete;
- optional_delete_assign_base &
- operator=(optional_delete_assign_base &&) noexcept = default;
-};
-
-template struct optional_delete_assign_base {
- 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 &
- operator=(const optional_delete_assign_base &) = delete;
- optional_delete_assign_base &
- operator=(optional_delete_assign_base &&) noexcept = delete;
-};
-
-} // namespace detail
-
-/// \brief A tag type to represent an empty optional
-struct nullopt_t {
- struct do_not_use {};
- constexpr explicit nullopt_t(do_not_use, do_not_use) noexcept {}
-};
-/// \brief Represents an empty optional
-/// \synopsis static constexpr nullopt_t nullopt;
-///
-/// *Examples*:
-/// ```
-/// tl::optional a = tl::nullopt;
-/// void foo (tl::optional);
-/// foo(tl::nullopt); //pass an empty optional
-/// ```
-static constexpr nullopt_t nullopt{nullopt_t::do_not_use{},
- nullopt_t::do_not_use{}};
-
-class bad_optional_access : public std::exception {
-public:
- bad_optional_access() = default;
- const char *what() const noexcept { return "Optional has no value"; }
-};
-
-/// An optional object is an object that contains the storage for another
-/// object and manages the lifetime of this contained object, if any. The
-/// contained object may be initialized after the optional object has been
-/// initialized, and may be destroyed before the optional object has been
-/// destroyed. The initialization state of the contained object is tracked by
-/// the optional object.
-template
-class optional : private detail::optional_move_assign_base,
- private detail::optional_delete_ctor_base,
- private detail::optional_delete_assign_base {
- using base = detail::optional_move_assign_base;
-
- static_assert(!std::is_same::value,
- "instantiation of optional with in_place_t is ill-formed");
- static_assert(!std::is_same, nullopt_t>::value,
- "instantiation of optional with nullopt_t is ill-formed");
-
-public:
-// The different versions for C++14 and 11 are needed because deduced return
-// types are not SFINAE-safe. This provides better support for things like
-// generic lambdas. C.f.
-// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html
-#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \
- !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
- /// \group and_then
- /// Carries out some operation which returns an optional on the stored
- /// object if there is one. \requires `std::invoke(std::forward(f),
- /// value())` returns a `std::optional` for some `U`. \returns Let `U` be
- /// the result of `std::invoke(std::forward(f), value())`. Returns a
- /// `std::optional`. The return value is empty if `*this` is empty,
- /// otherwise the return value of `std::invoke(std::forward(f), value())`
- /// is returned.
- /// \group and_then
- /// \synopsis template