diff --git a/include/beman/optional26/optional.hpp b/include/beman/optional26/optional.hpp index be22fd3b..2b32eb48 100644 --- a/include/beman/optional26/optional.hpp +++ b/include/beman/optional26/optional.hpp @@ -288,7 +288,8 @@ concept enable_assign_from_other = template class optional { static_assert((!std::is_same_v>) && - (!std::is_same_v, nullopt_t>)); + (!std::is_same_v, nullopt_t>), + "T must not be in_place_t or nullopt_t"); struct empty {}; union { @@ -487,7 +488,7 @@ class optional { template constexpr auto and_then(F&& f) & { using U = std::invoke_result_t; - static_assert(detail::is_optional>); + static_assert(detail::is_optional>, "F must return an optional"); if (has_value()) { return std::invoke(std::forward(f), value_); } else { @@ -498,7 +499,7 @@ class optional { template constexpr auto and_then(F&& f) && { using U = std::invoke_result_t; - static_assert(detail::is_optional>); + static_assert(detail::is_optional>, "F must return an optional"); if (has_value()) { return std::invoke(std::forward(f), std::move(value_)); } else { @@ -509,7 +510,7 @@ class optional { template constexpr auto and_then(F&& f) const& { using U = std::invoke_result_t; - static_assert(detail::is_optional>); + static_assert(detail::is_optional>, "F must return an optional"); if (has_value()) { return std::invoke(std::forward(f), value_); } else { @@ -520,7 +521,7 @@ class optional { template constexpr auto and_then(F&& f) const&& { using U = std::invoke_result_t; - static_assert(detail::is_optional>); + static_assert(detail::is_optional>, "F must return an optional"); if (has_value()) { return std::invoke(std::forward(f), std::move(value_)); } else { @@ -532,40 +533,44 @@ class optional { template constexpr auto transform(F&& f) & { using U = std::invoke_result_t; - static_assert(!std::is_array_v); - static_assert(!std::is_same_v); - static_assert(!std::is_same_v); - static_assert(std::is_object_v || std::is_reference_v); /// References now allowed + static_assert(!std::is_array_v, "U must not be an array"); + static_assert(!std::is_same_v, "U must not be an inplace type"); + static_assert(!std::is_same_v, "U must not be nullopt_t"); + static_assert(std::is_object_v || std::is_reference_v, + "U must be either an object or a reference"); /// References now allowed return (has_value()) ? optional{std::invoke(std::forward(f), value_)} : optional{}; } template constexpr auto transform(F&& f) && { using U = std::invoke_result_t; - static_assert(!std::is_array_v); - static_assert(!std::is_same_v); - static_assert(!std::is_same_v); - static_assert(std::is_object_v || std::is_reference_v); /// References now allowed + static_assert(!std::is_array_v, "U must not be an array"); + static_assert(!std::is_same_v, "U must not be an inplace type"); + static_assert(!std::is_same_v, "U must not be nullopt_t type"); + static_assert(std::is_object_v || std::is_reference_v, + "U must be either an objecy or a reference"); /// References now allowed return (has_value()) ? optional{std::invoke(std::forward(f), std::move(value_))} : optional{}; } template constexpr auto transform(F&& f) const& { using U = std::invoke_result_t; - static_assert(!std::is_array_v); - static_assert(!std::is_same_v); - static_assert(!std::is_same_v); - static_assert(std::is_object_v || std::is_reference_v); /// References now allowed + static_assert(!std::is_array_v, "U must not be an array"); + static_assert(!std::is_same_v, "U must not be an inplace type"); + static_assert(!std::is_same_v, "U must not be nullopt_t type"); + static_assert(std::is_object_v || std::is_reference_v, + "U must be either an objecy or a reference"); /// References now allowed return (has_value()) ? optional{std::invoke(std::forward(f), value_)} : optional{}; } template constexpr auto transform(F&& f) const&& { using U = std::invoke_result_t; - static_assert(!std::is_array_v); - static_assert(!std::is_same_v); - static_assert(!std::is_same_v); - static_assert(std::is_object_v || std::is_reference_v); /// References now allowed + static_assert(!std::is_array_v, "U must not be an array"); + static_assert(!std::is_same_v, "U must not be an inplace type"); + static_assert(!std::is_same_v, "U must not be nullopt_t type"); + static_assert(std::is_object_v || std::is_reference_v, + "U must be either an objecy or a reference"); /// References now allowed return (has_value()) ? optional{std::invoke(std::forward(f), value_)} : optional{}; } @@ -653,7 +658,7 @@ class optional { /// one. template constexpr T& emplace(Args&&... args) { - static_assert(std::is_constructible_v); + static_assert(std::is_constructible_v, "each parameter pack must be constructible to T"); *this = nullopt; construct(std::forward(args)...); return value(); @@ -675,7 +680,7 @@ class optional { /// valueless. constexpr void swap(optional& rhs) noexcept(std::is_nothrow_move_constructible::value && std::is_nothrow_swappable::value) { - static_assert(std::is_move_constructible_v); + static_assert(std::is_move_constructible_v, "T must be move-constructible"); using std::swap; if (has_value()) { if (rhs.has_value()) { @@ -1138,7 +1143,7 @@ class optional { template constexpr optional or_else(F&& f) const { using U = std::invoke_result_t; - static_assert(std::is_same_v, optional>); + static_assert(std::is_same_v, optional>, "F must return an optional"); return has_value() ? *value_ : std::forward(f)(); } diff --git a/src/beman/optional26/tests/optional.t.cpp b/src/beman/optional26/tests/optional.t.cpp index 3a0ff3f7..ee0c0e71 100644 --- a/src/beman/optional26/tests/optional.t.cpp +++ b/src/beman/optional26/tests/optional.t.cpp @@ -837,7 +837,7 @@ TEST(OptionalTest, HashTest) { EXPECT_EQ(h3, h4); EXPECT_NE(h1, h3); - for(int i : std::views::iota(0, 1000)) { + for (int i : std::views::iota(0, 1000)) { auto h1 = std::hash>{}(i); auto h2 = std::hash{}(i); EXPECT_EQ(h1, h2);