diff --git a/.clang-format b/.clang-format index 01d5fac..822f5c4 100644 --- a/.clang-format +++ b/.clang-format @@ -196,7 +196,7 @@ SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true SpaceBeforeJsonColon: false -SpaceBeforeParens: ControlStatements +SpaceBeforeParens: Custom SpaceBeforeParensOptions: AfterControlStatements: true AfterForeachMacros: true @@ -204,7 +204,7 @@ SpaceBeforeParensOptions: AfterFunctionDeclarationName: false AfterIfMacros: true AfterOverloadedOperator: false - AfterRequiresInClause: false + AfterRequiresInClause: true AfterRequiresInExpression: false BeforeNonEmptyParentheses: false SpaceBeforeRangeBasedForLoopColon: true diff --git a/include/beman/optional/detail/stl_interfaces/iterator_interface.hpp b/include/beman/optional/detail/stl_interfaces/iterator_interface.hpp index 8a0c0f8..3c8c373 100644 --- a/include/beman/optional/detail/stl_interfaces/iterator_interface.hpp +++ b/include/beman/optional/detail/stl_interfaces/iterator_interface.hpp @@ -435,7 +435,7 @@ BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V2 { }; template - requires( + requires ( !requires { typename std::iterator_traits::iterator_concept; } && requires { typename std::iterator_traits::iterator_category; }) struct iter_concept { @@ -443,7 +443,7 @@ BEMAN_OPTIONAL_DETAIL_STL_INTERFACES_NAMESPACE_V2 { }; template - requires( + requires ( !requires { typename std::iterator_traits::iterator_concept; } && !requires { typename std::iterator_traits::iterator_category; }) struct iter_concept { diff --git a/include/beman/optional/optional.hpp b/include/beman/optional/optional.hpp index 4d72548..e927f93 100644 --- a/include/beman/optional/optional.hpp +++ b/include/beman/optional/optional.hpp @@ -92,6 +92,12 @@ inline constexpr auto std::format_kind> = range_for #endif namespace beman::optional { +namespace detail { +template +inline constexpr bool is_optional = false; +template +inline constexpr bool is_optional> = true; +} // namespace detail /** * @brief Concept for checking if derived from optional. */ @@ -155,42 +161,54 @@ constexpr std::strong_ordering operator<=>(const optional&, nullopt_t) noexce // \ref{optional.comp.with.t}, comparison with \tcode{T} template constexpr bool operator==(const optional& lhs, const U& rhs) - requires detail::optional_eq_rel; + requires (!detail::is_optional) && detail::optional_eq_rel; + template constexpr bool operator==(const T& lhs, const optional& rhs) - requires detail::optional_eq_rel; + requires (!detail::is_optional) && detail::optional_eq_rel; + template constexpr bool operator!=(const optional& lhs, const U& rhs) - requires detail::optional_ne_rel; + requires (!detail::is_optional) && detail::optional_ne_rel; + template constexpr bool operator!=(const T& lhs, const optional& rhs) - requires detail::optional_ne_rel; + requires (!detail::is_optional) && detail::optional_ne_rel; + template constexpr bool operator<(const optional& lhs, const U& rhs) - requires detail::optional_lt_rel; + requires (!detail::is_optional) && detail::optional_lt_rel; + template constexpr bool operator<(const T& lhs, const optional& rhs) - requires detail::optional_lt_rel; + requires (!detail::is_optional) && detail::optional_lt_rel; + template constexpr bool operator>(const optional& lhs, const U& rhs) - requires detail::optional_gt_rel; + requires (!detail::is_optional) && detail::optional_gt_rel; + template constexpr bool operator>(const T& lhs, const optional& rhs) - requires detail::optional_gt_rel; + requires (!detail::is_optional) && detail::optional_gt_rel; + template constexpr bool operator<=(const optional& lhs, const U& rhs) - requires detail::optional_le_rel; + requires (!detail::is_optional) && detail::optional_le_rel; + template constexpr bool operator<=(const T& lhs, const optional& rhs) - requires detail::optional_le_rel; + requires (!detail::is_optional) && detail::optional_le_rel; + template constexpr bool operator>=(const optional& lhs, const U& rhs) - requires detail::optional_ge_rel; + requires (!detail::is_optional) && detail::optional_ge_rel; + template constexpr bool operator>=(const T& lhs, const optional& rhs) - requires detail::optional_ge_rel; + requires (!detail::is_optional) && detail::optional_ge_rel; + template - requires(!is_derived_from_optional) && std::three_way_comparable_with + requires (!is_derived_from_optional) && std::three_way_comparable_with constexpr std::compare_three_way_result_t operator<=>(const optional& x, const U& v); // \ref{optional.specalg}, specialized algorithms @@ -261,14 +279,6 @@ concept enable_assign_from_other = !std::is_assignable_v&> && !std::is_assignable_v&&>; } // namespace detail -namespace detail { -template -concept is_optional = requires(const T& t) { // exposition only - [](const optional&) {}(t); -}; - -} // namespace detail - // 22.5.3.1 General[optional.optional.general] /** @@ -377,14 +387,14 @@ class optional { */ template constexpr explicit(!std::is_convertible_v) optional(const optional& rhs) - requires(detail::enable_from_other); + requires (detail::enable_from_other); /** * @brief Constructs the value from \p rhs if it has one. */ template constexpr explicit(!std::is_convertible_v) optional(optional&& rhs) - requires(detail::enable_from_other); + requires (detail::enable_from_other); // \ref{optional.dtor}, destructor /** @@ -399,7 +409,7 @@ class optional { * @brief Destroys the optional and its value if it has one. */ constexpr ~optional() - requires(!std::is_trivially_destructible_v); + requires (!std::is_trivially_destructible_v); // \ref{optional.assign}, assignment /** @@ -456,14 +466,14 @@ class optional { */ template constexpr optional& operator=(const optional& rhs) - requires(detail::enable_assign_from_other); + requires (detail::enable_assign_from_other); /** * @brief Assigns the contained value from \p rhs if it has one, destroying the old value if there */ template constexpr optional& operator=(optional&& rhs) - requires(detail::enable_assign_from_other); + requires (detail::enable_assign_from_other); /** * @brief Constructs the value in-place, destroying the current one if there * @@ -841,7 +851,7 @@ inline constexpr optional::optional(U&& u) template template inline constexpr optional::optional(const optional& rhs) - requires(detail::enable_from_other) + requires (detail::enable_from_other) { if (rhs.has_value()) { construct(*rhs); @@ -852,7 +862,7 @@ inline constexpr optional::optional(const optional& rhs) template template inline constexpr optional::optional(optional&& rhs) - requires(detail::enable_from_other) + requires (detail::enable_from_other) { if (rhs.has_value()) { construct(*std::move(rhs)); @@ -863,7 +873,7 @@ inline constexpr optional::optional(optional&& rhs) template inline constexpr optional::~optional() - requires(!std::is_trivially_destructible_v) + requires (!std::is_trivially_destructible_v) { if (has_value()) std::destroy_at(std::addressof(value_)); @@ -929,7 +939,7 @@ inline constexpr optional& optional::operator=(U&& u) template template inline constexpr optional& optional::operator=(const optional& rhs) - requires(detail::enable_assign_from_other) + requires (detail::enable_assign_from_other) { if (has_value()) { if (rhs.has_value()) { @@ -953,7 +963,7 @@ inline constexpr optional& optional::operator=(const optional& rhs) template template inline constexpr optional& optional::operator=(optional&& rhs) - requires(detail::enable_assign_from_other) + requires (detail::enable_assign_from_other) { if (has_value()) { if (rhs.has_value()) { @@ -1316,90 +1326,90 @@ constexpr std::strong_ordering operator<=>(const optional& x, nullopt_t) noex // 22.5.8 Comparison with T[optional.comp.with.t] template constexpr bool operator==(const optional& lhs, const U& rhs) - requires detail::optional_eq_rel + requires (!detail::is_optional) && detail::optional_eq_rel { return lhs && *lhs == rhs; } template constexpr bool operator==(const T& lhs, const optional& rhs) - requires detail::optional_eq_rel + requires (!detail::is_optional) && detail::optional_eq_rel { return rhs && lhs == *rhs; } template constexpr bool operator!=(const optional& lhs, const U& rhs) - requires detail::optional_ne_rel + requires (!detail::is_optional) && detail::optional_ne_rel { return !lhs || *lhs != rhs; } template constexpr bool operator!=(const T& lhs, const optional& rhs) - requires detail::optional_ne_rel + requires (!detail::is_optional) && detail::optional_ne_rel { return !rhs || lhs != *rhs; } template constexpr bool operator<(const optional& lhs, const U& rhs) - requires detail::optional_lt_rel + requires (!detail::is_optional) && detail::optional_lt_rel { return !lhs || *lhs < rhs; } template constexpr bool operator<(const T& lhs, const optional& rhs) - requires detail::optional_lt_rel + requires (!detail::is_optional) && detail::optional_lt_rel { return rhs && lhs < *rhs; } template constexpr bool operator>(const optional& lhs, const U& rhs) - requires detail::optional_gt_rel + requires (!detail::is_optional) && detail::optional_gt_rel { return lhs && *lhs > rhs; } template constexpr bool operator>(const T& lhs, const optional& rhs) - requires detail::optional_gt_rel + requires (!detail::is_optional) && detail::optional_gt_rel { return !rhs || lhs > *rhs; } template constexpr bool operator<=(const optional& lhs, const U& rhs) - requires detail::optional_le_rel + requires (!detail::is_optional) && detail::optional_le_rel { return !lhs || *lhs <= rhs; } template constexpr bool operator<=(const T& lhs, const optional& rhs) - requires detail::optional_le_rel + requires (!detail::is_optional) && detail::optional_le_rel { return rhs && lhs <= *rhs; } template constexpr bool operator>=(const optional& lhs, const U& rhs) - requires detail::optional_ge_rel + requires (!detail::is_optional) && detail::optional_ge_rel { return lhs && *lhs >= rhs; } template constexpr bool operator>=(const T& lhs, const optional& rhs) - requires detail::optional_ge_rel + requires (!detail::is_optional) && detail::optional_ge_rel { return !rhs || lhs >= *rhs; } template - requires(!is_derived_from_optional) && std::three_way_comparable_with + requires (!is_derived_from_optional) && std::three_way_comparable_with constexpr std::compare_three_way_result_t operator<=>(const optional& x, const U& v) { return bool(x) ? *x <=> v : std::strong_ordering::less; } @@ -1519,7 +1529,7 @@ class optional { * @param arg The value to construct in-place from. */ template - requires(std::is_constructible_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !detail::reference_constructs_from_temporary_v) constexpr explicit optional(in_place_t, Arg&& arg); /** @@ -1532,9 +1542,9 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !(std::is_same_v, in_place_t>) && - !(std::is_same_v, optional>) && - !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !(std::is_same_v, in_place_t>) && + !(std::is_same_v, optional>) && + !detail::reference_constructs_from_temporary_v) constexpr explicit(!std::is_convertible_v) optional(U&& u) noexcept(std::is_nothrow_constructible_v) { convert_ref_init_val(u); @@ -1546,9 +1556,9 @@ class optional { * @tparam U */ template - requires(std::is_constructible_v && !(std::is_same_v, in_place_t>) && - !(std::is_same_v, optional>) && - detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !(std::is_same_v, in_place_t>) && + !(std::is_same_v, optional>) && + detail::reference_constructs_from_temporary_v) constexpr optional(U&& u) = delete; // The full set of 4 overloads on optional by value category, doubled to @@ -1568,8 +1578,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr explicit(!std::is_convertible_v) optional(optional& rhs) noexcept(std::is_nothrow_constructible_v); @@ -1584,8 +1594,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr explicit(!std::is_convertible_v) optional(const optional& rhs) noexcept(std::is_nothrow_constructible_v); @@ -1600,8 +1610,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr explicit(!std::is_convertible_v) optional(optional&& rhs) noexcept(noexcept(std::is_nothrow_constructible_v)); @@ -1617,8 +1627,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr explicit(!std::is_convertible_v) optional(const optional&& rhs) noexcept(noexcept(std::is_nothrow_constructible_v)); @@ -1634,8 +1644,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && detail::reference_constructs_from_temporary_v) constexpr optional(optional& rhs) = delete; /** @@ -1650,8 +1660,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && detail::reference_constructs_from_temporary_v) constexpr optional(const optional& rhs) = delete; /** @@ -1666,8 +1676,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && detail::reference_constructs_from_temporary_v) constexpr optional(optional&& rhs) = delete; /** @@ -1682,8 +1692,8 @@ class optional { * deleted to prevent binding a temporary to a reference. */ template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && detail::reference_constructs_from_temporary_v) constexpr optional(const optional&& rhs) = delete; // \ref{optionalref.dtor}, destructor @@ -1729,7 +1739,7 @@ class optional { * Constructs the contained value from `u` if it is convertible to `T&`. */ template - requires(std::is_constructible_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !detail::reference_constructs_from_temporary_v) constexpr T& emplace(U&& u) noexcept(std::is_nothrow_constructible_v); // \ref{optionalref.swap}, swap @@ -1875,7 +1885,7 @@ class optional { // \rSec3[optionalref.ctor]{Constructors} template template - requires(std::is_constructible_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !detail::reference_constructs_from_temporary_v) constexpr optional::optional(in_place_t, Arg&& arg) { convert_ref_init_val(std::forward(arg)); } @@ -1891,8 +1901,8 @@ constexpr optional::optional(in_place_t, Arg&& arg) { template template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr optional::optional(optional& rhs) noexcept(std::is_nothrow_constructible_v) { if (rhs.has_value()) { convert_ref_init_val(*rhs); @@ -1901,8 +1911,8 @@ constexpr optional::optional(optional& rhs) noexcept(std::is_nothrow_cons template template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr optional::optional(const optional& rhs) noexcept(std::is_nothrow_constructible_v) { if (rhs.has_value()) { convert_ref_init_val(*rhs); @@ -1911,8 +1921,8 @@ constexpr optional::optional(const optional& rhs) noexcept(std::is_nothro template template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr optional::optional(optional&& rhs) noexcept(noexcept(std::is_nothrow_constructible_v)) { if (rhs.has_value()) { convert_ref_init_val(*std::move(rhs)); @@ -1921,8 +1931,8 @@ constexpr optional::optional(optional&& rhs) noexcept(noexcept(std::is_no template template - requires(std::is_constructible_v && !std::is_same_v, optional> && - !std::is_same_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !std::is_same_v, optional> && + !std::is_same_v && !detail::reference_constructs_from_temporary_v) constexpr optional::optional(const optional&& rhs) noexcept( noexcept(std::is_nothrow_constructible_v)) { if (rhs.has_value()) { @@ -1939,7 +1949,7 @@ constexpr optional& optional::operator=(nullopt_t) noexcept { template template - requires(std::is_constructible_v && !detail::reference_constructs_from_temporary_v) + requires (std::is_constructible_v && !detail::reference_constructs_from_temporary_v) constexpr T& optional::emplace(U&& u) noexcept(std::is_nothrow_constructible_v) { convert_ref_init_val(std::forward(u)); return *value_;