mirror of
https://github.com/TartanLlama/optional.git
synced 2025-07-30 09:57:13 +02:00
More functions
This commit is contained in:
164
optional.hpp
164
optional.hpp
@ -87,9 +87,8 @@ constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
|
|||||||
return std::mem_fn(f)(std::forward<Args>(args)...);
|
return std::mem_fn(f)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <typename Fn, typename... Args,
|
||||||
typename Fn, typename... Args,
|
enable_if_t<!std::is_member_pointer<decay_t<Fn>>{}, int> = 0>
|
||||||
enable_if_t<!std::is_member_pointer<decay_t<Fn>>{}, int> = 0>
|
|
||||||
constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
|
constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
|
||||||
noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
|
noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
|
||||||
-> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
|
-> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
|
||||||
@ -118,7 +117,8 @@ template <class F, class U> struct get_invoke_optional_ret {
|
|||||||
using type = invoke_result_t<
|
using type = invoke_result_t<
|
||||||
conditional_t<std::is_lvalue_reference<F>::value,
|
conditional_t<std::is_lvalue_reference<F>::value,
|
||||||
typename remove_reference_t<F>::value_type &,
|
typename remove_reference_t<F>::value_type &,
|
||||||
typename remove_reference_t<F>::value_type &&>, U>;
|
typename remove_reference_t<F>::value_type &&>,
|
||||||
|
U>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class F, class U>
|
template <class F, class U>
|
||||||
@ -711,10 +711,14 @@ public:
|
|||||||
constexpr const T *operator->() const {
|
constexpr const T *operator->() const {
|
||||||
return std::addressof(this->m_value);
|
return std::addressof(this->m_value);
|
||||||
}
|
}
|
||||||
TL_OPTIONAL_11_CONSTEXPR T *operator->() { return std::addressof(this->m_value); }
|
TL_OPTIONAL_11_CONSTEXPR T *operator->() {
|
||||||
|
return std::addressof(this->m_value);
|
||||||
|
}
|
||||||
constexpr const T &operator*() const & { return this->m_value; }
|
constexpr const T &operator*() const & { return this->m_value; }
|
||||||
TL_OPTIONAL_11_CONSTEXPR T &operator*() & { return this->m_value; }
|
TL_OPTIONAL_11_CONSTEXPR T &operator*() & { return this->m_value; }
|
||||||
TL_OPTIONAL_11_CONSTEXPR T &&operator*() && { return std::move(this->m_value); }
|
TL_OPTIONAL_11_CONSTEXPR T &&operator*() && {
|
||||||
|
return std::move(this->m_value);
|
||||||
|
}
|
||||||
constexpr const T &&operator*() const && { return std::move(this->m_value); }
|
constexpr const T &&operator*() const && { return std::move(this->m_value); }
|
||||||
constexpr explicit operator bool() const noexcept {
|
constexpr explicit operator bool() const noexcept {
|
||||||
return this->m_has_value;
|
return this->m_has_value;
|
||||||
@ -761,20 +765,24 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F> TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> bind(F &&f) & {
|
template <class F>
|
||||||
|
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> bind(F &&f) & {
|
||||||
using result = detail::invoke_result_t<F, T>;
|
using result = detail::invoke_result_t<F, T>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
|
|
||||||
return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
|
return has_value() ? detail::invoke(std::forward<F>(f), **this)
|
||||||
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F> TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> bind(F &&f) && {
|
template <class F>
|
||||||
|
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> bind(F &&f) && {
|
||||||
using result = detail::invoke_result_t<F, T>;
|
using result = detail::invoke_result_t<F, T>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
|
|
||||||
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
@ -783,7 +791,8 @@ public:
|
|||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
|
|
||||||
return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
|
return has_value() ? detail::invoke(std::forward<F>(f), **this)
|
||||||
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
@ -792,11 +801,15 @@ public:
|
|||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
|
|
||||||
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, class E>
|
template <class F, class E>
|
||||||
detail::invoke_result_t<F, T> bind(F &&f, E &&e) & {
|
detail::invoke_result_t<F, T> bind(F &&f, E &&e) &
|
||||||
|
noexcept(noexcept(detail::invoke(std::forward<F>(f),
|
||||||
|
std::declval<T &>())) &&
|
||||||
|
noexcept(std::forward<E>(e)())) {
|
||||||
using result = detail::invoke_result_t<F, T>;
|
using result = detail::invoke_result_t<F, T>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
@ -811,7 +824,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class F, class E>
|
template <class F, class E>
|
||||||
detail::invoke_result_t<F, T> bind(F &&f, E &&e) && {
|
detail::invoke_result_t<F, T> bind(F &&f, E &&e) && {
|
||||||
using result = detail::invoke_result_t<F, T>;
|
using result = detail::invoke_result_t<F, T>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
@ -857,16 +870,17 @@ public:
|
|||||||
|
|
||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T &> * = nullptr>
|
detail::disable_if_ret_void<F, T &> * = nullptr>
|
||||||
detail::get_map_return<F, T &> map(F &&f) & {
|
detail::get_map_return<F, T &> map(F &&f) &
|
||||||
using result = detail::get_map_return<F, T&>;
|
noexcept(noexcept(detail::invoke(std::forward<F>(f),
|
||||||
return has_value() ?
|
std::declval<T &>()))) {
|
||||||
detail::invoke(std::forward<F>(f), **this) :
|
using result = detail::get_map_return<F, T &>;
|
||||||
result(nullopt);
|
return has_value() ? detail::invoke(std::forward<F>(f), **this)
|
||||||
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::enable_if_ret_void<F, T &> * = nullptr>
|
detail::enable_if_ret_void<F, T &> * = nullptr>
|
||||||
detail::get_map_return<F, T &> map(F &&f) & {
|
detail::get_map_return<F, T &> map(F &&f) & {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
|
||||||
@ -876,16 +890,16 @@ public:
|
|||||||
|
|
||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T &> * = nullptr>
|
detail::disable_if_ret_void<F, T &> * = nullptr>
|
||||||
detail::get_map_return<F, T &> map(F &&f) & {
|
detail::get_map_return<F, T &> map(F &&f) & {
|
||||||
using result = detail::get_map_return<F, T&>;
|
using result = detail::get_map_return<F, T &>;
|
||||||
return (f.has_value() && has_value()) ?
|
return (f.has_value() && has_value())
|
||||||
detail::invoke(*std::forward<F>(f), **this) :
|
? detail::invoke(*std::forward<F>(f), **this)
|
||||||
result(nullopt);
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
detail::enable_if_ret_void<F, T &> * = nullptr>
|
detail::enable_if_ret_void<F, T &> * = nullptr>
|
||||||
detail::get_map_return<F, T &> map(F &&f) & {
|
detail::get_map_return<F, T &> map(F &&f) & {
|
||||||
if (!f.has_value() || !has_value())
|
if (!f.has_value() || !has_value())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
|
||||||
@ -896,15 +910,14 @@ public:
|
|||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T &&> * = nullptr>
|
detail::disable_if_ret_void<F, T &&> * = nullptr>
|
||||||
detail::get_map_return<F, T &&> map(F &&f) && {
|
detail::get_map_return<F, T &&> map(F &&f) && {
|
||||||
using result = detail::get_map_return<F, T&&>;
|
using result = detail::get_map_return<F, T &&>;
|
||||||
return has_value() ?
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
detail::invoke(std::forward<F>(f), std::move(**this)) :
|
: result(nullopt);
|
||||||
result(nullopt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::enable_if_ret_void<F, T &&> * = nullptr>
|
detail::enable_if_ret_void<F, T &&> * = nullptr>
|
||||||
detail::get_map_return<F, T &&> map(F &&f) && {
|
detail::get_map_return<F, T &&> map(F &&f) && {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
|
||||||
@ -914,16 +927,16 @@ public:
|
|||||||
|
|
||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T &&> * = nullptr>
|
detail::disable_if_ret_void<F, T &&> * = nullptr>
|
||||||
detail::get_map_return<F, T &&> map(F &&f) && {
|
detail::get_map_return<F, T &&> map(F &&f) && {
|
||||||
using result = detail::get_map_return<F, T&&>;
|
using result = detail::get_map_return<F, T &&>;
|
||||||
return (f.has_value() && has_value()) ?
|
return (f.has_value() && has_value())
|
||||||
detail::invoke(*std::forward<F>(f), std::move(**this)) :
|
? detail::invoke(*std::forward<F>(f), std::move(**this))
|
||||||
result(nullopt);
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
detail::enable_if_ret_void<F, T &&> * = nullptr>
|
detail::enable_if_ret_void<F, T &&> * = nullptr>
|
||||||
detail::get_map_return<F, T &&> map(F &&f) && {
|
detail::get_map_return<F, T &&> map(F &&f) && {
|
||||||
if (!f.has_value() || !has_value())
|
if (!f.has_value() || !has_value())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
|
||||||
@ -934,13 +947,15 @@ public:
|
|||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T const &> * = nullptr>
|
detail::disable_if_ret_void<F, T const &> * = nullptr>
|
||||||
constexpr detail::get_map_return<F, T const &> map(F &&f) const & {
|
constexpr detail::get_map_return<F, T const &> map(F &&f) const & {
|
||||||
using result = detail::get_map_return<F, T const &>;
|
using result = detail::get_map_return<F, T const &>;
|
||||||
return this->has_value() ? result(detail::invoke(std::forward<F>(f), **this)) : result(nullopt);
|
return this->has_value()
|
||||||
|
? result(detail::invoke(std::forward<F>(f), **this))
|
||||||
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::enable_if_ret_void<F, T const &> * = nullptr>
|
detail::enable_if_ret_void<F, T const &> * = nullptr>
|
||||||
detail::get_map_return<F, T const &> map(F &&f) const & {
|
detail::get_map_return<F, T const &> map(F &&f) const & {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
|
||||||
@ -951,10 +966,10 @@ public:
|
|||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T const &> * = nullptr>
|
detail::disable_if_ret_void<F, T const &> * = nullptr>
|
||||||
constexpr detail::get_map_return<F, T const &> map(F &&f) const & {
|
constexpr detail::get_map_return<F, T const &> map(F &&f) const & {
|
||||||
using result = detail::get_map_return<F, const T&>;
|
using result = detail::get_map_return<F, const T &>;
|
||||||
return (f.has_value() && has_value()) ?
|
return (f.has_value() && has_value())
|
||||||
detail::invoke(*std::forward<F>(f), **this) :
|
? detail::invoke(*std::forward<F>(f), **this)
|
||||||
result(nullopt);
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
@ -970,15 +985,14 @@ public:
|
|||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T const &&> * = nullptr>
|
detail::disable_if_ret_void<F, T const &&> * = nullptr>
|
||||||
constexpr detail::get_map_return<F, T const &&> map(F &&f) const && {
|
constexpr detail::get_map_return<F, T const &&> map(F &&f) const && {
|
||||||
using result = detail::get_map_return<F, const T&&>;
|
using result = detail::get_map_return<F, const T &&>;
|
||||||
return has_value() ?
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
detail::invoke(std::forward<F>(f), std::move(**this)) :
|
: result(nullopt);
|
||||||
result(nullopt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::disable_if_optional<F> * = nullptr,
|
template <class F, detail::disable_if_optional<F> * = nullptr,
|
||||||
detail::enable_if_ret_void<F, T const &&> * = nullptr>
|
detail::enable_if_ret_void<F, T const &&> * = nullptr>
|
||||||
detail::get_map_return<F, T const &&> map(F &&f) const && {
|
detail::get_map_return<F, T const &&> map(F &&f) const && {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
|
||||||
@ -989,22 +1003,62 @@ public:
|
|||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
detail::disable_if_ret_void<F, T const &&> * = nullptr>
|
detail::disable_if_ret_void<F, T const &&> * = nullptr>
|
||||||
constexpr detail::get_map_return<F, T const &&> map(F &&f) const && {
|
constexpr detail::get_map_return<F, T const &&> map(F &&f) const && {
|
||||||
using result = detail::get_map_return<F, const T&&>;
|
using result = detail::get_map_return<F, const T &&>;
|
||||||
return (f.has_value() && has_value()) ?
|
return (f.has_value() && has_value())
|
||||||
detail::invoke(*std::forward<F>(f), std::move(**this)) :
|
? detail::invoke(*std::forward<F>(f), std::move(**this))
|
||||||
result(nullopt);
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, detail::enable_if_optional<F> * = nullptr,
|
template <class F, detail::enable_if_optional<F> * = nullptr,
|
||||||
detail::enable_if_ret_void<F, T const &&> * = nullptr>
|
detail::enable_if_ret_void<F, T const &&> * = nullptr>
|
||||||
detail::get_map_return<F, T &> map(F &&f) const && {
|
detail::get_map_return<F, T &> map(F &&f) const && {
|
||||||
if (!f.has_value() || !has_value())
|
if (!f.has_value() || !has_value())
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
|
||||||
detail::invoke(*std::forward<F>(f), std::move(**this));
|
detail::invoke(*std::forward<F>(f), std::move(**this));
|
||||||
return monostate{};
|
return monostate{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or(F &&f, U &&u) & {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), **this)
|
||||||
|
: std::forward<U>(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or(F &&f, U &&u) && {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
|
: std::forward<U>(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or(F &&f, U &&u) const & {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), **this)
|
||||||
|
: std::forward<U>(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or(F &&f, U &&u) const && {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
|
: std::forward<U>(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or_else(F &&f, U &&u) & {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), **this)
|
||||||
|
: std::forward<U>(u)();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or_else(F &&f, U &&u) && {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
|
: std::forward<U>(u)();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or_else(F &&f, U &&u) const & {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), **this)
|
||||||
|
: std::forward<U>(u)();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, class U> U map_or_else(F &&f, U &&u) const && {
|
||||||
|
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
|
||||||
|
: std::forward<U>(u)();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//template <class T> optional(T)->optional<T>;
|
// template <class T> optional(T)->optional<T>;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user