@@ -253,6 +253,75 @@ struct RefQualifiedPredicate {
253253 constexpr bool operator ()(char lhs, char rhs) && noexcept { return lhs == rhs; }
254254};
255255
256+ TEST_CASE (" bool enum text lookup does not convert pointers to true" ) {
257+ static_assert (enum_cast<BoolTest>(" Yay" ) == BoolTest::Yay);
258+ static_assert (enum_cast<const BoolTest&>(" Nay" ) == BoolTest::Nay);
259+ static_assert (!enum_cast<BoolTest>(" INVALID" ).has_value ());
260+ static_assert (!enum_cast<BoolTest>(" " ).has_value ());
261+ static_assert (enum_contains<BoolTest>(" Yay" ));
262+ static_assert (!enum_contains<BoolTest>(" INVALID" ));
263+ static_assert (!enum_contains<BoolTest>(" " ));
264+ static_assert (enum_cast<BoolTest, as_common<>>(" Yay" ) == BoolTest::Yay);
265+ static_assert (enum_cast<BoolTest>(" yay" , case_insensitive) == BoolTest::Yay);
266+ static_assert (enum_cast<BoolTest>(" Yay" , ConstReferencePredicate{}) == BoolTest::Yay);
267+ static_assert (enum_contains<BoolTest>(" Yay" , ConstReferencePredicate{}));
268+ static_assert (noexcept (enum_cast<BoolTest>(" Yay" )));
269+ static_assert (noexcept (enum_contains<BoolTest>(" Yay" )));
270+ static_assert (!noexcept (enum_cast<BoolTest>(" Yay" , ThrowingReferencePredicate{})));
271+
272+ constexpr const char * false_name = " Yay" ;
273+ constexpr const char * invalid_name = " INVALID" ;
274+ static_assert (enum_cast<BoolTest>(false_name) == BoolTest::Yay);
275+ static_assert (!enum_cast<BoolTest>(invalid_name).has_value ());
276+ static_assert (enum_cast<BoolTest>(string_view{" Yay-extra" , 3 }) == BoolTest::Yay);
277+ static_assert (enum_cast<BoolTest>({" Yay-extra" , 3 }) == BoolTest::Yay);
278+
279+ for (const char * name : {" Yay" , " Nay" , " INVALID" , " " , " yay" , " Yay-extra" }) {
280+ const auto expected = enum_cast<BoolTest>(string_view{name});
281+ CHECK (enum_cast<BoolTest>(name) == expected);
282+ CHECK (enum_contains<BoolTest>(name) == expected.has_value ());
283+ const std::string owned{name};
284+ CHECK (enum_cast<BoolTest>(owned) == expected);
285+ CHECK (enum_cast<BoolTest>(std::string{name}) == expected);
286+ CHECK (enum_contains<BoolTest>(owned) == expected.has_value ());
287+ }
288+ char mutable_name[] = " Yay" ;
289+ char * mutable_pointer = mutable_name;
290+ CHECK (enum_cast<BoolTest>(mutable_name) == BoolTest::Yay);
291+ CHECK (enum_cast<BoolTest>(mutable_pointer) == BoolTest::Yay);
292+ CHECK (enum_contains<BoolTest>(mutable_pointer));
293+ CHECK (enum_cast<BoolTest>(false ) == BoolTest::Yay);
294+ CHECK (enum_cast<BoolTest>(true ) == BoolTest::Nay);
295+ CHECK (enum_cast<BoolTest>(0 ) == BoolTest::Yay);
296+ CHECK (enum_cast<BoolTest>(1 ) == BoolTest::Nay);
297+ REQUIRE_THROWS_AS (static_cast <void >(enum_cast<BoolTest>(" Yay" , ThrowingReferencePredicate{})), int );
298+
299+ struct BorrowedName {
300+ BorrowedName () = default ;
301+ BorrowedName (const BorrowedName&) = delete ;
302+ operator string_view () & noexcept { return " Yay" ; }
303+ operator bool () const noexcept { return true ; }
304+ };
305+ BorrowedName borrowed;
306+ CHECK (enum_cast<BoolTest>(borrowed) == BoolTest::Yay);
307+ CHECK (enum_contains<BoolTest>(borrowed));
308+ static_assert (noexcept (enum_cast<BoolTest>(borrowed)));
309+
310+ struct TemporaryName {
311+ operator string_view () && noexcept { return " Yay" ; }
312+ };
313+ CHECK (enum_cast<BoolTest>(TemporaryName{}) == BoolTest::Yay);
314+ CHECK (enum_contains<BoolTest>(TemporaryName{}));
315+
316+ struct ThrowingName {
317+ operator string_view () const { throw 42 ; }
318+ };
319+ static_assert (!noexcept (enum_cast<BoolTest>(ThrowingName{})));
320+ static_assert (!noexcept (enum_contains<BoolTest>(ThrowingName{})));
321+ CHECK_THROWS_AS (static_cast <void >(enum_cast<BoolTest>(ThrowingName{})), int );
322+ CHECK_THROWS_AS (static_cast <void >(enum_contains<BoolTest>(ThrowingName{})), int );
323+ }
324+
256325TEST_CASE (" enum_cast" ) {
257326 SUBCASE (" string" ) {
258327 constexpr auto cr = enum_cast<Color>(" red" );
0 commit comments