|
| 1 | +main: () = { |
| 2 | + postfix_operators(); |
| 3 | + |
| 4 | + // Variables with type of a mix of `*`/`const` to `() throws -> void`. |
| 5 | + f0: * () throws = :() = {}; |
| 6 | + f1: const * () throws = f0; |
| 7 | + f2: * const () throws = f0; |
| 8 | + f3: const * const () throws = f0; |
| 9 | + |
| 10 | + i: i32 = 0; |
| 11 | + i0: * i32 = i&; |
| 12 | + i1: const * i32 = i0; |
| 13 | + i2: * const i32 = i0; |
| 14 | + i3: const * const i32 = i0; |
| 15 | + |
| 16 | + // Assert consistent '*'/'const' with non-function type variables. |
| 17 | + static_assert((std::is_const_v<decltype(f1)>) == std::is_const_v<decltype(i1)>); |
| 18 | + static_assert((std::is_const_v<decltype(f2)>) == std::is_const_v<decltype(i2)>); |
| 19 | + static_assert((std::is_const_v<decltype(f3)>) == std::is_const_v<decltype(i3)>); |
| 20 | + |
| 21 | + // Variables with various kinds of parameter. |
| 22 | + f4: * (_: i32) throws = :(x: i32) = {}; |
| 23 | + f5: * (_: std::any) throws = :(x: std::any) = {}; |
| 24 | + f6: * (move _: i32) throws = :(move x: i32) = {}; |
| 25 | + f7: * (out _: i32) throws = :(copy x) = {}; |
| 26 | + |
| 27 | + // In alternative. |
| 28 | + [[assert: inspect f0 -> bool { |
| 29 | + is () = (std::terminate(), false); |
| 30 | + is () throws = (std::terminate(), false); |
| 31 | + is * () throws = true; |
| 32 | + is _ = false; |
| 33 | + }]] |
| 34 | + [[assert: inspect f0* -> bool { |
| 35 | + is () throws = true; |
| 36 | + is _ = false; |
| 37 | + }]] |
| 38 | + |
| 39 | + // As block variable. |
| 40 | + (f: * () throws = f0) { } |
| 41 | + |
| 42 | + // As local function parameter. |
| 43 | + _ = :(f: * () throws) = {}; |
| 44 | + _ = :(f: * () throws -> * () throws) = {}; |
| 45 | + _ = :(f: * () throws -> * () throws -> * () throws) = {}; |
| 46 | + |
| 47 | + // In local function return type. |
| 48 | + _ = :() -> * () throws = nullptr; |
| 49 | + _ = :() -> * () throws -> * () throws = nullptr; |
| 50 | + |
| 51 | + // Without `throws`. |
| 52 | + _ = :* (copy _: std::string_view, copy _: CPP2_MESSAGE_PARAM) = cpp2::report_and_terminate; |
| 53 | + |
| 54 | + // As template argument. |
| 55 | + _ = :std::type_identity_t<* () throws> = f0; |
| 56 | +} |
| 57 | + |
| 58 | +// As non-local function parameter. |
| 59 | +g: (f: * () throws) = { } |
| 60 | +g: (f: * () throws -> * () throws) = { } |
| 61 | +// As template parameter. |
| 62 | +g: <V: * () throws> () = { } |
| 63 | +g: <V: * () throws -> * () throws> () = { } |
| 64 | + |
| 65 | +// In non-local function return type. |
| 66 | +g1: () -> * () throws = nullptr; |
| 67 | +g2: () -> * () throws -> * () throws = nullptr; |
| 68 | + |
| 69 | +// clang-format off |
| 70 | +// Test case from #343. |
| 71 | +f2: () -> std::function<(_: std::string) throws -> std::string> = { |
| 72 | + return :(s: std::string) -> std::string = { return s + " World!"; }; |
| 73 | +} |
| 74 | + |
| 75 | +// Adapted from <https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators>. |
| 76 | + f: (x: i32) -> * (_: i32) throws -> std::string = +:(x: i32) -> std::string = ""; |
| 77 | +postfix_operators: () = { |
| 78 | + [[assert: f is (_: i32) throws -> * (_: i32) throws -> std::string]] |
| 79 | + // / | | |
| 80 | + // / | | |
| 81 | + [[assert: f(42) is * (_: i32) throws -> std::string]] |
| 82 | + // ________________/ | |
| 83 | + // / | |
| 84 | + [[assert: f(42)* is (_: i32) throws -> std::string]] |
| 85 | + // _______________/ |
| 86 | + // / |
| 87 | + [[assert: (f(42)*)(1) is std::string]] |
| 88 | +} // clang-format on |
0 commit comments