72#ifndef ALEPH_CPP_COMPAT_H
73#define ALEPH_CPP_COMPAT_H
82#if __has_include(<version>)
90#if defined(__cpp_lib_expected) && __cpp_lib_expected >= 202211L
91# define ALEPH_HAS_STD_EXPECTED 1
93# define ALEPH_HAS_STD_EXPECTED 0
96#if defined(__cpp_lib_generator) && __cpp_lib_generator >= 202207L
97# define ALEPH_HAS_STD_GENERATOR 1
99# define ALEPH_HAS_STD_GENERATOR 0
102#if defined(__cpp_lib_flat_map) && __cpp_lib_flat_map >= 202207L
103# define ALEPH_HAS_STD_FLAT_MAP 1
105# define ALEPH_HAS_STD_FLAT_MAP 0
108#if defined(__cpp_lib_mdspan) && __cpp_lib_mdspan >= 202207L
109# define ALEPH_HAS_STD_MDSPAN 1
111# define ALEPH_HAS_STD_MDSPAN 0
118#if ALEPH_HAS_STD_EXPECTED
123template <
class T,
class E>
using expected = std::expected<T, E>;
124template <
class E>
using unexpected = std::unexpected<E>;
125template <
class E>
using bad_expected_access = std::bad_expected_access<E>;
127using std::unexpect_t;
134namespace cpp_compat_detail {
201 template <
class Err = E>
203 std::is_constructible_v<E, Err>)
205 noexcept(std::is_nothrow_constructible_v<E, Err>)
224 constexpr E &&
error() &&
noexcept {
return std::move(
err_); }
259 return "Aleph::bad_expected_access: expected holds an error, not a value";
284template <
class T,
class E>
287 static_assert(
not std::is_same_v<std::remove_cv_t<T>,
unexpect_t>,
288 "T must not be unexpect_t");
335 template <
class U =
T,
336 class = std::enable_if_t<
337 std::is_constructible_v<T, U &&>
and
338 not std::is_same_v<cpp_compat_detail::remove_cvref_t<U>,
expected>
and
339 not std::is_same_v<cpp_compat_detail::remove_cvref_t<U>,
unexpect_t>>>
385 template <
class...
Args>
404 ::new (
static_cast<void *
>(std::addressof(
val_)))
T(
o.val_);
406 ::new (
static_cast<void *
>(std::addressof(
err_))) E(
o.err_);
420 std::is_nothrow_move_constructible_v<E>)
424 ::new (
static_cast<void *
>(std::addressof(
val_)))
T(std::move(
o.val_));
426 ::new (
static_cast<void *
>(std::addressof(
err_))) E(std::move(
o.err_));
444 if (
this != std::addressof(
o))
450 ::new (
static_cast<void *
>(std::addressof(
val_)))
T(std::move(
tmp.val_));
452 ::new (
static_cast<void *
>(std::addressof(
err_))) E(std::move(
tmp.err_));
470 std::is_nothrow_move_constructible_v<T>
and
471 std::is_nothrow_move_constructible_v<E>)
473 if (
this != std::addressof(
o))
479 ::new (
static_cast<void *
>(std::addressof(
val_)))
T(std::move(
tmp.val_));
481 ::new (
static_cast<void *
>(std::addressof(
err_))) E(std::move(
tmp.err_));
531 return std::addressof(
val_);
541 return std::addressof(
val_);
600 return has_ ?
val_ :
static_cast<T>(std::forward<U>(default_value));
625 return std::invoke(std::forward<F>(f),
val_);
649 return R(std::invoke(std::forward<F>(f),
val_));
677 return std::invoke(std::forward<F>(f),
err_);
721 template <
class...
Args>
730 ::new (
static_cast<void *
>(std::addressof(
err_))) E(
o.err_);
737 ::new (
static_cast<void *
>(std::addressof(
err_))) E(std::move(
o.err_));
742 if (
this != std::addressof(
o))
748 ::new (
static_cast<void *
>(std::addressof(
err_))) E(std::move(
tmp.err_));
754 std::is_nothrow_move_constructible_v<E>)
756 if (
this != std::addressof(
o))
762 ::new (
static_cast<void *
>(std::addressof(
err_))) E(std::move(
tmp.err_));
786 return std::invoke(std::forward<F>(f));
796 return std::invoke(std::forward<F>(f),
err_);
Exception thrown by expected::value() when no value is held.
const char * what() const noexcept override
Get exception description.
E & error() &noexcept
Access the stored error (lvalue).
const E & error() const &noexcept
Access the stored error (const lvalue).
bad_expected_access(E e)
Construct with an error value.
auto and_then(F &&f) const
constexpr expected(unexpect_t, Args &&...args)
constexpr expected() noexcept
constexpr const E & error() const &noexcept
expected & operator=(expected &&o) noexcept(std::is_nothrow_move_constructible_v< E >)
constexpr expected(const unexpected< G > &u)
constexpr E & error() &noexcept
constexpr bool has_value() const noexcept
expected & operator=(const expected &o)
expected(const expected &o)
constexpr expected(unexpected< G > &&u)
constexpr void value() const
expected(expected &&o) noexcept(std::is_nothrow_move_constructible_v< E >)
auto or_else(F &&f) const
Minimal std::expected-style result type for C++20.
auto or_else(F &&f) const &
Monadic error recovery: handle the error.
expected & operator=(expected &&o) noexcept(std::is_nothrow_move_constructible_v< T > and std::is_nothrow_move_constructible_v< E >)
Move assignment.
constexpr expected(unexpected< G > &&u)
Construct an error from unexpected (rvalue).
constexpr T & operator*() &noexcept
Access the value (lvalue).
expected & operator=(const expected &o)
Copy assignment.
constexpr T * operator->() noexcept
Access the value via pointer (mutable).
constexpr T value_or(U &&default_value) const &
Get the value or a default.
constexpr T & value() &
Access the value with exception on error (lvalue).
constexpr E & error() &noexcept
Access the error (lvalue).
constexpr const T & operator*() const &noexcept
Access the value (const lvalue).
expected(const expected &o)
Copy constructor.
expected(expected &&o) noexcept(std::is_nothrow_move_constructible_v< T > and std::is_nothrow_move_constructible_v< E >)
Move constructor.
constexpr bool has_value() const noexcept
Check if a value is held.
auto and_then(F &&f) const &
Monadic bind: chain another fallible operation.
constexpr const E & error() const &noexcept
Access the error (const lvalue).
constexpr expected(unexpect_t, Args &&...args)
Construct an error in place.
constexpr expected()
Default-construct with a value.
auto transform(F &&f) const &
Monadic map: transform the value.
constexpr const T * operator->() const noexcept
Access the value via pointer (const).
constexpr expected(U &&v)
Construct from a value.
constexpr const T & value() const &
Access the value with exception on error (const lvalue).
constexpr expected(const unexpected< G > &u)
Construct an error from unexpected (lvalue).
Wrapper for the error value used to initialize an expected.
constexpr unexpected(Err &&e) noexcept(std::is_nothrow_constructible_v< E, Err >)
Construct the stored error from any value convertible to E.
constexpr E & error() &noexcept
Access the error (lvalue).
constexpr const E & error() const &noexcept
Access the error (const lvalue).
constexpr E && error() &&noexcept
Access the error (rvalue).
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
std::remove_cv_t< std::remove_reference_t< U > > remove_cvref_t
C++17-safe equivalent of C++20 cpp_compat_detail::remove_cvref_t.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
constexpr unexpect_t unexpect
Tag value of type unexpect_t.
Tag type used to construct an expected holding an error in place.