8
8
#define SMALL_VECTORS_EXPECTED
9
9
#include < version>
10
10
11
- #if defined(__cpp_lib_expected) && __cpp_lib_expected >= 202211L
11
+ #if !defined(SMALL_VECTORS_ENABLE_CUSTOM_EXCPECTED) && defined(__cpp_lib_expected) && __cpp_lib_expected >= 202211L
12
12
#include < expected>
13
13
14
14
namespace cxx23
@@ -110,7 +110,7 @@ namespace detail
110
110
}
111
111
112
112
template <typename E>
113
- class unexpected
113
+ class [[clang::trivial_abi]] unexpected
114
114
{
115
115
public:
116
116
static_assert (concepts::unexpected_constraint<E>, " not a valid type for unexpected error type" );
@@ -304,8 +304,11 @@ namespace concepts
304
304
};
305
305
} // namespace concepts
306
306
307
+ // https://clang.llvm.org/docs/AttributeReference.html#trivial-abi
308
+ // Attribute trivial_abi has no effect when the class has a non-static data member whose type is non-trivial for the
309
+ // purposes of calls
307
310
template <typename T, typename E>
308
- class expected
311
+ class [[nodiscard, clang::trivial_abi]] expected
309
312
{
310
313
public:
311
314
static_assert (concepts::unexpected_constraint<E>, " not a valid type for expected error type" );
@@ -388,9 +391,11 @@ class expected
388
391
requires std::is_constructible_v<E, G const &>;
389
392
requires concepts::expected_conv_constr<T, E, U, G>;
390
393
}
391
- constexpr explicit (!std::is_convertible_v<std::add_lvalue_reference_t <U const >, T> || !std::is_convertible_v<G const &, E>) expected(
392
- expected<U, G> const & rh
393
- ) noexcept (std::is_nothrow_constructible_v<value_type, decltype(std::forward<std::add_lvalue_reference_t <U const >>(rh.value()))> && std::is_nothrow_constructible_v<error_type, decltype(std::forward<G const &>(rh.error()))>) :
394
+ constexpr explicit (!std::is_convertible_v<std::add_lvalue_reference_t <U const >, T> || !std::is_convertible_v<G const &, E>) expected (expected<U, G> const & rh) noexcept (
395
+ std::
396
+ is_nothrow_constructible_v<value_type, decltype (std::forward<std::add_lvalue_reference_t <U const >>(rh.value ()))>
397
+ && std::is_nothrow_constructible_v<error_type, decltype (std::forward<G const &>(rh.error ()))>
398
+ ) :
394
399
has_value_{rh.has_value ()}
395
400
{
396
401
if (has_value_) [[likely]]
@@ -405,8 +410,10 @@ class expected
405
410
requires std::is_constructible_v<E, G>;
406
411
requires concepts::expected_conv_constr<T, E, U, G>;
407
412
}
408
- constexpr explicit (!std::is_convertible_v<U, T> || !std::is_convertible_v<G, E>) expected(expected<U, G> && rh
409
- ) noexcept (std::is_nothrow_constructible_v<value_type, decltype(std::forward<U>(rh.value()))> && std::is_nothrow_constructible_v<error_type, decltype(std::forward<G>(rh.error()))>) :
413
+ constexpr explicit (!std::is_convertible_v<U, T> || !std::is_convertible_v<G, E>) expected (expected<U, G> && rh) noexcept (
414
+ std::is_nothrow_constructible_v<value_type, decltype (std::forward<U>(rh.value ()))>
415
+ && std::is_nothrow_constructible_v<error_type, decltype (std::forward<G>(rh.error ()))>
416
+ ) :
410
417
has_value_{rh.has_value ()}
411
418
{
412
419
if (has_value_) [[likely]]
@@ -423,8 +430,8 @@ class expected
423
430
requires !concepts::is_unexpected<std::remove_cvref_t <U>>;
424
431
requires !std::same_as<bool , T> || !concepts::is_expected<std::remove_cvref_t <U>>;
425
432
}
426
- constexpr explicit (!std::is_convertible_v<U, T>)
427
- expected(U && v) noexcept (std::is_nothrow_constructible_v<value_type, decltype(std::forward<U>(v))>) :
433
+ constexpr explicit (!std::is_convertible_v<U, T>
434
+ ) expected (U && v) noexcept (std::is_nothrow_constructible_v<value_type, decltype (std::forward<U>(v))>) :
428
435
has_value_{true }
429
436
{
430
437
std::construct_at (std::addressof (value_), std::forward<U>(v));
@@ -617,7 +624,8 @@ class expected
617
624
618
625
template <typename U>
619
626
[[nodiscard]]
620
- constexpr value_type value_or (U && default_value
627
+ constexpr value_type value_or (
628
+ U && default_value
621
629
) const & noexcept (std::is_nothrow_copy_constructible_v<value_type> && std::is_nothrow_convertible_v<U, value_type>)
622
630
requires value_copy_constructible && std::is_convertible_v<U, value_type>
623
631
{
@@ -626,7 +634,8 @@ class expected
626
634
627
635
template <typename U>
628
636
[[nodiscard]]
629
- constexpr value_type value_or (U && default_value
637
+ constexpr value_type value_or (
638
+ U && default_value
630
639
) && noexcept (std::is_nothrow_move_constructible_v<value_type> && std::is_nothrow_convertible_v<U, value_type>)
631
640
requires value_move_constructible && std::is_convertible_v<U, value_type>
632
641
{
@@ -883,7 +892,8 @@ class expected<T, E>
883
892
requires std::is_constructible_v<E, G const &>;
884
893
requires concepts::expected_conv_constr<void , E, U, G>;
885
894
}
886
- constexpr explicit (!std::is_convertible_v<G const &, E>) expected(expected<U, G> const & rh
895
+ constexpr explicit (!std::is_convertible_v<G const &, E>) expected(
896
+ expected<U, G> const & rh
887
897
) noexcept (std::is_nothrow_constructible_v<error_type, decltype(std::forward<G const &>(rh.error()))>) :
888
898
has_value_{rh.has_value ()}
889
899
{
@@ -897,7 +907,8 @@ class expected<T, E>
897
907
requires std::is_constructible_v<E, G>;
898
908
requires concepts::expected_conv_constr<void , E, U, G>;
899
909
}
900
- constexpr explicit (!std::is_convertible_v<G, E>) expected(expected<U, G> && rh
910
+ constexpr explicit (!std::is_convertible_v<G, E>) expected(
911
+ expected<U, G> && rh
901
912
) noexcept (std::is_nothrow_constructible_v<error_type, decltype(std::forward<G>(rh.error()))>) :
902
913
has_value_{rh.has_value ()}
903
914
{
@@ -1286,8 +1297,9 @@ namespace detail
1286
1297
struct swap_expected_t
1287
1298
{
1288
1299
template <typename T, typename E>
1289
- static_call_operator constexpr void operator ()(expected<T, E> & l, expected<T, E> & r) static_call_operator_const
1290
- noexcept (detail::swap_no_throw<T, E>)
1300
+ static_call_operator constexpr void
1301
+ operator ()(expected<T, E> & l, expected<T, E> & r) static_call_operator_const noexcept (detail::swap_no_throw<T, E>
1302
+ )
1291
1303
requires concepts::swap_constraints<T, E>
1292
1304
{
1293
1305
if (l.has_value () && r.has_value ())
0 commit comments