Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions include/tl/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
#include <type_traits>
#include <utility>

#ifdef __EXCEPTIONS
#define TL_OPTIONAL_THROW(e) throw e
#else
Copy link

@lukasnee-kna lukasnee-kna Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing #include <cstdlib> for std::abort

#define TL_OPTIONAL_THROW(e) std::abort()
#endif

#if (defined(_MSC_VER) && _MSC_VER == 1900)
#define TL_OPTIONAL_MSVC2015
#endif
Expand Down Expand Up @@ -73,7 +79,7 @@ namespace tl {
template<class T, class A>
struct is_trivially_copy_constructible<std::vector<T,A>>
: std::is_trivially_copy_constructible<T>{};
#endif
#endif
}
}
#endif
Expand Down Expand Up @@ -153,25 +159,25 @@ struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...)> : std::true_typ
template <class T, class Ret, class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...)&> : std::true_type{};
template <class T, class Ret, class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...)&&> : std::true_type{};
struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...)&&> : std::true_type{};
template <class T, class Ret, class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...) volatile> : std::true_type{};
template <class T, class Ret, class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...) volatile&> : std::true_type{};
template <class T, class Ret, class... Args>
struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...) volatile&&> : std::true_type{};
struct is_pointer_to_non_const_member_func<Ret (T::*) (Args...) volatile&&> : std::true_type{};

template <class T> struct is_const_or_const_ref : std::false_type{};
template <class T> struct is_const_or_const_ref<T const&> : std::true_type{};
template <class T> struct is_const_or_const_ref<T const> : std::true_type{};
template <class T> struct is_const_or_const_ref<T const> : std::true_type{};
#endif

// std::invoke from C++17
// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
template <typename Fn, typename... Args,
#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value
&& is_const_or_const_ref<Args...>::value)>,
typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value
&& is_const_or_const_ref<Args...>::value)>,
#endif
typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
int = 0>
Expand Down Expand Up @@ -1229,7 +1235,7 @@ class optional : private detail::optional_move_assign_base<T>,
emplace(std::initializer_list<U> il, Args &&... args) {
*this = nullopt;
this->construct(il, std::forward<Args>(args)...);
return value();
return value();
}

/// Swaps this optional with the other.
Expand Down Expand Up @@ -1289,24 +1295,24 @@ class optional : private detail::optional_move_assign_base<T>,
TL_OPTIONAL_11_CONSTEXPR T &value() & {
if (has_value())
return this->m_value;
throw bad_optional_access();
TL_OPTIONAL_THROW(bad_optional_access);
}
TL_OPTIONAL_11_CONSTEXPR const T &value() const & {
if (has_value())
return this->m_value;
throw bad_optional_access();
TL_OPTIONAL_THROW(bad_optional_access);
}
TL_OPTIONAL_11_CONSTEXPR T &&value() && {
if (has_value())
return std::move(this->m_value);
throw bad_optional_access();
TL_OPTIONAL_THROW(bad_optional_access);
}

#ifndef TL_OPTIONAL_NO_CONSTRR
TL_OPTIONAL_11_CONSTEXPR const T &&value() const && {
if (has_value())
return std::move(this->m_value);
throw bad_optional_access();
TL_OPTIONAL_THROW(bad_optional_access);
}
#endif

Expand Down Expand Up @@ -2012,12 +2018,12 @@ template <class T> class optional<T &> {
TL_OPTIONAL_11_CONSTEXPR T &value() {
if (has_value())
return *m_value;
throw bad_optional_access();
TL_OPTIONAL_THROW(bad_optional_access);
}
TL_OPTIONAL_11_CONSTEXPR const T &value() const {
if (has_value())
return *m_value;
throw bad_optional_access();
TL_OPTIONAL_THROW(bad_optional_access);
}

/// Returns the stored value if there is one, otherwise returns `u`
Expand Down