| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #include "test.h" | 
| 2 |  |  |  |  |  |  | #include | 
| 3 |  |  |  |  |  |  | #include | 
| 4 |  |  |  |  |  |  | #include | 
| 5 |  |  |  |  |  |  | #include | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | using panda::function; | 
| 8 |  |  |  |  |  |  | using panda::make_function; | 
| 9 |  |  |  |  |  |  | using panda::iptr; | 
| 10 |  |  |  |  |  |  | using panda::function_details::make_method; | 
| 11 |  |  |  |  |  |  | using panda::function_details::tmp_abstract_function; | 
| 12 |  |  |  |  |  |  | using test::Tracer; | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | namespace test { | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  |  | 
| 17 | 0 |  |  |  |  |  | void void_func(){} | 
| 18 | 0 |  |  |  |  |  | void void_func2(){} | 
| 19 | 0 |  |  |  |  |  | void func_int(int){} | 
| 20 | 0 |  |  |  |  |  | void func_int16(int16_t){} | 
| 21 | 0 |  |  |  |  |  | void func_double(int){} | 
| 22 |  |  |  |  |  |  |  | 
| 23 | 2 |  |  |  |  |  | int foo2() {return 1;} | 
| 24 | 4 |  |  |  |  |  | int plus_one(int a) { return a + 1;} | 
| 25 |  |  |  |  |  |  |  | 
| 26 | 48 | 50 |  |  |  |  | class Test : public panda::Refcnt { | 
| 27 |  |  |  |  |  |  | public: | 
| 28 |  |  |  |  |  |  | int value = 0; | 
| 29 |  |  |  |  |  |  |  | 
| 30 | 8 |  |  |  |  |  | Test(int value) : value(value) {} | 
| 31 | 12 |  |  |  |  |  | Test() : value(0) {} | 
| 32 |  |  |  |  |  |  |  | 
| 33 | 0 |  |  |  |  |  | void foo(int) {} | 
| 34 | 0 |  |  |  |  |  | void foo2(int) {} | 
| 35 | 4 |  |  |  |  |  | int bar() {return value + 40;} | 
| 36 |  |  |  |  |  |  |  | 
| 37 | 0 |  |  |  |  |  | int operator()(int v) {return v;} | 
| 38 | 6 |  |  |  |  |  | bool operator == (const Test& oth) const { return value == oth.value;} | 
| 39 |  |  |  |  |  |  | }; | 
| 40 |  |  |  |  |  |  | } | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | using namespace test; | 
| 43 |  |  |  |  |  |  |  | 
| 44 | 19 |  |  |  |  |  | TEST_CASE("simplest function", "[function]") { | 
| 45 | 2 | 50 |  |  |  |  | function f = &void_func; | 
| 46 | 1 | 50 |  |  |  |  | REQUIRE(true); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 47 | 1 |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  |  | 
| 49 | 19 |  |  |  |  |  | TEST_CASE("simplest function call", "[function]") { | 
| 50 | 2 | 50 |  |  |  |  | function f; | 
| 51 | 1 | 50 |  |  |  |  | f = &plus_one; | 
|  |  | 50 |  |  |  |  |  | 
| 52 | 1 | 50 |  |  |  |  | REQUIRE(f(1) == 2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 53 | 1 |  |  |  |  |  | } | 
| 54 |  |  |  |  |  |  |  | 
| 55 | 19 |  |  |  |  |  | TEST_CASE("function by reference call", "[function]") { | 
| 56 | 2 | 50 |  |  |  |  | function f; | 
| 57 | 1 | 50 |  |  |  |  | f = plus_one; | 
|  |  | 50 |  |  |  |  |  | 
| 58 | 1 | 50 |  |  |  |  | REQUIRE(f(1) == 2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 59 | 1 |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  |  | 
| 61 | 19 |  |  |  |  |  | TEST_CASE("simplest lambda call", "[function]") { | 
| 62 | 1 |  |  |  |  |  | int a = 13; | 
| 63 | 4 | 50 |  |  |  |  | function f = [&](){return a;}; | 
| 64 | 1 | 50 |  |  |  |  | REQUIRE(f() == 13); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 65 | 1 |  |  |  |  |  | } | 
| 66 |  |  |  |  |  |  |  | 
| 67 | 19 |  |  |  |  |  | TEST_CASE("simplest method call", "[function]") { | 
| 68 | 2 | 50 |  |  |  |  | iptr t = new Test(); | 
|  |  | 50 |  |  |  |  |  | 
| 69 | 1 |  |  |  |  |  | t->value = 14; | 
| 70 | 2 | 50 |  |  |  |  | auto m = make_function(&Test::bar, t); | 
| 71 | 1 | 50 |  |  |  |  | REQUIRE(m() == 54); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 72 | 1 |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 19 |  |  |  |  |  | TEST_CASE("mixedcall", "[function]") { | 
| 75 | 2 | 50 |  |  |  |  | iptr t = new Test(); | 
|  |  | 50 |  |  |  |  |  | 
| 76 | 1 |  |  |  |  |  | t->value = 14; | 
| 77 | 2 | 50 |  |  |  |  | auto f = make_function(&Test::bar, t); | 
| 78 | 1 | 50 |  |  |  |  | REQUIRE(f() == 54); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 79 |  |  |  |  |  |  |  | 
| 80 | 1 | 50 |  |  |  |  | f = &foo2; | 
|  |  | 50 |  |  |  |  |  | 
| 81 | 1 | 50 |  |  |  |  | REQUIRE(f() == 1); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 82 |  |  |  |  |  |  |  | 
| 83 | 1 |  |  |  |  |  | int a = 13; | 
| 84 | 3 | 50 |  |  |  |  | f = [&](){return a;}; | 
|  |  | 50 |  |  |  |  |  | 
| 85 | 1 | 50 |  |  |  |  | REQUIRE(f() == 13); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 86 | 1 |  |  |  |  |  | } | 
| 87 |  |  |  |  |  |  |  | 
| 88 | 19 |  |  |  |  |  | TEST_CASE("function ptr comparations", "[function]") { | 
| 89 | 2 | 50 |  |  |  |  | function f1_void = &void_func; | 
| 90 | 2 | 50 |  |  |  |  | function f2_void = &void_func; | 
| 91 | 2 | 50 |  |  |  |  | function f3_void = &void_func2; | 
| 92 |  |  |  |  |  |  |  | 
| 93 | 1 | 50 |  |  |  |  | REQUIRE(f1_void == f2_void); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 94 | 1 | 50 |  |  |  |  | REQUIRE(f1_void != f3_void); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 1 | 50 |  |  |  |  | REQUIRE(f1_void == tmp_abstract_function(&void_func)); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 97 | 1 | 50 |  |  |  |  | REQUIRE(f1_void != tmp_abstract_function(&void_func2)); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 98 | 1 |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  |  | 
| 100 | 19 |  |  |  |  |  | TEST_CASE("function ptr comparations covariant", "[function]") { | 
| 101 |  |  |  |  |  |  | struct Int { | 
| 102 | 0 |  |  |  |  |  | void operator()(int) {} | 
| 103 | 1 |  |  |  |  |  | bool operator==(const Int&) const { | 
| 104 | 1 |  |  |  |  |  | return true; | 
| 105 |  |  |  |  |  |  | } | 
| 106 |  |  |  |  |  |  | }; | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 2 | 50 |  |  |  |  | function    f1(&func_int); | 
| 109 | 2 | 50 |  |  |  |  | function f2(&func_int); | 
| 110 | 2 | 50 |  |  |  |  | function f3(&func_double); | 
| 111 | 2 | 50 |  |  |  |  | function f4(&func_int); | 
| 112 |  |  |  |  |  |  |  | 
| 113 | 1 | 50 |  |  |  |  | CHECK(f1 == f2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 114 | 1 | 50 |  |  |  |  | CHECK(f1 != f3); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 115 | 1 | 50 |  |  |  |  | CHECK(f2 != f3); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 116 | 1 | 50 |  |  |  |  | CHECK(f2 == f4); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | Int i; | 
| 119 | 2 | 50 |  |  |  |  | function    ff1(i); | 
| 120 | 2 | 50 |  |  |  |  | function ff2(i); | 
| 121 |  |  |  |  |  |  |  | 
| 122 | 1 | 50 |  |  |  |  | CHECK(ff1 == ff2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 123 | 1 |  |  |  |  |  | } | 
| 124 |  |  |  |  |  |  |  | 
| 125 | 19 |  |  |  |  |  | TEST_CASE("function covariant copy comparations", "[function]") { | 
| 126 | 1 |  |  |  |  |  | bool called = false; | 
| 127 | 0 |  |  |  |  |  | auto lambda = [&](int a) { | 
| 128 | 0 |  |  |  |  |  | called = true; | 
| 129 | 0 |  |  |  |  |  | return a; | 
| 130 | 1 |  |  |  |  |  | }; | 
| 131 |  |  |  |  |  |  |  | 
| 132 | 2 | 50 |  |  |  |  | function f1 = lambda; | 
| 133 | 2 | 50 |  |  |  |  | function f2(f1); | 
| 134 | 1 | 50 |  |  |  |  | CHECK(f1 == f2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 135 | 1 | 50 |  |  |  |  | CHECK(f2 == f1); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 136 | 1 |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  |  | 
| 138 | 19 |  |  |  |  |  | TEST_CASE("methods comparations", "[function]") { | 
| 139 | 2 | 50 |  |  |  |  | iptr t = new Test(); | 
|  |  | 50 |  |  |  |  |  | 
| 140 | 2 | 50 |  |  |  |  | auto m1 = make_function(&Test::foo, t); | 
| 141 | 2 | 50 |  |  |  |  | auto m2 = make_method(&Test::foo); | 
| 142 | 1 | 50 |  |  |  |  | REQUIRE(m1 != *m2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 1 | 50 |  |  |  |  | m2->bind(t); | 
| 145 | 1 | 50 |  |  |  |  | REQUIRE(m1 == function(m2)); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 146 |  |  |  |  |  |  |  | 
| 147 | 2 | 50 |  |  |  |  | iptr t2 = new Test(); | 
|  |  | 50 |  |  |  |  |  | 
| 148 | 1 | 50 |  |  |  |  | m2->bind(t2); | 
| 149 | 1 | 50 |  |  |  |  | REQUIRE(m1 != *m2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 150 |  |  |  |  |  |  |  | 
| 151 | 2 | 50 |  |  |  |  | auto m3 = make_method(&Test::foo2); | 
| 152 | 1 | 50 |  |  |  |  | REQUIRE(m1 != *m3); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 153 |  |  |  |  |  |  |  | 
| 154 | 1 |  |  |  |  |  | } | 
| 155 |  |  |  |  |  |  |  | 
| 156 | 19 |  |  |  |  |  | TEST_CASE("lambdas comparations", "[function]") { | 
| 157 | 1 |  |  |  |  |  | int a = 10; | 
| 158 | 2 | 50 |  |  |  |  | function l1 = [&](){return a;}; | 
| 159 | 2 | 50 |  |  |  |  | auto l2 = l1; | 
| 160 | 2 | 50 |  |  |  |  | function l3 = [&](){return a;}; | 
| 161 |  |  |  |  |  |  |  | 
| 162 | 1 | 50 |  |  |  |  | REQUIRE(l1 == l2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 163 | 1 | 50 |  |  |  |  | REQUIRE(l1 != l3); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 164 | 1 |  |  |  |  |  | } | 
| 165 |  |  |  |  |  |  |  | 
| 166 | 19 |  |  |  |  |  | TEST_CASE("mixed function comparations", "[function]") { | 
| 167 | 1 |  |  |  |  |  | int a = 10; | 
| 168 | 2 | 50 |  |  |  |  | function l = [&](){return a;}; | 
| 169 | 2 | 50 |  |  |  |  | function f = &foo2; | 
| 170 | 2 | 50 |  |  |  |  | iptr t = new Test(); | 
|  |  | 50 |  |  |  |  |  | 
| 171 | 2 | 50 |  |  |  |  | auto m = make_function(&Test::bar, t); | 
| 172 |  |  |  |  |  |  |  | 
| 173 | 1 | 50 |  |  |  |  | REQUIRE(l != f); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 174 | 1 | 50 |  |  |  |  | REQUIRE(m != l); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 175 | 1 | 50 |  |  |  |  | REQUIRE(m != f); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 176 | 1 |  |  |  |  |  | } | 
| 177 |  |  |  |  |  |  |  | 
| 178 | 19 |  |  |  |  |  | TEST_CASE("null function comparations", "[function]") { | 
| 179 | 1 |  |  |  |  |  | int a = 10; | 
| 180 | 2 | 50 |  |  |  |  | function n; | 
| 181 | 2 | 50 |  |  |  |  | function l = [&](){return a;}; | 
| 182 | 2 | 50 |  |  |  |  | function f = &foo2; | 
| 183 | 2 | 50 |  |  |  |  | iptr t = new Test(); | 
|  |  | 50 |  |  |  |  |  | 
| 184 | 2 | 50 |  |  |  |  | auto m = make_function(&Test::bar, t); | 
| 185 |  |  |  |  |  |  |  | 
| 186 | 1 | 50 |  |  |  |  | REQUIRE_FALSE(l == n); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 187 | 1 | 50 |  |  |  |  | REQUIRE_FALSE(f == n); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 188 | 1 | 50 |  |  |  |  | REQUIRE_FALSE(m == n); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 189 |  |  |  |  |  |  |  | 
| 190 | 1 | 50 |  |  |  |  | REQUIRE_FALSE(n == l); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 191 | 1 | 50 |  |  |  |  | REQUIRE_FALSE(n == f); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 192 | 1 | 50 |  |  |  |  | REQUIRE_FALSE(n == m); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 193 | 1 |  |  |  |  |  | } | 
| 194 |  |  |  |  |  |  |  | 
| 195 | 19 |  |  |  |  |  | TEST_CASE("functors comparations", "[function]") { | 
| 196 | 2 | 50 |  |  |  |  | function f1 = Test(1); | 
|  |  | 50 |  |  |  |  |  | 
| 197 | 2 | 50 |  |  |  |  | function f2 = Test(2); | 
|  |  | 50 |  |  |  |  |  | 
| 198 | 2 | 50 |  |  |  |  | function f11 = Test(1); | 
|  |  | 50 |  |  |  |  |  | 
| 199 |  |  |  |  |  |  |  | 
| 200 | 1 | 50 |  |  |  |  | REQUIRE(f1 != f2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 201 | 1 | 50 |  |  |  |  | REQUIRE(f1 == f11); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 202 |  |  |  |  |  |  |  | 
| 203 | 2 | 50 |  |  |  |  | auto tmp1 = tmp_abstract_function(Test(1)); // inited from rvalue | 
|  |  | 50 |  |  |  |  |  | 
| 204 | 1 | 50 |  |  |  |  | REQUIRE(f1 == tmp1); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 205 | 1 |  |  |  |  |  | } | 
| 206 |  |  |  |  |  |  |  | 
| 207 | 19 |  |  |  |  |  | TEST_CASE("function copy ellision", "[function]") { | 
| 208 | 1 |  |  |  |  |  | Tracer::refresh(); | 
| 209 |  |  |  |  |  |  | { | 
| 210 | 2 | 50 |  |  |  |  | function f = Tracer(10); | 
| 211 | 2 | 50 |  |  |  |  | auto f2 = f; | 
| 212 | 1 | 50 |  |  |  |  | f(11); | 
| 213 | 1 | 50 |  |  |  |  | f2(12); | 
| 214 |  |  |  |  |  |  | } | 
| 215 | 1 | 50 |  |  |  |  | REQUIRE(Tracer::ctor_calls == 1); // 1 for temporary object Tracer(10); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 216 | 1 | 50 |  |  |  |  | REQUIRE(Tracer::copy_calls == 0); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 217 | 1 | 50 |  |  |  |  | REQUIRE(Tracer::move_calls == 1); // 1 construction from tmp object function f = Tracer(10); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 218 | 1 | 50 |  |  |  |  | REQUIRE(Tracer::dtor_calls == 2); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 219 | 1 |  |  |  |  |  | } | 
| 220 |  |  |  |  |  |  |  | 
| 221 | 19 |  |  |  |  |  | TEST_CASE("covariant return type optional" , "[function]") { | 
| 222 | 2 |  |  |  |  |  | function (int)> cb = [](int a) -> int { | 
| 223 | 1 |  |  |  |  |  | return a; | 
| 224 | 3 | 50 |  |  |  |  | }; | 
| 225 | 1 | 50 |  |  |  |  | REQUIRE(cb(3).value_or(42) == 3); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 226 | 1 |  |  |  |  |  | } | 
| 227 |  |  |  |  |  |  |  | 
| 228 | 19 |  |  |  |  |  | TEST_CASE("covariant return type double" , "[function]") { | 
| 229 | 2 |  |  |  |  |  | function cb = [](int a) -> int { | 
| 230 | 1 |  |  |  |  |  | return a; | 
| 231 | 3 | 50 |  |  |  |  | }; | 
| 232 | 1 | 50 |  |  |  |  | REQUIRE(cb(3) == 3.0); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 233 | 1 |  |  |  |  |  | } | 
| 234 |  |  |  |  |  |  |  | 
| 235 | 19 |  |  |  |  |  | TEST_CASE("contravariance of arguments" , "[function]") { | 
| 236 | 2 |  |  |  |  |  | function cb = [](double) -> int { | 
| 237 | 1 |  |  |  |  |  | return 10; | 
| 238 | 3 | 50 |  |  |  |  | }; | 
| 239 | 1 | 50 |  |  |  |  | REQUIRE(cb(3) == 10); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 240 | 1 |  |  |  |  |  | } | 
| 241 |  |  |  |  |  |  | struct Base { | 
| 242 | 0 | 0 |  |  |  |  | virtual ~Base(){} | 
| 243 | 0 | 0 |  |  |  |  | virtual panda::string name() { return "base";} | 
| 244 |  |  |  |  |  |  | }; | 
| 245 | 2 | 50 |  |  |  |  | struct Derrived : Base { | 
| 246 | 2 | 50 |  |  |  |  | virtual panda::string name() override { return "override";} | 
| 247 |  |  |  |  |  |  | }; | 
| 248 |  |  |  |  |  |  |  | 
| 249 | 19 |  |  |  |  |  | TEST_CASE("contravariance of arguments classes" , "[function]") { | 
| 250 |  |  |  |  |  |  | using panda::string; | 
| 251 | 2 |  |  |  |  |  | function cb = [](Base& b) -> Base& { | 
| 252 | 1 |  |  |  |  |  | return b; | 
| 253 | 3 | 50 |  |  |  |  | }; | 
| 254 | 1 |  |  |  |  |  | Derrived b; | 
| 255 | 1 | 50 |  |  |  |  | REQUIRE(cb(b).name() == b.name()); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 256 | 1 |  |  |  |  |  | } | 
| 257 |  |  |  |  |  |  |  | 
| 258 | 1 |  |  |  |  |  | function lamda() { | 
| 259 | 2 |  |  |  |  |  | Tracer t(1); | 
| 260 | 7 |  |  |  |  |  | auto wrapper = [t](int a) -> int { | 
| 261 | 1 |  |  |  |  |  | Tracer o = t; | 
| 262 | 2 |  |  |  |  |  | return a + 1; | 
| 263 | 2 |  |  |  |  |  | }; | 
| 264 | 2 | 50 |  |  |  |  | return wrapper; | 
| 265 |  |  |  |  |  |  | } | 
| 266 |  |  |  |  |  |  |  | 
| 267 |  |  |  |  |  |  |  | 
| 268 | 19 |  |  |  |  |  | TEST_CASE("function memory", "[function]") { | 
| 269 |  |  |  |  |  |  |  | 
| 270 | 1 |  |  |  |  |  | Tracer::refresh(); | 
| 271 |  |  |  |  |  |  | { | 
| 272 | 2 | 50 |  |  |  |  | auto wrapper = lamda(); | 
| 273 | 1 | 50 |  |  |  |  | REQUIRE(wrapper(10) == 11); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | } | 
| 275 |  |  |  |  |  |  |  | 
| 276 | 1 | 50 |  |  |  |  | REQUIRE(Tracer::ctor_total() == Tracer::dtor_calls); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 277 | 1 |  |  |  |  |  | } | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  |  | 
| 280 | 19 |  |  |  |  |  | TEST_CASE("lambda self reference", "[function]") { | 
| 281 | 1 |  |  |  |  |  | int a = 1; | 
| 282 |  |  |  |  |  |  | int b; | 
| 283 | 2 | 50 |  |  |  |  | function outer; | 
| 284 |  |  |  |  |  |  | { | 
| 285 | 2 |  |  |  |  |  | auto inner = [=, &b](panda::Ifunction& self) mutable { | 
| 286 | 2 | 100 |  |  |  |  | if (a == 1) { | 
| 287 | 1 |  |  |  |  |  | a++; | 
| 288 | 1 |  |  |  |  |  | self();; | 
| 289 |  |  |  |  |  |  | } else { | 
| 290 | 1 |  |  |  |  |  | b = 43; | 
| 291 |  |  |  |  |  |  | } | 
| 292 | 3 |  |  |  |  |  | }; | 
| 293 | 1 | 50 |  |  |  |  | outer = inner; | 
|  |  | 50 |  |  |  |  |  | 
| 294 |  |  |  |  |  |  | } | 
| 295 | 1 | 50 |  |  |  |  | outer(); | 
| 296 | 1 | 50 |  |  |  |  | REQUIRE(b == 43); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 297 | 1 |  |  |  |  |  | } | 
| 298 |  |  |  |  |  |  |  | 
| 299 | 19 |  |  |  |  |  | TEST_CASE("no capture self reference", "[function]") { | 
| 300 |  |  |  |  |  |  | static int a = 0; | 
| 301 | 2 | 50 |  |  |  |  | function outer; | 
| 302 |  |  |  |  |  |  | { | 
| 303 | 2 |  |  |  |  |  | auto inner = [](panda::Ifunction& self, int val) { | 
| 304 |  |  |  |  |  |  | while(false) {self(a);} | 
| 305 | 1 |  |  |  |  |  | a = val; | 
| 306 | 1 |  |  |  |  |  | }; | 
| 307 | 1 | 50 |  |  |  |  | outer = inner; | 
|  |  | 50 |  |  |  |  |  | 
| 308 |  |  |  |  |  |  | } | 
| 309 | 1 | 50 |  |  |  |  | outer(1); | 
| 310 | 1 | 50 |  |  |  |  | REQUIRE(a == 1); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 311 | 1 |  |  |  |  |  | } | 
| 312 |  |  |  |  |  |  |  | 
| 313 | 19 |  |  |  |  |  | TEST_CASE("function from null", "[function]") { | 
| 314 |  |  |  |  |  |  | void (*fptr)(); | 
| 315 | 1 |  |  |  |  |  | fptr = nullptr; | 
| 316 | 2 | 50 |  |  |  |  | function f = fptr; | 
| 317 | 1 | 50 |  |  |  |  | REQUIRE(!f); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 318 | 1 |  |  |  |  |  | } | 
| 319 |  |  |  |  |  |  |  | 
| 320 | 19 |  |  |  |  |  | TEST_CASE("function from null method", "[function]") { | 
| 321 | 1 |  |  |  |  |  | auto meth = &Test::bar; | 
| 322 | 1 |  |  |  |  |  | meth = nullptr; | 
| 323 | 2 | 50 |  |  |  |  | auto m = make_function(meth); | 
| 324 | 1 | 50 |  |  |  |  | REQUIRE(!m); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 325 | 1 |  |  |  |  |  | } | 
| 326 |  |  |  |  |  |  |  | 
| 327 | 19 |  |  |  |  |  | TEST_CASE("function from nullable object", "[function]") { | 
| 328 |  |  |  |  |  |  | struct S { | 
| 329 | 0 |  |  |  |  |  | void operator()() const {} | 
| 330 | 2 |  |  |  |  |  | explicit operator bool() const { | 
| 331 | 2 |  |  |  |  |  | return val; | 
| 332 |  |  |  |  |  |  | } | 
| 333 |  |  |  |  |  |  | bool val; | 
| 334 |  |  |  |  |  |  | }; | 
| 335 |  |  |  |  |  |  |  | 
| 336 | 1 |  |  |  |  |  | S s{false}; | 
| 337 | 2 | 50 |  |  |  |  | function f = s; | 
| 338 | 1 | 50 |  |  |  |  | REQUIRE(!f); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 339 | 1 |  |  |  |  |  | s.val = true; | 
| 340 | 1 | 50 |  |  |  |  | f = s; | 
|  |  | 50 |  |  |  |  |  | 
| 341 | 1 | 50 |  |  |  |  | REQUIRE(f); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 342 | 1 |  |  |  |  |  | } | 
| 343 |  |  |  |  |  |  |  | 
| 344 | 19 |  |  |  |  |  | TEST_CASE("lambda self reference gcc bug", "[function]") { | 
| 345 |  |  |  |  |  |  | struct SomeStruct { | 
| 346 | 1 |  |  |  |  |  | void method(int val) { | 
| 347 | 1 |  |  |  |  |  | function ff = [this](panda::Ifunction&, auto... args) mutable { | 
| 348 | 1 |  |  |  |  |  | this->bar(args...); | 
| 349 | 2 | 50 |  |  |  |  | }; | 
| 350 | 1 | 50 |  |  |  |  | ff(val); | 
| 351 | 1 |  |  |  |  |  | } | 
| 352 |  |  |  |  |  |  |  | 
| 353 | 1 |  |  |  |  |  | void bar(int val) { | 
| 354 | 1 |  |  |  |  |  | a = val; | 
| 355 | 1 |  |  |  |  |  | } | 
| 356 |  |  |  |  |  |  | int a = 10; | 
| 357 |  |  |  |  |  |  | }; | 
| 358 | 1 |  |  |  |  |  | SomeStruct s; | 
| 359 | 1 | 50 |  |  |  |  | s.method(20); | 
| 360 | 1 | 50 |  |  |  |  | REQUIRE(s.a == 20); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 361 | 1 |  |  |  |  |  | } | 
| 362 |  |  |  |  |  |  |  | 
| 363 | 19 |  |  |  |  |  | TEST_CASE("lambda self reference auto...", "[function]") { | 
| 364 | 1 |  |  |  |  |  | int a = 10; | 
| 365 | 1 |  |  |  |  |  | function f = [&](auto...args) -> int { | 
| 366 |  |  |  |  |  |  | static_assert(sizeof...(args) == 1, "auto... resolved as without SELF"); | 
| 367 | 1 |  |  |  |  |  | return (a = 20) + 1; | 
| 368 | 2 | 50 |  |  |  |  | }; | 
| 369 | 1 | 50 |  |  |  |  | int b = f(42); | 
| 370 | 1 | 50 |  |  |  |  | REQUIRE(a == 20); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 371 | 1 | 50 |  |  |  |  | REQUIRE(b == 21); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 372 |  |  |  |  |  |  |  | 
| 373 | 1 |  |  |  |  |  | function f2 = [&](auto&&...args) -> int { | 
| 374 |  |  |  |  |  |  | static_assert(sizeof...(args) == 1, "auto... resolved as without SELF"); | 
| 375 | 1 |  |  |  |  |  | return 111; | 
| 376 | 2 | 50 |  |  |  |  | }; | 
| 377 | 1 | 50 |  |  |  |  | CHECK(f2(123) == 111); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 378 |  |  |  |  |  |  |  | 
| 379 | 1 |  |  |  |  |  | function f3 = [&](auto&&...args) { | 
| 380 | 1 | 50 |  |  |  |  | REQUIRE(sizeof...(args) == 1); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 381 | 1 |  |  |  |  |  | return 111; | 
| 382 | 2 | 50 |  |  |  |  | }; | 
| 383 | 1 | 50 |  |  |  |  | CHECK(f3(123) == 111); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 384 | 73 | 50 |  |  |  |  | } | 
|  |  | 50 |  |  |  |  |  |