diff --git a/include/cpp2util.h b/include/cpp2util.h index 2cb9ee1a8f..553f52e68a 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -894,6 +894,12 @@ inline constexpr auto is( auto const& x, auto const& value ) -> bool return false; } +// Free function predicate case +template< typename X > +constexpr auto is( X const& x, bool (&value)(X const&) ) -> bool +{ + return value(x); +} //------------------------------------------------------------------------------------------------------------- // Built-in as diff --git a/regression-tests/mixed-inspect-values-2.cpp2 b/regression-tests/mixed-inspect-values-2.cpp2 index ed250e52b0..e3e961dbb7 100644 --- a/regression-tests/mixed-inspect-values-2.cpp2 +++ b/regression-tests/mixed-inspect-values-2.cpp2 @@ -16,6 +16,10 @@ constexpr auto empty = [](auto&& x){ return std::empty(x); }; +auto negative(auto v) { + return v < 0; +} + main: () -> int = { i := 15; @@ -33,6 +37,12 @@ main: () -> int = { std::cout << "i is between 10 and 30" << std::endl; } + if i is (negative) { + std::cout << "i is negative" << std::endl; + } else { + std::cout << "i is not negative" << std::endl; + } + v : std::vector = (); if empty(v) { diff --git a/regression-tests/test-results/apple-clang-14/mixed-inspect-values-2.cpp.execution b/regression-tests/test-results/apple-clang-14/mixed-inspect-values-2.cpp.execution index 8372eadcae..43ab3e654f 100644 --- a/regression-tests/test-results/apple-clang-14/mixed-inspect-values-2.cpp.execution +++ b/regression-tests/test-results/apple-clang-14/mixed-inspect-values-2.cpp.execution @@ -1,5 +1,6 @@ i is between 11 and 20 less than 20 i is between 10 and 30 +i is not negative v is empty v is empty diff --git a/regression-tests/test-results/clang-12/mixed-inspect-values-2.cpp.execution b/regression-tests/test-results/clang-12/mixed-inspect-values-2.cpp.execution index 8372eadcae..43ab3e654f 100644 --- a/regression-tests/test-results/clang-12/mixed-inspect-values-2.cpp.execution +++ b/regression-tests/test-results/clang-12/mixed-inspect-values-2.cpp.execution @@ -1,5 +1,6 @@ i is between 11 and 20 less than 20 i is between 10 and 30 +i is not negative v is empty v is empty diff --git a/regression-tests/test-results/mixed-inspect-values-2.cpp b/regression-tests/test-results/mixed-inspect-values-2.cpp index 4b2cde6324..1f07be423f 100644 --- a/regression-tests/test-results/mixed-inspect-values-2.cpp +++ b/regression-tests/test-results/mixed-inspect-values-2.cpp @@ -27,14 +27,18 @@ constexpr auto empty = [](auto&& x){ return std::empty(x); }; -#line 19 "mixed-inspect-values-2.cpp2" +auto negative(auto v) { + return v < 0; +} + +#line 23 "mixed-inspect-values-2.cpp2" [[nodiscard]] auto main() -> int; //=== Cpp2 function definitions ================================================= -#line 19 "mixed-inspect-values-2.cpp2" +#line 23 "mixed-inspect-values-2.cpp2" [[nodiscard]] auto main() -> int{ auto i {15}; @@ -48,10 +52,16 @@ constexpr auto empty = [](auto&& x){ std::cout << "less than 20" << std::endl; } - if (cpp2::is(std::move(i), (in(10, 30)))) { + if (cpp2::is(i, (in(10, 30)))) { std::cout << "i is between 10 and 30" << std::endl; } + if (cpp2::is(std::move(i), (negative))) { + std::cout << "i is negative" << std::endl; + }else { + std::cout << "i is not negative" << std::endl; + } + std::vector v {}; if (empty(v)) {