diff --git a/regression-tests/mixed-overview-of-is-inspections.cpp2 b/regression-tests/mixed-overview-of-is-inspections.cpp2 new file mode 100644 index 000000000..643a6733f --- /dev/null +++ b/regression-tests/mixed-overview-of-is-inspections.cpp2 @@ -0,0 +1,327 @@ +int* raw_null = nullptr; + +auto expect_throws(auto l) -> bool { + try { + l(); + } catch (...) { + return true; + } + return false; +} + +struct ThrowingConstruction { + constexpr ThrowingConstruction() = default; + ThrowingConstruction(int) { throw 1; } +}; + + +main: () = { + + print_header("type is type"); + { + print(" is A", cpp2::is(), true); + print(" is B", cpp2::is(), false); + print(" is C", cpp2::is(), false); + print(" is A", cpp2::is(), false); + print(" is B", cpp2::is(), true); + print(" is C", cpp2::is(), false); + print(" is A", cpp2::is(), true); + print(" is B", cpp2::is(), false); + print(" is C", cpp2::is(), true); + } + + print_header("type is template"); + { + print("> is std::vector", cpp2::is,std::vector>(), true); + print("> is std::array", cpp2::is,std::array>(), false); + print("> is std::optional", cpp2::is,std::optional>(), false); + print("> is ", cpp2::is,std::vector>(), false); + print("> is ", cpp2::is,std::array>(), true); + print("> is ", cpp2::is,std::optional>(), false); + print("> is ", cpp2::is,std::vector>(), false); + print("> is ", cpp2::is,std::array>(), false); + print("> is ", cpp2::is,std::optional>(), true); + } + + print_header("type is type_trait"); + { + v : std::vector = (); + print("> is std::is_const", cpp2::is,std::is_const>(), true); + print("> is std::is_const", cpp2::is,std::is_const>(), false); + print("&> is std::is_reference", cpp2::is(), true); + } + + print_header("type is concept"); + { + // requires: clang-13+, gcc-12.1+, msvc-v19.34+ + print(" is std::integral", cpp2::is()={}>(), true); + print(" is std::integral", cpp2::is()={}>(), false); + } + + print_header("variable is template"); + { + v : std::vector = (1, 2, 3); + print("v is vector", v is std::vector, true); + print("v is array", v is std::array, false); + print("v is optional", v is std::optional, false); + a : std::array = (4,3,2,1); + print("a is array", a is std::array, true); + print("a is vector", a is std::vector, false); + print("a is optional", a is std::optional, false); + o : std::optional = 42; + print("o is array", o is std::array, false); + print("o is vector", o is std::vector, false); + print("o is optional", o is std::optional, true); + + } + + print_header("variable is type"); + { + a: A = (); + b: B = (); + c: C = (); + print("a is A", a is A, true); + print("b is A", b is A, false); + print("c is A", c is A, true); + } + { + vc: VC = (); + ptr_va0: *VA<0> = vc&; + ptr_va1: *VA<1> = vc&; + cptr_va0: * const VA<0> = vc&; + + print("vc is VA<0>", vc is VA<0>, true); + print("vc is VA<1>", vc is VA<1>, true); + print("vc& is *VA<0>", vc& is *VA<0>, true); + print("vc& is *VA<1>", vc& is *VA<1>, true); + + print("ptr_va0 is *VC", ptr_va0 is *VC, true); + print("ptr_va1 is *VC", ptr_va1 is *VC, true); + print("ptr_va0 is *VA<1>", ptr_va0 is *VA<1>, true); + print("ptr_va1 is *VA<0>", ptr_va1 is *VA<0>, true); + print("cptr_va0 is *VC", cptr_va0 is *VC, false); + print("cptr_va0 is * const VC", cptr_va0 is * const VC, true); + + print("ptr_va0* is VC", ptr_va0* is VC, true); + print("ptr_va1* is VC", ptr_va1* is VC, true); + print("ptr_va0* is VA<1>", ptr_va0* is VA<1>, true); + print("ptr_va1* is VA<0>", ptr_va1* is VA<0>, true); + print("cptr_va0* is VC", cptr_va0* is VC, false); + print("cptr_va0* is const VC", cptr_va0* is const VC, true); + } + + print_header("pointer-like variable is empty"); + { + print("raw_null is empty", raw_null is cpp2::empty, true); + print("nullptr is empty", nullptr is cpp2::empty, true); + print("shared_ptr() is empty", std::shared_ptr() is cpp2::empty, true); + print("unique_ptr() is empty", std::unique_ptr() is cpp2::empty, true); + + i := 42; + print("i& is empty", i& is cpp2::empty, false); + print("std::make_shared(42) is empty", std::make_shared(42) is cpp2::empty, false); + print("std::make_unique(44) is empty", std::make_unique(44) is cpp2::empty, false); + } + + print_header("variable is value"); + { + i := 42; + print("i{42} is empty", i is cpp2::empty, false); + print("i{42} is 24", i is 24, false); + print("i{42} is 42", i is 42, true); + print("i{42} is 42u", i is 42u, true); + print("i{42} is 42L", i is 42L, true); + print("i{42} is 42.0", i is 42.0, true); + print("i{42} is 42.0f", i is 42.0f, true); + print("3.14f is 3.14", 3.14f is 3.14, false); + close_to := :(v) -> _ = :(x) -> bool = { + return std::abs(v$ - x) < std::max,std::decay_t>>(std::numeric_limits>::epsilon(), std::numeric_limits>::epsilon()); + }; + print("3.14f is (close_to(3.14 ))", 3.14f is (close_to(3.14 )), true); + print("3.14 is (close_to(3.14f))", 3.14 is (close_to(3.14f)), true); + } + + print_header("variable is type_trait"); + { + i : int = 42; + ci : const int = 24; + + print("i{int} is std::is_const", i is std::is_const, false); + print("ci{const int} is std::is_const", ci is std::is_const, true); + print("ci{const int} is std::is_integral", ci is std::is_integral, true); + print("ci{const int} is std::is_floating_point", ci is std::is_floating_point, false); + } + + print_header("variable is predicate"); + { + d := 3.14; + + print("d{3.14} is (:(x) -> bool = x>0;)", d is (:(x) -> bool = x>0;), true); + print("d{3.14} is (:(x:int) -> bool = x>0;)", d is (:(x:int) -> bool = x>0;), false); + print("d{3.14} is (:(x:std::string) -> bool = x.ssize()>5;)", d is (:(x:std::string) -> bool = x.ssize()>5;), false); + print("std::string(\"abcdefg\") is (:(x:std::string) -> bool = x.ssize()>5;)", std::string("abcdefg") is (:(x:std::string) -> bool = x.ssize()>5;), true); + + print("d{3.14} is (pred_i)", d is (pred_i), false); + print("d{3.14} is (pred_d)", d is (pred_d), true); + print("d{3.14} is (pred_)", true, true); + + print("d{3.14} is (: () -> _ = true;)", d is (: () -> _ = true;), true); + print("d{3.14} is (: () = {})", d is (: () = {}), true); + print("d{3.14} is (: () = {})", d is (: () = {}), false); + } + + print_header("variant variable is value"); + { + v : std::variant> = (42); + + print("v{42} is 42", v is 42, true); + print("v{42} is int", v is int, true); + print("v{42} is int", v is double, false); + print("v{42} is 42.0", v is 42.0, true); + print("v{42} is 24", v is 24, false); + print("v{42} is (std::string(\"hello\"))", v is (std::string("hello")), false); + print("v{42} is std::integral", v is (: () = {}), true); + print("v{42} is std::floating_point", v is (: () = {}), false); + + v = std::string("hello"); + print("v{hello} is (std::string(\"hello\"))", v is (std::string("hello")), true); + print("v{hello} is 42", v is 42, false); + print("v{hello} is empty", v is cpp2::empty, false); + print("v{hello} is int", v is int, false); + print("v{hello} is std::string", v is std::string, true); + + v = :std::vector = (1,2,3,4); + print("v{std::vector{1,2,3,4}} is std::vector", v is std::vector, true ); + print("v{std::vector{1,2,3,4}} is std::vector", v is std::vector, true ); + print("v{std::vector{1,2,3,4}} is std::map", v is std::map, false); + print("v{std::vector{1,2,3,4}} is std::variant", v is std::variant, true ); + } + + print_header("variant variable is empty"); + { + v : std::variant = (); + print("v{int} is empty", v is cpp2::empty, false, "v contains default value of first type"); + + v = std::monostate(); + print("v{monostate} is empty", v is cpp2::empty, true); + + expect_throws(:() = v&$*.emplace<1>(42);); + print("v{valueless_by_exception} is empty", v is cpp2::empty, true, "is valueless: " + cpp2::to_string(v.valueless_by_exception())); + + } + + print_header("any variable is type"); + { + a : std::any = 42; + + print("a{42} is int", a is int, true); + print("a{42} is double", a is double, false); + print("a{42} is empty", a is cpp2::empty, false); + + print("std::any() is empty", std::any() is cpp2::empty, true); + } + + print_header("any variable is value"); + { + a : std::any = 42; + + print("a{42} is 42", a is 42, true); + print("a{42} is 24", a is 24, false); + print("a{42} is 42L", a is 42L, false); + print("std::any(3.14) is 3", std::any(3.14) is 3, false); + + print("a{42} is :(v)->bool = v.has_value();", a is :(v)->bool = v.has_value();, true); + print("a{42} is :(v:std::any)->bool = v.has_value();", a is :(v:std::any)->bool = v.has_value();, true); + print("a{42} is :(v:int)->bool = v>0;", a is :(v:int)->bool = v>0;, true); + } + + print_header("optional variable is type"); + { + o : std::optional = 42; + + print("o{42} is int", o is int, true); + print("o{42} is empty", o is cpp2::empty, false); + print("std::optional() is empty", std::optional() is cpp2::empty, true); + } + + print_header("optional variable is value"); + { + o : std::optional = 42; + + print("o{42} is 42", o is 42, true); + print("o{42} is 24", o is 24, false); + print("o{42} is 42.0", o is 42.0, true); + + print("o{42} is :(v) -> bool = v > 0;", o is :(v) -> bool = v > 0;, true); + print("o{42} is :(v:std::optional) -> bool = v > 0;", o is :(v:std::optional) -> bool = v > 0;, true); + print("o{42} is :(v:std::optional) -> bool = v > 0;", o is :(v:std::optional) -> bool = v > 0;, true); + print("std::optional(3.14) is :(v:std::optional) -> bool = v == 3;", std::optional(3.14) is :(v:std::optional) -> bool = v* == 3;, false); + } + +} + +A: type = {} +B: type = {} +C: type = { + this: A = (); +} + +VA: @polymorphic_base type = {} + +VC: type = { + this: VA<0>; + this: VA<1>; +} + + +pred_i: (x : int ) -> bool = { + return x > 0; +} + +pred_d: (x : double ) -> bool = { + return x > 0; +} + +pred_: (x) -> bool = { + return x > 0; +} + +col : std::array = (70, 8, 8, 8, 40); + +print: (what, value, expected, comment) = { + l := :(value) -> std::string = { + if value { + return "true"; + } else { + return "false"; + } + }; + print(what, l(value), l(expected), inspect (value == expected) -> std::string { is (true) = "OK"; is _ = "FAILED!";}, comment ); +} + +print: (what, value, expected) = { + print(what, value, expected, std::string()); +} + +print: (what, value, expected, result, comment) = { + std::cout << "|" << std::setw(col[0]) << std::right << what; + std::cout << "|" << std::setw(col[1]) << std::internal << value; + std::cout << "|" << std::setw(col[2]) << std::internal << expected; + std::cout << "|" << std::setw(col[3]) << std::internal << result; + std::cout << "|" << std::setw(col[4]) << std::left << std::setprecision(20) << comment; + std::cout << "|" << std::endl; +} + +print_header: (title) = { + std::cout << "\n# (title)$\n\n"; + print("Test", "Actual", "Expected", "Result", "Comment"); + print( std::string(col[0]-1,'-')+":" + , ":"+std::string(col[1]-2,'-')+":" + , ":"+std::string(col[2]-2,'-')+":" + , ":"+std::string(col[3]-2,'-')+":" + , ":"+std::string(col[4]-1,'-') + ); +} + +#include +#include diff --git a/regression-tests/test-results/apple-clang-14/mixed-overview-of-is-inspections.cpp.execution b/regression-tests/test-results/apple-clang-14/mixed-overview-of-is-inspections.cpp.execution new file mode 100644 index 000000000..1e459cc74 --- /dev/null +++ b/regression-tests/test-results/apple-clang-14/mixed-overview-of-is-inspections.cpp.execution @@ -0,0 +1,203 @@ + +# type is type + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| is A| true| true| OK| | +| is B| false| false| OK| | +| is C| false| false| OK| | +| is A| false| false| OK| | +| is B| true| true| OK| | +| is C| false| false| OK| | +| is A| true| true| OK| | +| is B| false| false| OK| | +| is C| true| true| OK| | + +# type is template + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| > is std::vector| true| true| OK| | +| > is std::array| false| false| OK| | +| > is std::optional| false| false| OK| | +| > is | false| false| OK| | +| > is | true| true| OK| | +| > is | false| false| OK| | +| > is | false| false| OK| | +| > is | false| false| OK| | +| > is | true| true| OK| | + +# type is type_trait + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| > is std::is_const| true| true| OK| | +| > is std::is_const| false| false| OK| | +| &> is std::is_reference| true| true| OK| | + +# type is concept + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| is std::integral| true| true| OK| | +| is std::integral| false| false| OK| | + +# variable is template + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| v is vector| true| true| OK| | +| v is array| false| false| OK| | +| v is optional| false| false| OK| | +| a is array| true| true| OK| | +| a is vector| false| false| OK| | +| a is optional| false| false| OK| | +| o is array| false| false| OK| | +| o is vector| false| false| OK| | +| o is optional| true| true| OK| | + +# variable is type + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| a is A| true| true| OK| | +| b is A| false| false| OK| | +| c is A| true| true| OK| | +| vc is VA<0>| true| true| OK| | +| vc is VA<1>| true| true| OK| | +| vc& is *VA<0>| true| true| OK| | +| vc& is *VA<1>| true| true| OK| | +| ptr_va0 is *VC| true| true| OK| | +| ptr_va1 is *VC| true| true| OK| | +| ptr_va0 is *VA<1>| true| true| OK| | +| ptr_va1 is *VA<0>| true| true| OK| | +| cptr_va0 is *VC| false| false| OK| | +| cptr_va0 is * const VC| true| true| OK| | +| ptr_va0* is VC| true| true| OK| | +| ptr_va1* is VC| true| true| OK| | +| ptr_va0* is VA<1>| true| true| OK| | +| ptr_va1* is VA<0>| true| true| OK| | +| cptr_va0* is VC| false| false| OK| | +| cptr_va0* is const VC| true| true| OK| | + +# pointer-like variable is empty + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| raw_null is empty| true| true| OK| | +| nullptr is empty| true| true| OK| | +| shared_ptr() is empty| true| true| OK| | +| unique_ptr() is empty| true| true| OK| | +| i& is empty| false| false| OK| | +| std::make_shared(42) is empty| false| false| OK| | +| std::make_unique(44) is empty| false| false| OK| | + +# variable is value + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| i{42} is empty| false| false| OK| | +| i{42} is 24| false| false| OK| | +| i{42} is 42| true| true| OK| | +| i{42} is 42u| true| true| OK| | +| i{42} is 42L| true| true| OK| | +| i{42} is 42.0| true| true| OK| | +| i{42} is 42.0f| true| true| OK| | +| 3.14f is 3.14| false| false| OK| | +| 3.14f is (close_to(3.14 ))| true| true| OK| | +| 3.14 is (close_to(3.14f))| true| true| OK| | + +# variable is type_trait + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| i{int} is std::is_const| false| false| OK| | +| ci{const int} is std::is_const| true| true| OK| | +| ci{const int} is std::is_integral| true| true| OK| | +| ci{const int} is std::is_floating_point| false| false| OK| | + +# variable is predicate + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| d{3.14} is (:(x) -> bool = x>0;)| true| true| OK| | +| d{3.14} is (:(x:int) -> bool = x>0;)| false| false| OK| | +| d{3.14} is (:(x:std::string) -> bool = x.ssize()>5;)| false| false| OK| | +| std::string("abcdefg") is (:(x:std::string) -> bool = x.ssize()>5;)| true| true| OK| | +| d{3.14} is (pred_i)| false| false| OK| | +| d{3.14} is (pred_d)| true| true| OK| | +| d{3.14} is (pred_)| true| true| OK| | +| d{3.14} is (: () -> _ = true;)| true| true| OK| | +| d{3.14} is (: () = {})| true| true| OK| | +| d{3.14} is (: () = {})| false| false| OK| | + +# variant variable is value + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| v{42} is 42| true| true| OK| | +| v{42} is int| true| true| OK| | +| v{42} is int| false| false| OK| | +| v{42} is 42.0| true| true| OK| | +| v{42} is 24| false| false| OK| | +| v{42} is (std::string("hello"))| false| false| OK| | +| v{42} is std::integral| true| true| OK| | +| v{42} is std::floating_point| false| false| OK| | +| v{hello} is (std::string("hello"))| true| true| OK| | +| v{hello} is 42| false| false| OK| | +| v{hello} is empty| false| false| OK| | +| v{hello} is int| false| false| OK| | +| v{hello} is std::string| true| true| OK| | +| v{std::vector{1,2,3,4}} is std::vector| true| true| OK| | +| v{std::vector{1,2,3,4}} is std::vector| true| true| OK| | +| v{std::vector{1,2,3,4}} is std::map| false| false| OK| | +| v{std::vector{1,2,3,4}} is std::variant| true| true| OK| | + +# variant variable is empty + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| v{int} is empty| false| false| OK|v contains default value of first type | +| v{monostate} is empty| true| true| OK| | +| v{valueless_by_exception} is empty| true| true| OK|is valueless: true | + +# any variable is type + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| a{42} is int| true| true| OK| | +| a{42} is double| false| false| OK| | +| a{42} is empty| false| false| OK| | +| std::any() is empty| true| true| OK| | + +# any variable is value + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| a{42} is 42| true| true| OK| | +| a{42} is 24| false| false| OK| | +| a{42} is 42L| false| false| OK| | +| std::any(3.14) is 3| false| false| OK| | +| a{42} is :(v)->bool = v.has_value();| true| true| OK| | +| a{42} is :(v:std::any)->bool = v.has_value();| true| true| OK| | +| a{42} is :(v:int)->bool = v>0;| true| true| OK| | + +# optional variable is type + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| o{42} is int| true| true| OK| | +| o{42} is empty| false| false| OK| | +| std::optional() is empty| true| true| OK| | + +# optional variable is value + +| Test| Actual|Expected| Result|Comment | +|---------------------------------------------------------------------:|:------:|:------:|:------:|:---------------------------------------| +| o{42} is 42| true| true| OK| | +| o{42} is 24| false| false| OK| | +| o{42} is 42.0| true| true| OK| | +| o{42} is :(v) -> bool = v > 0;| true| true| OK| | +| o{42} is :(v:std::optional) -> bool = v > 0;| true| true| OK| | +| o{42} is :(v:std::optional) -> bool = v > 0;| true| true| OK| | +| std::optional(3.14) is :(v:std::optional) -> bool = v == 3;| false| false| OK| | diff --git a/regression-tests/test-results/apple-clang-14/mixed-overview-of-is-inspections.cpp.output b/regression-tests/test-results/apple-clang-14/mixed-overview-of-is-inspections.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/mixed-overview-of-is-inspections.cpp b/regression-tests/test-results/mixed-overview-of-is-inspections.cpp new file mode 100644 index 000000000..7577ef7ca --- /dev/null +++ b/regression-tests/test-results/mixed-overview-of-is-inspections.cpp @@ -0,0 +1,419 @@ + + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "mixed-overview-of-is-inspections.cpp2" + +#line 263 "mixed-overview-of-is-inspections.cpp2" +class A; +class B; +class C; + + +#line 269 "mixed-overview-of-is-inspections.cpp2" +template class VA; + +class VC; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "mixed-overview-of-is-inspections.cpp2" +int* raw_null = nullptr; + +auto expect_throws(auto l) -> bool { + try { + l(); + } catch (...) { + return true; + } + return false; +} + +struct ThrowingConstruction { + constexpr ThrowingConstruction() = default; + ThrowingConstruction(int) { throw 1; } +}; + +#line 18 "mixed-overview-of-is-inspections.cpp2" +auto main() -> int; + +#line 263 "mixed-overview-of-is-inspections.cpp2" +class A { + public: A() = default; + public: A(A const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(A const&) -> void = delete; +}; +#line 264 "mixed-overview-of-is-inspections.cpp2" +class B { + public: B() = default; + public: B(B const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(B const&) -> void = delete; +}; +#line 265 "mixed-overview-of-is-inspections.cpp2" +class C: public A { + public: C() = default; + public: C(C const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(C const&) -> void = delete; + + +#line 267 "mixed-overview-of-is-inspections.cpp2" +}; + +template class VA { +public: virtual ~VA() noexcept; + + public: VA() = default; + public: VA(VA const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(VA const&) -> void = delete; +}; +#line 270 "mixed-overview-of-is-inspections.cpp2" + +class VC: public VA<0>, public VA<1> { + public: VC() = default; + public: VC(VC const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(VC const&) -> void = delete; + + +#line 274 "mixed-overview-of-is-inspections.cpp2" +}; + +#line 277 "mixed-overview-of-is-inspections.cpp2" +[[nodiscard]] auto pred_i(cpp2::in x) -> bool; + +#line 281 "mixed-overview-of-is-inspections.cpp2" +[[nodiscard]] auto pred_d(cpp2::in x) -> bool; + +#line 285 "mixed-overview-of-is-inspections.cpp2" +[[nodiscard]] auto pred_(auto const& x) -> bool; + +#line 289 "mixed-overview-of-is-inspections.cpp2" +extern std::array col; + +auto print(auto const& what, auto const& value, auto const& expected, auto const& comment) -> void; + +#line 302 "mixed-overview-of-is-inspections.cpp2" +auto print(auto const& what, auto const& value, auto const& expected) -> void; + +#line 306 "mixed-overview-of-is-inspections.cpp2" +auto print(auto const& what, auto const& value, auto const& expected, auto const& result, auto const& comment) -> void; + +#line 315 "mixed-overview-of-is-inspections.cpp2" +auto print_header(auto const& title) -> void; +#line 325 "mixed-overview-of-is-inspections.cpp2" + +#include +#include + + +//=== Cpp2 function definitions ================================================= + +#line 1 "mixed-overview-of-is-inspections.cpp2" + +#line 18 "mixed-overview-of-is-inspections.cpp2" +auto main() -> int{ + + print_header("type is type"); + { + print(" is A", cpp2::is(), true); + print(" is B", cpp2::is(), false); + print(" is C", cpp2::is(), false); + print(" is A", cpp2::is(), false); + print(" is B", cpp2::is(), true); + print(" is C", cpp2::is(), false); + print(" is A", cpp2::is(), true); + print(" is B", cpp2::is(), false); + print(" is C", cpp2::is(), true); + } + + print_header("type is template"); + { + print("> is std::vector", cpp2::is,std::vector>(), true); + print("> is std::array", cpp2::is,std::array>(), false); + print("> is std::optional", cpp2::is,std::optional>(), false); + print("> is ", cpp2::is,std::vector>(), false); + print("> is ", cpp2::is,std::array>(), true); + print("> is ", cpp2::is,std::optional>(), false); + print("> is ", cpp2::is,std::vector>(), false); + print("> is ", cpp2::is,std::array>(), false); + print("> is ", cpp2::is,std::optional>(), true); + } + + print_header("type is type_trait"); + { + std::vector v {}; + print("> is std::is_const", cpp2::is const,std::is_const>(), true); + print("> is std::is_const", cpp2::is,std::is_const>(), false); + print("&> is std::is_reference", cpp2::is(), true); + } + + print_header("type is concept"); + { + // requires: clang-13+, gcc-12.1+, msvc-v19.34+ + print(" is std::integral", cpp2::is() mutable -> void{}>(), true); + print(" is std::integral", cpp2::is() mutable -> void{}>(), false); + } + + print_header("variable is template"); + { + std::vector v {1, 2, 3}; + print("v is vector", cpp2::is(v), true); + print("v is array", cpp2::is(v), false); + print("v is optional", cpp2::is(std::move(v)), false); + std::array a {4, 3, 2, 1}; + print("a is array", cpp2::is(a), true); + print("a is vector", cpp2::is(a), false); + print("a is optional", cpp2::is(std::move(a)), false); + std::optional o {42}; + print("o is array", cpp2::is(o), false); + print("o is vector", cpp2::is(o), false); + print("o is optional", cpp2::is(std::move(o)), true); + + } + + print_header("variable is type"); + { + A a {}; + B b {}; + C c {}; + print("a is A", cpp2::is(std::move(a)), true); + print("b is A", cpp2::is(std::move(b)), false); + print("c is A", cpp2::is(std::move(c)), true); + } + { + VC vc {}; + VA<0>* ptr_va0 {&vc}; + VA<1>* ptr_va1 {&vc}; + VA<0> const* cptr_va0 {&vc}; + + print("vc is VA<0>", cpp2::is>(vc), true); + print("vc is VA<1>", cpp2::is>(vc), true); + print("vc& is *VA<0>", cpp2::is*>(&vc), true); + print("vc& is *VA<1>", cpp2::is*>(&vc), true); + + print("ptr_va0 is *VC", cpp2::is(ptr_va0), true); + print("ptr_va1 is *VC", cpp2::is(ptr_va1), true); + print("ptr_va0 is *VA<1>", cpp2::is*>(ptr_va0), true); + print("ptr_va1 is *VA<0>", cpp2::is*>(ptr_va1), true); + print("cptr_va0 is *VC", cpp2::is(cptr_va0), false); + print("cptr_va0 is * const VC", cpp2::is(cptr_va0), true); + + print("ptr_va0* is VC", cpp2::is(*cpp2::assert_not_null(ptr_va0)), true); + print("ptr_va1* is VC", cpp2::is(*cpp2::assert_not_null(ptr_va1)), true); + print("ptr_va0* is VA<1>", cpp2::is>(*cpp2::assert_not_null(std::move(ptr_va0))), true); + print("ptr_va1* is VA<0>", cpp2::is>(*cpp2::assert_not_null(std::move(ptr_va1))), true); + print("cptr_va0* is VC", cpp2::is(*cpp2::assert_not_null(cptr_va0)), false); + print("cptr_va0* is const VC", cpp2::is(*cpp2::assert_not_null(std::move(cptr_va0))), true); + } + + print_header("pointer-like variable is empty"); + { + print("raw_null is empty", cpp2::is(raw_null), true); + print("nullptr is empty", cpp2::is(nullptr), true); + print("shared_ptr() is empty", cpp2::is(std::shared_ptr()), true); + print("unique_ptr() is empty", cpp2::is(std::unique_ptr()), true); + + auto i {42}; + print("i& is empty", cpp2::is(&i), false); + print("std::make_shared(42) is empty", cpp2::is(std::make_shared(42)), false); + print("std::make_unique(44) is empty", cpp2::is(std::make_unique(44)), false); + } + + print_header("variable is value"); + { + auto i {42}; + print("i{42} is empty", cpp2::is(i), false); + print("i{42} is 24", cpp2::is(i, 24), false); + print("i{42} is 42", cpp2::is(i, 42), true); + print("i{42} is 42u", cpp2::is(i, 42u), true); + print("i{42} is 42L", cpp2::is(i, 42L), true); + print("i{42} is 42.0", cpp2::is(i, 42.0), true); + print("i{42} is 42.0f", cpp2::is(std::move(i), 42.0f), true); + print("3.14f is 3.14", cpp2::is(3.14f, 3.14), false); + auto close_to {[](auto const& v) mutable -> auto { return [_0 = v](auto const& x) mutable -> bool{ + return cpp2::cmp_less(std::abs(_0 - x),std::max,std::decay_t>>(std::numeric_limits>::epsilon(), std::numeric_limits>::epsilon())); + }; }}; + print("3.14f is (close_to(3.14 ))", cpp2::is(3.14f, (close_to(3.14))), true); + print("3.14 is (close_to(3.14f))", cpp2::is(3.14, (std::move(close_to)(3.14f))), true); + } + + print_header("variable is type_trait"); + { + int i {42}; + int const ci {24}; + + print("i{int} is std::is_const", cpp2::is(std::move(i)), false); + print("ci{const int} is std::is_const", cpp2::is(ci), true); + print("ci{const int} is std::is_integral", cpp2::is(ci), true); + print("ci{const int} is std::is_floating_point", cpp2::is(std::move(ci)), false); + } + + print_header("variable is predicate"); + { + auto d {3.14}; + + print("d{3.14} is (:(x) -> bool = x>0;)", cpp2::is(d, ([](auto const& x) mutable -> bool { return cpp2::cmp_greater(x,0); })), true); + print("d{3.14} is (:(x:int) -> bool = x>0;)", cpp2::is(d, ([](cpp2::in x) mutable -> bool { return cpp2::cmp_greater(x,0); })), false); + print("d{3.14} is (:(x:std::string) -> bool = x.ssize()>5;)", cpp2::is(d, ([](cpp2::in x) mutable -> bool { return cpp2::cmp_greater(CPP2_UFCS(ssize)(x),5); })), false); + print("std::string(\"abcdefg\") is (:(x:std::string) -> bool = x.ssize()>5;)", cpp2::is(std::string("abcdefg"), ([](cpp2::in x) mutable -> bool { return cpp2::cmp_greater(CPP2_UFCS(ssize)(x),5); })), true); + + print("d{3.14} is (pred_i)", cpp2::is(d, (pred_i)), false); + print("d{3.14} is (pred_d)", cpp2::is(d, (pred_d)), true); + print("d{3.14} is (pred_)", true, true); + + print("d{3.14} is (: () -> _ = true;)", cpp2::is(d, ([]() mutable -> auto { return true; })), true); + print("d{3.14} is (: () = {})", cpp2::is(d, ([]() mutable -> void{})), true); + print("d{3.14} is (: () = {})", cpp2::is(std::move(d), ([]() mutable -> void{})), false); + } + + print_header("variant variable is value"); + { + std::variant> v {42}; + + print("v{42} is 42", cpp2::is(v, 42), true); + print("v{42} is int", cpp2::is(v), true); + print("v{42} is int", cpp2::is(v), false); + print("v{42} is 42.0", cpp2::is(v, 42.0), true); + print("v{42} is 24", cpp2::is(v, 24), false); + print("v{42} is (std::string(\"hello\"))", cpp2::is(v, (std::string("hello"))), false); + print("v{42} is std::integral", cpp2::is(v, ([]() mutable -> void{})), true); + print("v{42} is std::floating_point", cpp2::is(v, ([]() mutable -> void{})), false); + + v = std::string("hello"); + print("v{hello} is (std::string(\"hello\"))", cpp2::is(v, (std::string("hello"))), true); + print("v{hello} is 42", cpp2::is(v, 42), false); + print("v{hello} is empty", cpp2::is(v), false); + print("v{hello} is int", cpp2::is(v), false); + print("v{hello} is std::string", cpp2::is(v), true); + + v = std::vector{1, 2, 3, 4}; + print("v{std::vector{1,2,3,4}} is std::vector", cpp2::is>(v), true); + print("v{std::vector{1,2,3,4}} is std::vector", cpp2::is(v), true); + print("v{std::vector{1,2,3,4}} is std::map", cpp2::is(v), false); + print("v{std::vector{1,2,3,4}} is std::variant", cpp2::is(std::move(v)), true); + } + + print_header("variant variable is empty"); + { + std::variant v {}; + print("v{int} is empty", cpp2::is(v), false, "v contains default value of first type"); + + v = std::monostate(); + print("v{monostate} is empty", cpp2::is(v), true); + + expect_throws([_0 = (&v)]() mutable -> void { CPP2_UFCS_TEMPLATE(emplace<1>)((*cpp2::assert_not_null(_0)), 42); }); + print("v{valueless_by_exception} is empty", cpp2::is(v), true, "is valueless: " + cpp2::to_string(CPP2_UFCS(valueless_by_exception)(std::move(v)))); + + } + + print_header("any variable is type"); + { + std::any a {42}; + + print("a{42} is int", cpp2::is(a), true); + print("a{42} is double", cpp2::is(a), false); + print("a{42} is empty", cpp2::is(std::move(a)), false); + + print("std::any() is empty", cpp2::is(std::any()), true); + } + + print_header("any variable is value"); + { + std::any a {42}; + + print("a{42} is 42", cpp2::is(a, 42), true); + print("a{42} is 24", cpp2::is(a, 24), false); + print("a{42} is 42L", cpp2::is(a, 42L), false); + print("std::any(3.14) is 3", cpp2::is(std::any(3.14), 3), false); + + print("a{42} is :(v)->bool = v.has_value();", cpp2::is(a, [](auto const& v) mutable -> bool { return CPP2_UFCS(has_value)(v); }), true); + print("a{42} is :(v:std::any)->bool = v.has_value();", cpp2::is(a, [](cpp2::in v) mutable -> bool { return CPP2_UFCS(has_value)(v); }), true); + print("a{42} is :(v:int)->bool = v>0;", cpp2::is(std::move(a), [](cpp2::in v) mutable -> bool { return cpp2::cmp_greater(v,0); }), true); + } + + print_header("optional variable is type"); + { + std::optional o {42}; + + print("o{42} is int", cpp2::is(o), true); + print("o{42} is empty", cpp2::is(std::move(o)), false); + print("std::optional() is empty", cpp2::is(std::optional()), true); + } + + print_header("optional variable is value"); + { + std::optional o {42}; + + print("o{42} is 42", cpp2::is(o, 42), true); + print("o{42} is 24", cpp2::is(o, 24), false); + print("o{42} is 42.0", cpp2::is(o, 42.0), true); + + print("o{42} is :(v) -> bool = v > 0;", cpp2::is(o, [](auto const& v) mutable -> bool { return cpp2::cmp_greater(v,0); }), true); + print("o{42} is :(v:std::optional) -> bool = v > 0;", cpp2::is(o, [](cpp2::in> v) mutable -> bool { return cpp2::cmp_greater(v,0); }), true); + print("o{42} is :(v:std::optional) -> bool = v > 0;", cpp2::is(std::move(o), [](cpp2::in> v) mutable -> bool { return cpp2::cmp_greater(v,0); }), true); + print("std::optional(3.14) is :(v:std::optional) -> bool = v == 3;", cpp2::is(std::optional(3.14), [](cpp2::in> v) mutable -> bool { return *cpp2::assert_not_null(v) == 3; }), false); + } + +} + +template VA::~VA() noexcept{} + +#line 277 "mixed-overview-of-is-inspections.cpp2" +[[nodiscard]] auto pred_i(cpp2::in x) -> bool{ + return cpp2::cmp_greater(x,0); +} + +#line 281 "mixed-overview-of-is-inspections.cpp2" +[[nodiscard]] auto pred_d(cpp2::in x) -> bool{ + return cpp2::cmp_greater(x,0); +} + +#line 285 "mixed-overview-of-is-inspections.cpp2" +[[nodiscard]] auto pred_(auto const& x) -> bool{ + return cpp2::cmp_greater(x,0); +} + +std::array col {70, 8, 8, 8, 40}; + +#line 291 "mixed-overview-of-is-inspections.cpp2" +auto print(auto const& what, auto const& value, auto const& expected, auto const& comment) -> void{ + auto l {[](auto const& value) mutable -> std::string{ + if (value) { + return "true"; + }else { + return "false"; + } + }}; + print(what, l(value), std::move(l)(expected), [&] () -> std::string { auto&& _expr = (value == expected); if (cpp2::is(_expr, (true))) { if constexpr( requires{"OK";} ) if constexpr( std::is_convertible_v ) return "OK"; else return std::string{}; else return std::string{}; }else return "FAILED!"; }(), comment); +} + +#line 302 "mixed-overview-of-is-inspections.cpp2" +auto print(auto const& what, auto const& value, auto const& expected) -> void{ + print(what, value, expected, std::string()); +} + +#line 306 "mixed-overview-of-is-inspections.cpp2" +auto print(auto const& what, auto const& value, auto const& expected, auto const& result, auto const& comment) -> void{ + std::cout << "|" << std::setw(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 0)) << std::right << what; + std::cout << "|" << std::setw(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 1)) << std::internal << value; + std::cout << "|" << std::setw(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 2)) << std::internal << expected; + std::cout << "|" << std::setw(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 3)) << std::internal << result; + std::cout << "|" << std::setw(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 4)) << std::left << std::setprecision(20) << comment; + std::cout << "|" << std::endl; +} + +#line 315 "mixed-overview-of-is-inspections.cpp2" +auto print_header(auto const& title) -> void{ + std::cout << ("\n# " + cpp2::to_string(title) + "\n\n"); + print("Test", "Actual", "Expected", "Result", "Comment"); + print( std::string(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 0) - 1, '-') + ":", + ":" + std::string(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 1) - 2, '-') + ":", + ":" + std::string(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 2) - 2, '-') + ":", + ":" + std::string(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 3) - 2, '-') + ":", + ":" + std::string(CPP2_ASSERT_IN_BOUNDS_LITERAL(col, 4) - 1, '-') + ); +} + diff --git a/regression-tests/test-results/mixed-overview-of-is-inspections.cpp2.output b/regression-tests/test-results/mixed-overview-of-is-inspections.cpp2.output new file mode 100644 index 000000000..257defc33 --- /dev/null +++ b/regression-tests/test-results/mixed-overview-of-is-inspections.cpp2.output @@ -0,0 +1,2 @@ +mixed-overview-of-is-inspections.cpp2... ok (mixed Cpp1/Cpp2, Cpp2 code passes safety checks) +