From c24155b4064970487fe7adf2f2539f6e5e2a9af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Mon, 7 Aug 2023 00:02:46 -0400 Subject: [PATCH] fix(cpp1): handle known UFCS corner cases Provide transparent SFINAE. Forward `noexcept`. Accept object with unparenthesized comma like `v`. Incidentially, merge the UFCS macros. --- include/cpp2util.h | 121 +++----- .../mixed-bugfix-for-ufcs-non-local.cpp2 | 35 +++ .../pure2-bugfix-for-ufcs-arguments.cpp2 | 46 +++ .../pure2-bugfix-for-ufcs-noexcept.cpp2 | 6 + .../pure2-bugfix-for-ufcs-sfinae.cpp2 | 5 + .../clang-18/clang-version.output | 2 +- ...ed-bugfix-for-ufcs-non-local.cpp.execution | 0 ...mixed-bugfix-for-ufcs-non-local.cpp.output | 0 ...e2-bugfix-for-ufcs-arguments.cpp.execution | 4 + ...pure2-bugfix-for-ufcs-arguments.cpp.output | 0 ...re2-bugfix-for-ufcs-noexcept.cpp.execution | 0 .../pure2-bugfix-for-ufcs-noexcept.cpp.output | 0 ...pure2-bugfix-for-ufcs-sfinae.cpp.execution | 0 .../pure2-bugfix-for-ufcs-sfinae.cpp.output | 0 ...ed-bugfix-for-ufcs-non-local.cpp.execution | 0 ...mixed-bugfix-for-ufcs-non-local.cpp.output | 0 ...e2-bugfix-for-ufcs-arguments.cpp.execution | 4 + ...pure2-bugfix-for-ufcs-arguments.cpp.output | 0 ...re2-bugfix-for-ufcs-noexcept.cpp.execution | 0 .../pure2-bugfix-for-ufcs-noexcept.cpp.output | 0 ...pure2-bugfix-for-ufcs-sfinae.cpp.execution | 0 .../pure2-bugfix-for-ufcs-sfinae.cpp.output | 0 .../test-results/mixed-bounds-check.cpp | 2 +- .../mixed-bounds-safety-with-assert-2.cpp | 2 +- .../mixed-bounds-safety-with-assert.cpp | 2 +- .../mixed-bugfix-for-ufcs-non-local.cpp | 64 ++++ ...ixed-bugfix-for-ufcs-non-local.cpp2.output | 2 + ...ures-in-expressions-and-postconditions.cpp | 6 +- ...d-function-expression-and-std-for-each.cpp | 8 +- ...nction-expression-with-pointer-capture.cpp | 2 +- ...ialization-safety-3-contract-violation.cpp | 4 +- .../mixed-initialization-safety-3.cpp | 4 +- ...xed-lifetime-safety-and-null-contracts.cpp | 2 +- .../mixed-postexpression-with-capture.cpp | 6 +- ...d-postfix-expression-custom-formatting.cpp | 8 +- .../mixed-string-interpolation.cpp | 2 +- .../test-results/mixed-type-safety-1.cpp | 2 +- ...mixed-ufcs-multiple-template-arguments.cpp | 2 +- .../test-results/pure2-bounds-safety-span.cpp | 2 +- .../pure2-bugfix-for-ufcs-arguments.cpp | 104 +++++++ ...ure2-bugfix-for-ufcs-arguments.cpp2.output | 2 + .../pure2-bugfix-for-ufcs-noexcept.cpp | 36 +++ ...pure2-bugfix-for-ufcs-noexcept.cpp2.output | 2 + .../pure2-bugfix-for-ufcs-sfinae.cpp | 35 +++ .../pure2-bugfix-for-ufcs-sfinae.cpp2.output | 2 + ...re2-initialization-safety-with-else-if.cpp | 4 +- ...ion-in-generic-function-multiple-types.cpp | 2 +- .../pure2-intro-example-hello-2022.cpp | 2 +- .../pure2-intro-example-three-loops.cpp | 2 +- .../test-results/pure2-stdio-with-raii.cpp | 2 +- regression-tests/test-results/pure2-stdio.cpp | 4 +- .../test-results/pure2-type-safety-1.cpp | 2 +- ...-type-safety-2-with-inspect-expression.cpp | 2 +- .../test-results/pure2-types-basics.cpp | 12 +- .../test-results/pure2-types-inheritance.cpp | 10 +- ...2-types-order-independence-and-nesting.cpp | 6 +- ...ypes-smf-and-that-1-provide-everything.cpp | 20 +- ...hat-2-provide-mvconstruct-and-cpassign.cpp | 20 +- ...hat-3-provide-mvconstruct-and-mvassign.cpp | 20 +- ...d-that-4-provide-cpassign-and-mvassign.cpp | 20 +- ...hat-5-provide-nothing-but-general-case.cpp | 20 +- .../pure2-types-that-parameters.cpp | 10 +- .../pure2-ufcs-member-access-and-chaining.cpp | 20 +- source/cppfront.cpp | 41 +-- source/reflect.h | 286 +++++++++--------- 65 files changed, 666 insertions(+), 363 deletions(-) create mode 100644 regression-tests/mixed-bugfix-for-ufcs-non-local.cpp2 create mode 100644 regression-tests/pure2-bugfix-for-ufcs-arguments.cpp2 create mode 100644 regression-tests/pure2-bugfix-for-ufcs-noexcept.cpp2 create mode 100644 regression-tests/pure2-bugfix-for-ufcs-sfinae.cpp2 create mode 100644 regression-tests/test-results/clang-18/mixed-bugfix-for-ufcs-non-local.cpp.execution create mode 100644 regression-tests/test-results/clang-18/mixed-bugfix-for-ufcs-non-local.cpp.output create mode 100644 regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-arguments.cpp.execution create mode 100644 regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-arguments.cpp.output create mode 100644 regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-noexcept.cpp.execution create mode 100644 regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-noexcept.cpp.output create mode 100644 regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-sfinae.cpp.execution create mode 100644 regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-sfinae.cpp.output create mode 100644 regression-tests/test-results/gcc-13/mixed-bugfix-for-ufcs-non-local.cpp.execution create mode 100644 regression-tests/test-results/gcc-13/mixed-bugfix-for-ufcs-non-local.cpp.output create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-arguments.cpp.execution create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-arguments.cpp.output create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-noexcept.cpp.execution create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-noexcept.cpp.output create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-sfinae.cpp.execution create mode 100644 regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-sfinae.cpp.output create mode 100644 regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp create mode 100644 regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp create mode 100644 regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp create mode 100644 regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp create mode 100644 regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp2.output diff --git a/include/cpp2util.h b/include/cpp2util.h index 8ee7792c8..920162b4a 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -191,7 +191,7 @@ // in our -pure-cpp2 "import std;" simulation mode... if you need this, // use mixed mode (not -pure-cpp2) and #include all the headers you need // including this one - // + // // #include #endif @@ -465,7 +465,7 @@ template auto Typeid() -> decltype(auto) { #ifdef CPP2_NO_RTTI Type.expects( - !"'any' dynamic casting is disabled with -fno-rtti", // more likely to appear on console + !"'any' dynamic casting is disabled with -fno-rtti", // more likely to appear on console "'any' dynamic casting is disabled with -fno-rtti" // make message available to hooked handlers ); #else @@ -655,12 +655,19 @@ class out { //----------------------------------------------------------------------- // #if defined(_MSC_VER) && !defined(__clang_major__) - #define CPP2_FORCE_INLINE __forceinline - #define CPP2_FORCE_INLINE_LAMBDA [[msvc::forceinline]] + #define CPP2_FORCE_INLINE __forceinline + #define CPP2_FORCE_INLINE_LAMBDA [[msvc::forceinline]] + #define CPP2_FORCE_INLINE_LAMBDA_CLANG /* empty */ #define CPP2_LAMBDA_NO_DISCARD #else - #define CPP2_FORCE_INLINE __attribute__((always_inline)) - #define CPP2_FORCE_INLINE_LAMBDA __attribute__((always_inline)) + #define CPP2_FORCE_INLINE __attribute__((always_inline)) + #if defined(__clang__) + #define CPP2_FORCE_INLINE_LAMBDA /* empty */ + #define CPP2_FORCE_INLINE_LAMBDA_CLANG __attribute__((always_inline)) + #else + #define CPP2_FORCE_INLINE_LAMBDA __attribute__((always_inline)) + #define CPP2_FORCE_INLINE_LAMBDA_CLANG /* empty */ + #endif #if defined(__clang_major__) // Also check __cplusplus, only to satisfy Clang -pedantic-errors @@ -681,84 +688,26 @@ class out { #endif -// Note: [&] is because a nested UFCS might be viewed as trying to capture 'this' - -#define CPP2_UFCS(FUNCNAME,PARAM1,...) \ -[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \ - return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \ - } else { \ - return FUNCNAME(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \ - } \ -}(PARAM1, __VA_ARGS__) - -#define CPP2_UFCS_0(FUNCNAME,PARAM1) \ -[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \ - return CPP2_FORWARD(obj).FUNCNAME(); \ - } else { \ - return FUNCNAME(CPP2_FORWARD(obj)); \ - } \ -}(PARAM1) - -#define CPP2_UFCS_REMPARENS(...) __VA_ARGS__ - -#define CPP2_UFCS_TEMPLATE(FUNCNAME,TEMPARGS,PARAM1,...) \ -[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \ - return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \ +#define CPP2_UFCS_(LAMBDADEFCAPT,TEMPKW,...) \ +[LAMBDADEFCAPT] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA_CLANG \ + noexcept(requires { requires requires { CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); }; \ + requires noexcept(CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...)); } \ + || requires { requires !requires { CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); }; \ + requires noexcept(__VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...)); }) \ + CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \ + requires requires { CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); } \ + || requires { __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \ + if constexpr (requires{ CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); }) { \ + return CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); \ } else { \ - return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \ + return __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \ } \ -}(PARAM1, __VA_ARGS__) - -#define CPP2_UFCS_TEMPLATE_0(FUNCNAME,TEMPARGS,PARAM1) \ -[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \ - return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \ - } else { \ - return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(obj)); \ - } \ -}(PARAM1) - - -// But for non-local lambdas [&] is not allowed - -#define CPP2_UFCS_NONLOCAL(FUNCNAME,PARAM1,...) \ -[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \ - return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \ - } else { \ - return FUNCNAME(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \ - } \ -}(PARAM1, __VA_ARGS__) - -#define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \ -[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \ - return CPP2_FORWARD(obj).FUNCNAME(); \ - } else { \ - return FUNCNAME(CPP2_FORWARD(obj)); \ - } \ -}(PARAM1) - -#define CPP2_UFCS_TEMPLATE_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1,...) \ -[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \ - return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \ - } else { \ - return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \ - } \ -}(PARAM1, __VA_ARGS__) +} -#define CPP2_UFCS_TEMPLATE_0_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1) \ -[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ - if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \ - return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \ - } else { \ - return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(obj)); \ - } \ -}(PARAM1) +#define CPP2_UFCS(...) CPP2_UFCS_(&,,__VA_ARGS__) +#define CPP2_UFCS_TEMPLATE(...) CPP2_UFCS_(&,template,__VA_ARGS__) +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,,__VA_ARGS__) +#define CPP2_UFCS_TEMPLATE_NONLOCAL(...) CPP2_UFCS_(,template,__VA_ARGS__) //----------------------------------------------------------------------- @@ -827,8 +776,8 @@ auto is( X const& ) -> bool { template< typename C, typename X > requires ( - ( std::is_base_of_v || - ( std::is_polymorphic_v && std::is_polymorphic_v) + ( std::is_base_of_v || + ( std::is_polymorphic_v && std::is_polymorphic_v) ) && !std::is_same_v) auto is( X const& x ) -> bool { return Dynamic_cast(&x) != nullptr; @@ -836,8 +785,8 @@ auto is( X const& x ) -> bool { template< typename C, typename X > requires ( - ( std::is_base_of_v || - ( std::is_polymorphic_v && std::is_polymorphic_v) + ( std::is_base_of_v || + ( std::is_polymorphic_v && std::is_polymorphic_v) ) && !std::is_same_v) auto is( X const* x ) -> bool { return Dynamic_cast(x) != nullptr; @@ -1425,7 +1374,7 @@ inline auto to_string(std::string const& s) -> std::string const& template inline auto to_string(T const& sv) -> std::string - requires (std::is_convertible_v + requires (std::is_convertible_v && !std::is_convertible_v) { return std::string{sv}; diff --git a/regression-tests/mixed-bugfix-for-ufcs-non-local.cpp2 b/regression-tests/mixed-bugfix-for-ufcs-non-local.cpp2 new file mode 100644 index 000000000..5f196851a --- /dev/null +++ b/regression-tests/mixed-bugfix-for-ufcs-non-local.cpp2 @@ -0,0 +1,35 @@ +template struct t { }; +constexpr bool f(const t&) { return true; } +constexpr t o{}; + +// Variables. + +// _: > bool = (); // Blocked on #389, [GCC109781][]. + +// _: t = (); // Blocked on Clang 12 (lambda in unevaluated context). + +_: bool = o.f(); + +// Functions. + +// g: > () = { } // Blocked on [GCC109781][]. + +// g: (x: t) = { } // Blocked on Clang 12 (lambda in unevaluated context). + +g: () [[pre: o.f()]] = { } + +// h: () -> t = o; // Blocked on Clang 12 (lambda in unevaluated context). + +// Aliases. + +// a: > type == bool; // Blocked on [GCC109781][]. + +// b: > _ == false; // Blocked on [GCC109781][]. + +// c: type == t; // Blocked on Clang 12 (lambda in unevaluated context). + +// d: _ == t(); // Blocked on Clang 12 (lambda in unevaluated context). + +main: () = { } + +// [GCC109781]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109781 diff --git a/regression-tests/pure2-bugfix-for-ufcs-arguments.cpp2 b/regression-tests/pure2-bugfix-for-ufcs-arguments.cpp2 new file mode 100644 index 000000000..c5f80f82a --- /dev/null +++ b/regression-tests/pure2-bugfix-for-ufcs-arguments.cpp2 @@ -0,0 +1,46 @@ +print_res: (x: i32) -> i32 = { + std::cout << x; + if (x == 9) { std::cout << '\n'; } + return x; +} +t: type = { + f: (inout this) -> i32 = print_res(0); + f: (inout this, x) -> i32 = print_res(1); + f: (inout this) -> i32 = print_res(2); + f: (inout this, x) -> i32 = print_res(3); + f: (inout this, x, y) -> i32 = print_res(4); +} +f: (o: t) -> i32 = print_res(5); +f: (o: t, x) -> i32 = print_res(6); +f: (o: t) -> i32 = print_res(7); +f: (o: t, x) -> i32 = print_res(8); +f: (o: t, x, y) -> i32 = print_res(9); +m: t = (); +n: const t = (); +a: _ == n; +_: i32 = m.f(); +_: i32 = m.f(0); +_: i32 = m.f(); +_: i32 = m.f(0); +_: i32 = m.f(0, 0); +_: i32 = n.f(); +_: i32 = n.f(0); +_: i32 = n.f(); +_: i32 = n.f(0); +_: i32 = n.f(0, 0); +_: i32 = a.f(0, 0); +main: () = { + _: i32 = m.f(); + _: i32 = m.f(0); + _: i32 = m.f(); + _: i32 = m.f(0); + _: i32 = m.f(0, 0); + _: i32 = n.f(); + _: i32 = n.f(0); + _: i32 = n.f(); + _: i32 = n.f(0); + _: i32 = n.f(0, 0); + _: i32 = a.f(0, 0); + + _ = :(a, f) = { _ = a.f(a).f(); }; +} diff --git a/regression-tests/pure2-bugfix-for-ufcs-noexcept.cpp2 b/regression-tests/pure2-bugfix-for-ufcs-noexcept.cpp2 new file mode 100644 index 000000000..cfadbbc05 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-ufcs-noexcept.cpp2 @@ -0,0 +1,6 @@ +t: type = { + swap: (inout this, that) = { } +} +main: () = { + // static_assert(noexcept(t().swap(t()))); // Blocked on Clang 12 (lambda in unevaluated context). +} diff --git a/regression-tests/pure2-bugfix-for-ufcs-sfinae.cpp2 b/regression-tests/pure2-bugfix-for-ufcs-sfinae.cpp2 new file mode 100644 index 000000000..a9bfe70d1 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-ufcs-sfinae.cpp2 @@ -0,0 +1,5 @@ +// f: () -> std::type_identity_t = { } // Blocked on Clang 12 (lambda in unevaluated context). +B: type = { } +main: () = { + // static_assert(!std::invocable (x: T) -> std::void_t())> = {}), B>); // Blocked on Clang 12 (lambda in unevaluated context). +} diff --git a/regression-tests/test-results/clang-18/clang-version.output b/regression-tests/test-results/clang-18/clang-version.output index 3cc1f0a62..be720f5d4 100644 --- a/regression-tests/test-results/clang-18/clang-version.output +++ b/regression-tests/test-results/clang-18/clang-version.output @@ -1,4 +1,4 @@ -clang version 18.0.0 (https://git.uplinklabs.net/mirrors/llvm-project.git c0abd3814564a568dfc607c216e6407eaa314f46) +clang version 18.0.0 (https://github.com/llvm/llvm-project.git c0abd3814564a568dfc607c216e6407eaa314f46) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /home/johel/root/clang-main/bin diff --git a/regression-tests/test-results/clang-18/mixed-bugfix-for-ufcs-non-local.cpp.execution b/regression-tests/test-results/clang-18/mixed-bugfix-for-ufcs-non-local.cpp.execution new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/clang-18/mixed-bugfix-for-ufcs-non-local.cpp.output b/regression-tests/test-results/clang-18/mixed-bugfix-for-ufcs-non-local.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-arguments.cpp.execution b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-arguments.cpp.execution new file mode 100644 index 000000000..0e41b7819 --- /dev/null +++ b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-arguments.cpp.execution @@ -0,0 +1,4 @@ +0123456789 +9 +0123456789 +9 diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-arguments.cpp.output b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-arguments.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-noexcept.cpp.execution b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-noexcept.cpp.execution new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-noexcept.cpp.output b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-noexcept.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-sfinae.cpp.execution b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-sfinae.cpp.execution new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-sfinae.cpp.output b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-sfinae.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/mixed-bugfix-for-ufcs-non-local.cpp.execution b/regression-tests/test-results/gcc-13/mixed-bugfix-for-ufcs-non-local.cpp.execution new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/mixed-bugfix-for-ufcs-non-local.cpp.output b/regression-tests/test-results/gcc-13/mixed-bugfix-for-ufcs-non-local.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-arguments.cpp.execution b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-arguments.cpp.execution new file mode 100644 index 000000000..0e41b7819 --- /dev/null +++ b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-arguments.cpp.execution @@ -0,0 +1,4 @@ +0123456789 +9 +0123456789 +9 diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-arguments.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-arguments.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-noexcept.cpp.execution b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-noexcept.cpp.execution new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-noexcept.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-noexcept.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-sfinae.cpp.execution b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-sfinae.cpp.execution new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-sfinae.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-sfinae.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/mixed-bounds-check.cpp b/regression-tests/test-results/mixed-bounds-check.cpp index 442a09bab..693750488 100644 --- a/regression-tests/test-results/mixed-bounds-check.cpp +++ b/regression-tests/test-results/mixed-bounds-check.cpp @@ -24,7 +24,7 @@ std::set_terminate(std::abort); std::vector v {1, 2, 3, 4, 5, -999}; - CPP2_UFCS_0(pop_back, v); + CPP2_UFCS(pop_back)(v); std::cout << cpp2::assert_in_bounds(std::move(v), 5) << "\n"; } diff --git a/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp b/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp index 2535f01a6..c979bb21b 100644 --- a/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp +++ b/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp @@ -38,7 +38,7 @@ auto add_42_to_subrange(auto& rng, cpp2::in start, cpp2::in end) -> vo auto add_42_to_subrange(auto& rng, cpp2::in start, cpp2::in end) -> void { cpp2::Bounds.expects(cpp2::cmp_less_eq(0,start), ""); - cpp2::Bounds.expects(cpp2::cmp_less_eq(end,CPP2_UFCS_0(ssize, rng)), ""); + cpp2::Bounds.expects(cpp2::cmp_less_eq(end,CPP2_UFCS(ssize)(rng)), ""); auto count {0}; for ( diff --git a/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp b/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp index b63e12b66..c33b9b96f 100644 --- a/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp +++ b/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp @@ -37,7 +37,7 @@ auto print_subrange(auto const& rng, cpp2::in start, cpp2::in end) -> auto print_subrange(auto const& rng, cpp2::in start, cpp2::in end) -> void{ cpp2::Bounds.expects(cpp2::cmp_less_eq(0,start), ""); - cpp2::Bounds.expects(cpp2::cmp_less_eq(end,CPP2_UFCS_0(ssize, rng)), ""); + cpp2::Bounds.expects(cpp2::cmp_less_eq(end,CPP2_UFCS(ssize)(rng)), ""); auto count {0}; for ( diff --git a/regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp b/regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp new file mode 100644 index 000000000..96ed0914c --- /dev/null +++ b/regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp @@ -0,0 +1,64 @@ + + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + + + +//=== Cpp2 type definitions and function declarations =========================== + +template struct t { }; +constexpr bool f(const t&) { return true; } +constexpr t o{}; + +// Variables. + +// _: > bool = (); // Blocked on #389, [GCC109781][]. + +// _: t = (); // Blocked on Clang 12 (lambda in unevaluated context). + +#line 11 "mixed-bugfix-for-ufcs-non-local.cpp2" +extern bool auto_11_1; + +// Functions. + +// g: > () = { } // Blocked on [GCC109781][]. + +// g: (x: t) = { } // Blocked on Clang 12 (lambda in unevaluated context). + +auto g() -> void; + +// h: () -> t = o; // Blocked on Clang 12 (lambda in unevaluated context). + +// Aliases. + +// a: > type == bool; // Blocked on [GCC109781][]. + +// b: > _ == false; // Blocked on [GCC109781][]. + +// c: type == t; // Blocked on Clang 12 (lambda in unevaluated context). + +// d: _ == t(); // Blocked on Clang 12 (lambda in unevaluated context). + +auto main() -> int; + +// [GCC109781]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109781 + + +//=== Cpp2 function definitions ================================================= + + +#line 11 "mixed-bugfix-for-ufcs-non-local.cpp2" +bool auto_11_1 {CPP2_UFCS_NONLOCAL(f)(o)}; + +#line 19 "mixed-bugfix-for-ufcs-non-local.cpp2" +auto g() -> void{ + cpp2::Default.expects(CPP2_UFCS(f)(o), ""); +#line 19 "mixed-bugfix-for-ufcs-non-local.cpp2" +} + +#line 33 "mixed-bugfix-for-ufcs-non-local.cpp2" +auto main() -> int{} + diff --git a/regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp2.output b/regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp2.output new file mode 100644 index 000000000..560fb3c5c --- /dev/null +++ b/regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp2.output @@ -0,0 +1,2 @@ +mixed-bugfix-for-ufcs-non-local.cpp2... ok (mixed Cpp1/Cpp2, Cpp2 code passes safety checks) + diff --git a/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp b/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp index 827a58d1b..6fe8b071f 100644 --- a/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp +++ b/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp @@ -45,9 +45,9 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void #line 22 "mixed-captures-in-expressions-and-postconditions.cpp2" { - cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), ""); - auto post_21_5 = cpp2::finally_success([_0 = CPP2_UFCS_0(ssize, vec)]{cpp2::Default.expects(CPP2_UFCS_0(ssize, vec)==_0 + 1, "");} ); + cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS(ssize)(vec)), ""); + auto post_21_5 = cpp2::finally_success([_0 = CPP2_UFCS(ssize)(vec)]{cpp2::Default.expects(CPP2_UFCS(ssize)(vec)==_0 + 1, "");} ); #line 23 "mixed-captures-in-expressions-and-postconditions.cpp2" - static_cast(CPP2_UFCS(insert, vec, CPP2_UFCS_0(begin, vec) + where, val)); + static_cast(CPP2_UFCS(insert)(vec, CPP2_UFCS(begin)(vec) + where, val)); } diff --git a/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp b/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp index 3457bbeac..63b7884c4 100644 --- a/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp +++ b/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp @@ -30,16 +30,16 @@ // Passing a function expression std::for_each( - CPP2_UFCS_0(begin, view), - CPP2_UFCS_0(end, view), + CPP2_UFCS(begin)(view), + CPP2_UFCS(end)(view), [](auto& x) -> void { x += "-ish"; } ); // Initializing from a function expression auto callback {[](auto& x) -> void { x += " maybe"; }}; std::for_each( - CPP2_UFCS_0(begin, view), - CPP2_UFCS_0(end, view), + CPP2_UFCS(begin)(view), + CPP2_UFCS(end)(view), std::move(callback) ); diff --git a/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp b/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp index 57e90b819..65f066610 100644 --- a/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp +++ b/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp @@ -31,7 +31,7 @@ std::string y {"\n"}; std::ranges::for_each(view, [_0 = (&y)](auto const& x) -> void{ - std::cout << CPP2_UFCS_0(c_str, (*cpp2::assert_not_null((_0)))) << x << *cpp2::assert_not_null(_0); + std::cout << CPP2_UFCS(c_str)((*cpp2::assert_not_null((_0)))) << x << *cpp2::assert_not_null(_0); }); auto callback {[](auto& x) -> void { x += "-ish"; }}; diff --git a/regression-tests/test-results/mixed-initialization-safety-3-contract-violation.cpp b/regression-tests/test-results/mixed-initialization-safety-3-contract-violation.cpp index 94c2a3fb0..db2e6f7c8 100644 --- a/regression-tests/test-results/mixed-initialization-safety-3-contract-violation.cpp +++ b/regression-tests/test-results/mixed-initialization-safety-3-contract-violation.cpp @@ -59,9 +59,9 @@ auto fill( ) -> void { - cpp2::Default.expects(cpp2::cmp_greater_eq(CPP2_UFCS_0(ssize, value),count), "fill: value must contain at least count elements"); + cpp2::Default.expects(cpp2::cmp_greater_eq(CPP2_UFCS(ssize)(value),count), "fill: value must contain at least count elements"); #line 25 "mixed-initialization-safety-3-contract-violation.cpp2" - x.construct(CPP2_UFCS(substr, value, 0, count)); + x.construct(CPP2_UFCS(substr)(value, 0, count)); } auto print_decorated(auto const& x) -> void { std::cout << ">> [" << x << "]\n"; } diff --git a/regression-tests/test-results/mixed-initialization-safety-3.cpp b/regression-tests/test-results/mixed-initialization-safety-3.cpp index d62ce7b0d..fa08e35a0 100644 --- a/regression-tests/test-results/mixed-initialization-safety-3.cpp +++ b/regression-tests/test-results/mixed-initialization-safety-3.cpp @@ -54,9 +54,9 @@ auto fill( ) -> void { - cpp2::Default.expects(cpp2::cmp_greater_eq(CPP2_UFCS_0(ssize, value),count), "fill: value must contain at least count elements"); + cpp2::Default.expects(cpp2::cmp_greater_eq(CPP2_UFCS(ssize)(value),count), "fill: value must contain at least count elements"); #line 23 "mixed-initialization-safety-3.cpp2" - x.construct(CPP2_UFCS(substr, value, 0, count)); + x.construct(CPP2_UFCS(substr)(value, 0, count)); } auto print_decorated(auto const& x) -> void { std::cout << ">> [" << x << "]\n"; } diff --git a/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp b/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp index a976c470b..3d89deba9 100644 --- a/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp +++ b/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp @@ -34,7 +34,7 @@ auto call_my_framework(char const* msg) -> void; #line 6 "mixed-lifetime-safety-and-null-contracts.cpp2" [[nodiscard]] auto main() -> int{ - CPP2_UFCS(set_handler, cpp2::Null, &call_my_framework); + CPP2_UFCS(set_handler)(cpp2::Null, &call_my_framework); try_pointer_stuff(); std::cout << "done\n"; } diff --git a/regression-tests/test-results/mixed-postexpression-with-capture.cpp b/regression-tests/test-results/mixed-postexpression-with-capture.cpp index 00557d279..c8183e365 100644 --- a/regression-tests/test-results/mixed-postexpression-with-capture.cpp +++ b/regression-tests/test-results/mixed-postexpression-with-capture.cpp @@ -40,9 +40,9 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void #line 17 "mixed-postexpression-with-capture.cpp2" { - cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), ""); - auto post_16_5 = cpp2::finally_success([_0 = CPP2_UFCS_0(size, vec)]{cpp2::Default.expects(CPP2_UFCS_0(size, vec)==_0 + 1, "");} ); + cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS(ssize)(vec)), ""); + auto post_16_5 = cpp2::finally_success([_0 = CPP2_UFCS(size)(vec)]{cpp2::Default.expects(CPP2_UFCS(size)(vec)==_0 + 1, "");} ); #line 18 "mixed-postexpression-with-capture.cpp2" - CPP2_UFCS(push_back, vec, val); + CPP2_UFCS(push_back)(vec, val); } diff --git a/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp b/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp index 81738a3b5..b571823c6 100644 --- a/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp +++ b/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp @@ -28,12 +28,12 @@ auto call([[maybe_unused]] auto const& param1, [[maybe_unused]] auto const& para [[nodiscard]] auto test(auto const& a) -> std::string{ return call(a, - ++*cpp2::assert_not_null(CPP2_UFCS(b, a, a.c)), "hello", /* polite + ++*cpp2::assert_not_null(CPP2_UFCS(b)(a, a.c)), "hello", /* polite greeting goes here */" there", - CPP2_UFCS(e, a.d, ++CPP2_UFCS_0(g, *cpp2::assert_not_null(a.f)), // because f is foobar - CPP2_UFCS_0(i, a.h), - CPP2_UFCS(j, a, a.k, a.l)) + CPP2_UFCS(e)(a.d, ++CPP2_UFCS(g)(*cpp2::assert_not_null(a.f)), // because f is foobar + CPP2_UFCS(i)(a.h), + CPP2_UFCS(j)(a, a.k, a.l)) ); } diff --git a/regression-tests/test-results/mixed-string-interpolation.cpp b/regression-tests/test-results/mixed-string-interpolation.cpp index 65bedf7f4..694dae0f5 100644 --- a/regression-tests/test-results/mixed-string-interpolation.cpp +++ b/regression-tests/test-results/mixed-string-interpolation.cpp @@ -30,7 +30,7 @@ struct custom_struct_with_no_stringize_customization { } custom; std::cout << "a = " + cpp2::to_string(a) + ", b = " + cpp2::to_string(b) + "\n"; b = 42; - std::cout << "a^2 + b = " + cpp2::to_string(a * std::move(a) + CPP2_UFCS_0(value, std::move(b))) + "\n"; + std::cout << "a^2 + b = " + cpp2::to_string(a * std::move(a) + CPP2_UFCS(value)(std::move(b))) + "\n"; std::string_view sv {"my string_view"}; std::cout << "sv = " + cpp2::to_string(std::move(sv)) + "\n"; diff --git a/regression-tests/test-results/mixed-type-safety-1.cpp b/regression-tests/test-results/mixed-type-safety-1.cpp index 4d07c63c3..01df586cf 100644 --- a/regression-tests/test-results/mixed-type-safety-1.cpp +++ b/regression-tests/test-results/mixed-type-safety-1.cpp @@ -55,7 +55,7 @@ auto print(cpp2::in msg, cpp2::in b) -> void print( "1 is int? ", cpp2::is(1)); auto c {cpp2_new()}; // safe by construction - Shape* s {CPP2_UFCS_0(get, c)}; // safe by Lifetime + Shape* s {CPP2_UFCS(get)(c)}; // safe by Lifetime print("\ns* is Shape? ", cpp2::is(*cpp2::assert_not_null(s))); print( "s* is Circle? ", cpp2::is(*cpp2::assert_not_null(s))); print( "s* is Square? ", cpp2::is(*cpp2::assert_not_null(std::move(s)))); diff --git a/regression-tests/test-results/mixed-ufcs-multiple-template-arguments.cpp b/regression-tests/test-results/mixed-ufcs-multiple-template-arguments.cpp index bf48ca606..142963d0d 100644 --- a/regression-tests/test-results/mixed-ufcs-multiple-template-arguments.cpp +++ b/regression-tests/test-results/mixed-ufcs-multiple-template-arguments.cpp @@ -39,6 +39,6 @@ struct X { std::cout << substr<4,8>(test_string) << "\n"; X x {test_string}; - std::cout << CPP2_UFCS_TEMPLATE_0(substr, (<4,8>), std::move(x)) << "\n"; + std::cout << CPP2_UFCS_TEMPLATE(substr<4,8>)(std::move(x)) << "\n"; } diff --git a/regression-tests/test-results/pure2-bounds-safety-span.cpp b/regression-tests/test-results/pure2-bounds-safety-span.cpp index b2e27887c..d32ef0c98 100644 --- a/regression-tests/test-results/pure2-bounds-safety-span.cpp +++ b/regression-tests/test-results/pure2-bounds-safety-span.cpp @@ -31,7 +31,7 @@ auto print_and_decorate(auto const& thing) -> void; std::span s {words}; auto i {0}; - for( ; cpp2::cmp_less(i,CPP2_UFCS_0(ssize, s)); ++i ) { + for( ; cpp2::cmp_less(i,CPP2_UFCS(ssize)(s)); ++i ) { print_and_decorate(cpp2::assert_in_bounds(s, i)); } } diff --git a/regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp b/regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp new file mode 100644 index 000000000..8765717b5 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp @@ -0,0 +1,104 @@ + +#define CPP2_USE_MODULES Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + + +#line 6 "pure2-bugfix-for-ufcs-arguments.cpp2" +class t; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-ufcs-arguments.cpp2" +[[nodiscard]] auto print_res(cpp2::in x) -> cpp2::i32; + + +#line 6 "pure2-bugfix-for-ufcs-arguments.cpp2" +class t { + public: [[nodiscard]] auto f() -> cpp2::i32; + public: [[nodiscard]] auto f(auto const& x) -> cpp2::i32; + public: template [[nodiscard]] auto f() -> cpp2::i32; + public: template [[nodiscard]] auto f(auto const& x) -> cpp2::i32; + public: template [[nodiscard]] auto f(auto const& x, auto const& y) -> cpp2::i32; + + public: t() = default; + public: t(t const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(t const&) -> void = delete; +#line 12 "pure2-bugfix-for-ufcs-arguments.cpp2" +}; +[[nodiscard]] auto f(cpp2::in o) -> cpp2::i32; +[[nodiscard]] auto f(cpp2::in o, auto const& x) -> cpp2::i32; +template [[nodiscard]] auto f(cpp2::in o) -> cpp2::i32; +template [[nodiscard]] auto f(cpp2::in o, auto const& x) -> cpp2::i32; +template [[nodiscard]] auto f(cpp2::in o, auto const& x, auto const& y) -> cpp2::i32; +extern t m; +extern t const n; +template auto const& a = n; +extern cpp2::i32 auto_21_1; +extern cpp2::i32 auto_22_1; +extern cpp2::i32 auto_23_1; +extern cpp2::i32 auto_24_1; +extern cpp2::i32 auto_25_1; +extern cpp2::i32 auto_26_1; +extern cpp2::i32 auto_27_1; +extern cpp2::i32 auto_28_1; +extern cpp2::i32 auto_29_1; +extern cpp2::i32 auto_30_1; +extern cpp2::i32 auto_31_1; +auto main() -> int; + + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-bugfix-for-ufcs-arguments.cpp2" +[[nodiscard]] auto print_res(cpp2::in x) -> cpp2::i32{ + std::cout << x; + if ((x==9)) {std::cout << '\n'; } + return x; +} + + [[nodiscard]] auto t::f() -> cpp2::i32 { return print_res(0); } + [[nodiscard]] auto t::f(auto const& x) -> cpp2::i32 { return print_res(1); } + template [[nodiscard]] auto t::f() -> cpp2::i32 { return print_res(2); } + template [[nodiscard]] auto t::f(auto const& x) -> cpp2::i32 { return print_res(3); } + template [[nodiscard]] auto t::f(auto const& x, auto const& y) -> cpp2::i32 { return print_res(4); } + +[[nodiscard]] auto f(cpp2::in o) -> cpp2::i32 { return print_res(5); } +[[nodiscard]] auto f(cpp2::in o, auto const& x) -> cpp2::i32 { return print_res(6); } +template [[nodiscard]] auto f(cpp2::in o) -> cpp2::i32 { return print_res(7); } +template [[nodiscard]] auto f(cpp2::in o, auto const& x) -> cpp2::i32 { return print_res(8); } +template [[nodiscard]] auto f(cpp2::in o, auto const& x, auto const& y) -> cpp2::i32 { return print_res(9); } +t m {}; +t const n {}; + +cpp2::i32 auto_21_1 {CPP2_UFCS_NONLOCAL(f)(m)}; +cpp2::i32 auto_22_1 {CPP2_UFCS_NONLOCAL(f)(m, 0)}; +cpp2::i32 auto_23_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(m)}; +cpp2::i32 auto_24_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(m, 0)}; +cpp2::i32 auto_25_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(m, 0, 0)}; +cpp2::i32 auto_26_1 {CPP2_UFCS_NONLOCAL(f)(n)}; +cpp2::i32 auto_27_1 {CPP2_UFCS_NONLOCAL(f)(n, 0)}; +cpp2::i32 auto_28_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(n)}; +cpp2::i32 auto_29_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(n, 0)}; +cpp2::i32 auto_30_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(n, 0, 0)}; +cpp2::i32 auto_31_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(a, 0, 0)}; +auto main() -> int{ + cpp2::i32 auto_33_3 {CPP2_UFCS(f)(m)}; + cpp2::i32 auto_34_3 {CPP2_UFCS(f)(m, 0)}; + cpp2::i32 auto_35_3 {CPP2_UFCS_TEMPLATE(f)(m)}; + cpp2::i32 auto_36_3 {CPP2_UFCS_TEMPLATE(f)(m, 0)}; + cpp2::i32 auto_37_3 {CPP2_UFCS_TEMPLATE(f)(m, 0, 0)}; + cpp2::i32 auto_38_3 {CPP2_UFCS(f)(n)}; + cpp2::i32 auto_39_3 {CPP2_UFCS(f)(n, 0)}; + cpp2::i32 auto_40_3 {CPP2_UFCS_TEMPLATE(f)(n)}; + cpp2::i32 auto_41_3 {CPP2_UFCS_TEMPLATE(f)(n, 0)}; + cpp2::i32 auto_42_3 {CPP2_UFCS_TEMPLATE(f)(n, 0, 0)}; + cpp2::i32 auto_43_3 {CPP2_UFCS_TEMPLATE(f)(a, 0, 0)}; + + static_cast([](auto const& a, auto const& f) -> void{static_cast(CPP2_UFCS(f)(CPP2_UFCS(f)(a, a))); }); +} + diff --git a/regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp2.output new file mode 100644 index 000000000..e230534bf --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-ufcs-arguments.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp b/regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp new file mode 100644 index 000000000..23373e894 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp @@ -0,0 +1,36 @@ + +#define CPP2_USE_MODULES Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-bugfix-for-ufcs-noexcept.cpp2" +class t; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-ufcs-noexcept.cpp2" +class t { + public: auto swap([[maybe_unused]] t const& that) noexcept -> void; + + public: t() = default; + public: t(t const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(t const&) -> void = delete; +#line 3 "pure2-bugfix-for-ufcs-noexcept.cpp2" +}; +auto main() -> int; + + +//=== Cpp2 function definitions ================================================= + + +#line 2 "pure2-bugfix-for-ufcs-noexcept.cpp2" + auto t::swap([[maybe_unused]] t const& that) noexcept -> void{} + +auto main() -> int{ + // static_assert(noexcept(t().swap(t()))); // Blocked on Clang 12 (lambda in unevaluated context). +} + diff --git a/regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp2.output new file mode 100644 index 000000000..6ff4d0ebb --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-ufcs-noexcept.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp b/regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp new file mode 100644 index 000000000..4e7b2e51b --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp @@ -0,0 +1,35 @@ + +#define CPP2_USE_MODULES Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + + +#line 2 "pure2-bugfix-for-ufcs-sfinae.cpp2" +class B; + + +//=== Cpp2 type definitions and function declarations =========================== + +// f: () -> std::type_identity_t = { } // Blocked on Clang 12 (lambda in unevaluated context). +#line 2 "pure2-bugfix-for-ufcs-sfinae.cpp2" +class B { + public: B() = default; + public: B(B const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(B const&) -> void = delete; + +#line 2 "pure2-bugfix-for-ufcs-sfinae.cpp2" + }; +auto main() -> int; + + +//=== Cpp2 function definitions ================================================= + + +#line 3 "pure2-bugfix-for-ufcs-sfinae.cpp2" +auto main() -> int { + // static_assert(!std::invocable (x: T) -> std::void_t())> = {}), B>); // Blocked on Clang 12 (lambda in unevaluated context). +} + diff --git a/regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp2.output new file mode 100644 index 000000000..9d817f307 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-ufcs-sfinae.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/regression-tests/test-results/pure2-initialization-safety-with-else-if.cpp b/regression-tests/test-results/pure2-initialization-safety-with-else-if.cpp index 406dafcf1..843820940 100644 --- a/regression-tests/test-results/pure2-initialization-safety-with-else-if.cpp +++ b/regression-tests/test-results/pure2-initialization-safety-with-else-if.cpp @@ -27,10 +27,10 @@ auto main(int const argc_, char const* const* const argv_) -> int{ auto c {3}; auto d {4}; - if (CPP2_UFCS_0(size, args)==3) { + if (CPP2_UFCS(size)(args)==3) { p.construct(&a); }else {if (true) { - if (CPP2_UFCS_0(size, args)==2) { + if (CPP2_UFCS(size)(args)==2) { p.construct(&c); }else {if (cpp2::cmp_greater(std::move(b),0)) { p.construct(&a); diff --git a/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp b/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp index 2ed00133c..4415c4a42 100644 --- a/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp +++ b/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp @@ -31,7 +31,7 @@ auto test_generic(auto const& x, auto const& msg) -> void; test_generic(a, "any"); test_generic(o, "optional"); - static_cast(CPP2_UFCS_TEMPLATE(emplace, (<0>), v, 1)); + static_cast(CPP2_UFCS_TEMPLATE(emplace<0>)(v, 1)); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/test-results/pure2-intro-example-hello-2022.cpp b/regression-tests/test-results/pure2-intro-example-hello-2022.cpp index 1ae920723..25059f3c4 100644 --- a/regression-tests/test-results/pure2-intro-example-hello-2022.cpp +++ b/regression-tests/test-results/pure2-intro-example-hello-2022.cpp @@ -38,7 +38,7 @@ auto println(auto const& x, auto const& len) -> void; [[nodiscard]] auto decorate(auto& thing) -> int{ thing = "[" + thing + "]"; - return CPP2_UFCS_0(ssize, thing); + return CPP2_UFCS(ssize)(thing); } auto println(auto const& x, auto const& len) -> void { diff --git a/regression-tests/test-results/pure2-intro-example-three-loops.cpp b/regression-tests/test-results/pure2-intro-example-three-loops.cpp index 327e5e0c2..fe8cbefc1 100644 --- a/regression-tests/test-results/pure2-intro-example-three-loops.cpp +++ b/regression-tests/test-results/pure2-intro-example-three-loops.cpp @@ -43,7 +43,7 @@ auto decorate_and_print(auto& thing) -> void{ std::span view {words}; auto i {cpp2_new(0)}; - for( ; cpp2::cmp_less(*cpp2::assert_not_null(i),CPP2_UFCS_0(ssize, view)); ++*cpp2::assert_not_null(i) ) { + for( ; cpp2::cmp_less(*cpp2::assert_not_null(i),CPP2_UFCS(ssize)(view)); ++*cpp2::assert_not_null(i) ) { print(cpp2::assert_in_bounds(view, *cpp2::assert_not_null(i))); } diff --git a/regression-tests/test-results/pure2-stdio-with-raii.cpp b/regression-tests/test-results/pure2-stdio-with-raii.cpp index a26a085d3..d1e67e114 100644 --- a/regression-tests/test-results/pure2-stdio-with-raii.cpp +++ b/regression-tests/test-results/pure2-stdio-with-raii.cpp @@ -24,6 +24,6 @@ [[nodiscard]] auto main() -> int{ std::string s {"Freddy"}; auto myfile {cpp2::fopen("xyzzy", "w")}; - static_cast(CPP2_UFCS(fprintf, std::move(myfile), "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s)))); + static_cast(CPP2_UFCS(fprintf)(std::move(myfile), "Hello %s with UFCS!", CPP2_UFCS(c_str)(std::move(s)))); } diff --git a/regression-tests/test-results/pure2-stdio.cpp b/regression-tests/test-results/pure2-stdio.cpp index 42a142f90..986e8ca01 100644 --- a/regression-tests/test-results/pure2-stdio.cpp +++ b/regression-tests/test-results/pure2-stdio.cpp @@ -27,7 +27,7 @@ [[nodiscard]] auto main() -> int{ std::string s {"Fred"}; auto myfile {fopen("xyzzy", "w")}; - static_cast(CPP2_UFCS(fprintf, myfile, "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s)))); - static_cast(CPP2_UFCS_0(fclose, std::move(myfile))); + static_cast(CPP2_UFCS(fprintf)(myfile, "Hello %s with UFCS!", CPP2_UFCS(c_str)(std::move(s)))); + static_cast(CPP2_UFCS(fclose)(std::move(myfile))); } diff --git a/regression-tests/test-results/pure2-type-safety-1.cpp b/regression-tests/test-results/pure2-type-safety-1.cpp index 15f79465c..aa4effac0 100644 --- a/regression-tests/test-results/pure2-type-safety-1.cpp +++ b/regression-tests/test-results/pure2-type-safety-1.cpp @@ -42,7 +42,7 @@ auto print(cpp2::in msg, cpp2::in b) -> void; std::cout << "\n"; - static_cast(CPP2_UFCS_TEMPLATE(emplace, (<1>), v, 1)); + static_cast(CPP2_UFCS_TEMPLATE(emplace<1>)(v, 1)); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp b/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp index b190252a5..ddc6b5db2 100644 --- a/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp +++ b/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp @@ -31,7 +31,7 @@ auto test_generic(auto const& x, auto const& msg) -> void; test_generic(a, "any"); test_generic(o, "optional"); - static_cast(CPP2_UFCS_TEMPLATE(emplace, (<2>), v, 1)); + static_cast(CPP2_UFCS_TEMPLATE(emplace<2>)(v, 1)); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/test-results/pure2-types-basics.cpp b/regression-tests/test-results/pure2-types-basics.cpp index eeca3e2f6..31ad0a961 100644 --- a/regression-tests/test-results/pure2-types-basics.cpp +++ b/regression-tests/test-results/pure2-types-basics.cpp @@ -183,19 +183,19 @@ namespace N { auto main() -> int{ N::myclass x {1}; - CPP2_UFCS(f, x, 53); + CPP2_UFCS(f)(x, 53); N::myclass::nested::g(); - std::cout << "f1: " + cpp2::to_string(CPP2_UFCS(f1, x, 1, 1)) + "\n"; - std::cout << "f2: " + cpp2::to_string(CPP2_UFCS(f2, x, 2, 2)) + "\n"; - std::cout << "f3: " + cpp2::to_string(CPP2_UFCS_TEMPLATE_0(f3, (<3,3>), x)) + "\n"; - std::cout << "f4: " + cpp2::to_string(CPP2_UFCS_TEMPLATE_0(f4, (<4,4>), x)) + "\n"; + std::cout << "f1: " + cpp2::to_string(CPP2_UFCS(f1)(x, 1, 1)) + "\n"; + std::cout << "f2: " + cpp2::to_string(CPP2_UFCS(f2)(x, 2, 2)) + "\n"; + std::cout << "f3: " + cpp2::to_string(CPP2_UFCS_TEMPLATE(f3<3,3>)(x)) + "\n"; + std::cout << "f4: " + cpp2::to_string(CPP2_UFCS_TEMPLATE(f4<4,4>)(x)) + "\n"; N::myclass x2 {"abracadabra"}; N::myclass x3 {}; N::myclass x4 {1, "hair"}; // Invoke the single-param operator=s as actual assignments std::cout << "x's state before assignments: "; - CPP2_UFCS_0(print, x); + CPP2_UFCS(print)(x); x = 84; x = "syzygy"; x = 84; diff --git a/regression-tests/test-results/pure2-types-inheritance.cpp b/regression-tests/test-results/pure2-types-inheritance.cpp index 77765240a..1ffd999c6 100644 --- a/regression-tests/test-results/pure2-types-inheritance.cpp +++ b/regression-tests/test-results/pure2-types-inheritance.cpp @@ -132,18 +132,18 @@ namespace N { #line 38 "pure2-types-inheritance.cpp2" auto make_speak(cpp2::in h) -> void{ std::cout << "-> [vcall: make_speak] "; - CPP2_UFCS_0(speak, h); + CPP2_UFCS(speak)(h); } auto do_work(cpp2::in> m) -> void{ std::cout << "-> [vcall: do_work] "; - CPP2_UFCS_0(work, m); + CPP2_UFCS(work)(m); } auto main() -> int{ Cyborg c {"Parsnip"}; - CPP2_UFCS_0(print, c); - CPP2_UFCS_0(make_speak, c); - CPP2_UFCS_0(do_work, std::move(c)); + CPP2_UFCS(print)(c); + CPP2_UFCS(make_speak)(c); + CPP2_UFCS(do_work)(std::move(c)); } diff --git a/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp b/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp index 2020cd3b2..8cb7a5aec 100644 --- a/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp +++ b/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp @@ -155,7 +155,7 @@ namespace N { // Exercise '_' anonymous objects too while we're at it cpp2::finally auto_37_9 {[&]() -> void { std::cout << "leaving call to 'why(" + cpp2::to_string(count) + ")'\n"; }}; if (cpp2::cmp_less(count,5)) { - CPP2_UFCS(why, (*cpp2::assert_not_null(py)), count + 1);// use Y object from X + CPP2_UFCS(why)((*cpp2::assert_not_null(py)), count + 1);// use Y object from X } } @@ -172,7 +172,7 @@ namespace N { } auto Y::why(cpp2::in count) const -> void { - CPP2_UFCS(exx, (*cpp2::assert_not_null(px)), count + 1); }// use X object from Y + CPP2_UFCS(exx)((*cpp2::assert_not_null(px)), count + 1); }// use X object from Y #line 55 "pure2-types-order-independence-and-nesting.cpp2" namespace M { @@ -192,7 +192,7 @@ auto main() -> int N::X x {cpp2::out(&y)}; // construct y and x, and point them at each other // now have the two objects call each other back and forth a few times - CPP2_UFCS(exx, std::move(x), 1); + CPP2_UFCS(exx)(std::move(x), 1); // and test a nested template out-of-line definition N::M::A::B<42>::f("welt"); diff --git a/regression-tests/test-results/pure2-types-smf-and-that-1-provide-everything.cpp b/regression-tests/test-results/pure2-types-smf-and-that-1-provide-everything.cpp index a96af4b6e..0ac135b94 100644 --- a/regression-tests/test-results/pure2-types-smf-and-that-1-provide-everything.cpp +++ b/regression-tests/test-results/pure2-types-smf-and-that-1-provide-everything.cpp @@ -127,24 +127,24 @@ auto main() -> int{ std::cout << "---------------------- ------------ ------------------------------------------------------\n"; myclass x {"Henry"}; - CPP2_UFCS(print, x, " construct ", "\n"); + CPP2_UFCS(print)(x, " construct ", "\n"); x = "Clara"; - CPP2_UFCS(print, x, " assign ", "\n"); + CPP2_UFCS(print)(x, " assign ", "\n"); auto y {x}; - CPP2_UFCS(print, y, " cp-construct ", " <- "); - CPP2_UFCS(print, x, "", "\n"); + CPP2_UFCS(print)(y, " cp-construct ", " <- "); + CPP2_UFCS(print)(x, "", "\n"); auto z {std::move(x)}; - CPP2_UFCS(print, z, " mv-construct ", " <- "); - CPP2_UFCS(print, std::move(x), "", "\n"); + CPP2_UFCS(print)(z, " mv-construct ", " <- "); + CPP2_UFCS(print)(std::move(x), "", "\n"); z = y; - CPP2_UFCS(print, z, " cp-assign ", " <- "); - CPP2_UFCS(print, y, "", "\n"); + CPP2_UFCS(print)(z, " cp-assign ", " <- "); + CPP2_UFCS(print)(y, "", "\n"); z = { std::move(y) }; - CPP2_UFCS(print, std::move(z), " mv-assign ", " <- "); - CPP2_UFCS(print, std::move(y), "", "\n"); + CPP2_UFCS(print)(std::move(z), " mv-assign ", " <- "); + CPP2_UFCS(print)(std::move(y), "", "\n"); } diff --git a/regression-tests/test-results/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp b/regression-tests/test-results/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp index 40645f9d8..9bb94aed8 100644 --- a/regression-tests/test-results/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp +++ b/regression-tests/test-results/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp @@ -132,24 +132,24 @@ auto main() -> int{ std::cout << "---------------------- ------------ ------------------------------------------------------\n"; myclass x {"Henry"}; - CPP2_UFCS(print, x, " construct ", "\n"); + CPP2_UFCS(print)(x, " construct ", "\n"); x = "Clara"; - CPP2_UFCS(print, x, " assign ", "\n"); + CPP2_UFCS(print)(x, " assign ", "\n"); auto y {x}; - CPP2_UFCS(print, y, " cp-construct ", " <- "); - CPP2_UFCS(print, x, "", "\n"); + CPP2_UFCS(print)(y, " cp-construct ", " <- "); + CPP2_UFCS(print)(x, "", "\n"); auto z {std::move(x)}; - CPP2_UFCS(print, z, " mv-construct ", " <- "); - CPP2_UFCS(print, std::move(x), "", "\n"); + CPP2_UFCS(print)(z, " mv-construct ", " <- "); + CPP2_UFCS(print)(std::move(x), "", "\n"); z = y; - CPP2_UFCS(print, z, " cp-assign ", " <- "); - CPP2_UFCS(print, y, "", "\n"); + CPP2_UFCS(print)(z, " cp-assign ", " <- "); + CPP2_UFCS(print)(y, "", "\n"); z = { std::move(y) }; - CPP2_UFCS(print, std::move(z), " mv-assign ", " <- "); - CPP2_UFCS(print, std::move(y), "", "\n"); + CPP2_UFCS(print)(std::move(z), " mv-assign ", " <- "); + CPP2_UFCS(print)(std::move(y), "", "\n"); } diff --git a/regression-tests/test-results/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp b/regression-tests/test-results/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp index 50b518b03..aeea6e3a0 100644 --- a/regression-tests/test-results/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp +++ b/regression-tests/test-results/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp @@ -131,24 +131,24 @@ auto main() -> int{ std::cout << "---------------------- ------------ ------------------------------------------------------\n"; myclass x {"Henry"}; - CPP2_UFCS(print, x, " construct ", "\n"); + CPP2_UFCS(print)(x, " construct ", "\n"); x = "Clara"; - CPP2_UFCS(print, x, " assign ", "\n"); + CPP2_UFCS(print)(x, " assign ", "\n"); auto y {x}; - CPP2_UFCS(print, y, " cp-construct ", " <- "); - CPP2_UFCS(print, x, "", "\n"); + CPP2_UFCS(print)(y, " cp-construct ", " <- "); + CPP2_UFCS(print)(x, "", "\n"); auto z {std::move(x)}; - CPP2_UFCS(print, z, " mv-construct ", " <- "); - CPP2_UFCS(print, std::move(x), "", "\n"); + CPP2_UFCS(print)(z, " mv-construct ", " <- "); + CPP2_UFCS(print)(std::move(x), "", "\n"); z = y; - CPP2_UFCS(print, z, " cp-assign ", " <- "); - CPP2_UFCS(print, y, "", "\n"); + CPP2_UFCS(print)(z, " cp-assign ", " <- "); + CPP2_UFCS(print)(y, "", "\n"); z = { std::move(y) }; - CPP2_UFCS(print, std::move(z), " mv-assign ", " <- "); - CPP2_UFCS(print, std::move(y), "", "\n"); + CPP2_UFCS(print)(std::move(z), " mv-assign ", " <- "); + CPP2_UFCS(print)(std::move(y), "", "\n"); } diff --git a/regression-tests/test-results/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp b/regression-tests/test-results/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp index 36701ed1c..b0d670dc9 100644 --- a/regression-tests/test-results/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp +++ b/regression-tests/test-results/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp @@ -131,24 +131,24 @@ auto main() -> int{ std::cout << "---------------------- ------------ ------------------------------------------------------\n"; myclass x {"Henry"}; - CPP2_UFCS(print, x, " construct ", "\n"); + CPP2_UFCS(print)(x, " construct ", "\n"); x = "Clara"; - CPP2_UFCS(print, x, " assign ", "\n"); + CPP2_UFCS(print)(x, " assign ", "\n"); auto y {x}; - CPP2_UFCS(print, y, " cp-construct ", " <- "); - CPP2_UFCS(print, x, "", "\n"); + CPP2_UFCS(print)(y, " cp-construct ", " <- "); + CPP2_UFCS(print)(x, "", "\n"); auto z {std::move(x)}; - CPP2_UFCS(print, z, " mv-construct ", " <- "); - CPP2_UFCS(print, std::move(x), "", "\n"); + CPP2_UFCS(print)(z, " mv-construct ", " <- "); + CPP2_UFCS(print)(std::move(x), "", "\n"); z = y; - CPP2_UFCS(print, z, " cp-assign ", " <- "); - CPP2_UFCS(print, y, "", "\n"); + CPP2_UFCS(print)(z, " cp-assign ", " <- "); + CPP2_UFCS(print)(y, "", "\n"); z = { std::move(y) }; - CPP2_UFCS(print, std::move(z), " mv-assign ", " <- "); - CPP2_UFCS(print, std::move(y), "", "\n"); + CPP2_UFCS(print)(std::move(z), " mv-assign ", " <- "); + CPP2_UFCS(print)(std::move(y), "", "\n"); } diff --git a/regression-tests/test-results/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp b/regression-tests/test-results/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp index 7c2754bfa..c50307f95 100644 --- a/regression-tests/test-results/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp +++ b/regression-tests/test-results/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp @@ -137,24 +137,24 @@ auto main() -> int{ std::cout << "---------------------- ------------ ------------------------------------------------------\n"; myclass x {"Henry"}; - CPP2_UFCS(print, x, " construct ", "\n"); + CPP2_UFCS(print)(x, " construct ", "\n"); x = "Clara"; - CPP2_UFCS(print, x, " assign ", "\n"); + CPP2_UFCS(print)(x, " assign ", "\n"); auto y {x}; - CPP2_UFCS(print, y, " cp-construct ", " <- "); - CPP2_UFCS(print, x, "", "\n"); + CPP2_UFCS(print)(y, " cp-construct ", " <- "); + CPP2_UFCS(print)(x, "", "\n"); auto z {std::move(x)}; - CPP2_UFCS(print, z, " mv-construct ", " <- "); - CPP2_UFCS(print, std::move(x), "", "\n"); + CPP2_UFCS(print)(z, " mv-construct ", " <- "); + CPP2_UFCS(print)(std::move(x), "", "\n"); z = y; - CPP2_UFCS(print, z, " cp-assign ", " <- "); - CPP2_UFCS(print, y, "", "\n"); + CPP2_UFCS(print)(z, " cp-assign ", " <- "); + CPP2_UFCS(print)(y, "", "\n"); z = { std::move(y) }; - CPP2_UFCS(print, std::move(z), " mv-assign ", " <- "); - CPP2_UFCS(print, std::move(y), "", "\n"); + CPP2_UFCS(print)(std::move(z), " mv-assign ", " <- "); + CPP2_UFCS(print)(std::move(y), "", "\n"); } diff --git a/regression-tests/test-results/pure2-types-that-parameters.cpp b/regression-tests/test-results/pure2-types-that-parameters.cpp index cdbc3bbe3..9bc056281 100644 --- a/regression-tests/test-results/pure2-types-that-parameters.cpp +++ b/regression-tests/test-results/pure2-types-that-parameters.cpp @@ -92,16 +92,16 @@ auto main() -> int; #line 25 "pure2-types-that-parameters.cpp2" auto main() -> int{ myclass x {}; - CPP2_UFCS_0(print, x); + CPP2_UFCS(print)(x); std::cout << "-----\n"; auto y {x}; - CPP2_UFCS_0(print, x); - CPP2_UFCS_0(print, std::move(y)); + CPP2_UFCS(print)(x); + CPP2_UFCS(print)(std::move(y)); std::cout << "-----\n"; auto z {std::move(x)}; - CPP2_UFCS_0(print, std::move(x)); - CPP2_UFCS_0(print, std::move(z)); + CPP2_UFCS(print)(std::move(x)); + CPP2_UFCS(print)(std::move(z)); } diff --git a/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp b/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp index 86a875ca3..430221b47 100644 --- a/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp +++ b/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp @@ -40,25 +40,25 @@ extern int y; #line 1 "pure2-ufcs-member-access-and-chaining.cpp2" [[nodiscard]] auto main() -> int{ auto i {42}; - static_cast(CPP2_UFCS_0(ufcs, std::move(i))); + static_cast(CPP2_UFCS(ufcs)(std::move(i))); auto j {fun()}; - static_cast(CPP2_UFCS_0(ufcs, j.i)); + static_cast(CPP2_UFCS(ufcs)(j.i)); - static_cast(CPP2_UFCS_0(ufcs, fun().i)); + static_cast(CPP2_UFCS(ufcs)(fun().i)); auto k {fun().i}; - static_cast(CPP2_UFCS_0(ufcs, std::move(k))); + static_cast(CPP2_UFCS(ufcs)(std::move(k))); - static_cast(CPP2_UFCS_0(ufcs, get_i(j))); + static_cast(CPP2_UFCS(ufcs)(get_i(j))); - static_cast(CPP2_UFCS_0(ufcs, get_i(fun()))); + static_cast(CPP2_UFCS(ufcs)(get_i(fun()))); - auto res {CPP2_UFCS_0(ufcs, (42))}; + auto res {CPP2_UFCS(ufcs)((42))}; - static_cast(CPP2_UFCS_0(ufcs, (std::move(j).i))); + static_cast(CPP2_UFCS(ufcs)((std::move(j).i))); - CPP2_UFCS_0(no_return, 42); + CPP2_UFCS(no_return)(42); } auto no_return([[maybe_unused]] auto const& param1) -> void{} @@ -80,5 +80,5 @@ auto no_return([[maybe_unused]] auto const& param1) -> void{} #line 40 "pure2-ufcs-member-access-and-chaining.cpp2" [[nodiscard]] auto f([[maybe_unused]] auto const& param1) -> int { return 0; } -int y {CPP2_UFCS_0_NONLOCAL(f, 0)}; +int y {CPP2_UFCS_NONLOCAL(f)(0)}; diff --git a/source/cppfront.cpp b/source/cppfront.cpp index 8ce4aca99..d29ae9fa8 100644 --- a/source/cppfront.cpp +++ b/source/cppfront.cpp @@ -1004,6 +1004,8 @@ class cppfront bool violates_initialization_safety = false; bool suppress_move_from_last_use = false; + declaration_node const* having_signature_emitted = {}; + declaration_node const* generating_assignment_from = {}; declaration_node const* generating_move_from = {}; bool emitting_that_function = false; @@ -2941,17 +2943,6 @@ class cppfront // If there are template arguments, use the _TEMPLATE version if (i->id_expr->template_args_count() > 0) { ufcs_string += "_TEMPLATE"; - // we need to replace "fun" to "fun, ()" to be able to generate - // from obj.fun(1,2) this CPP2_UFCS_TEMPLATE(fun, (), obj, 1, 2) - auto split = funcname.find('<'); assert(split != std::string::npos); - funcname.insert(split, ", ("); - assert(funcname.back() == '>'); - funcname += ')'; - } - - // If there are no additional arguments, use the _0 version - if (args.value().text_chunks.empty()) { - ufcs_string += "_0"; } // If we're in an object declaration (i.e., initializer) @@ -2963,7 +2954,14 @@ class cppfront if ( current_declarations.back()->is_namespace() || ( - current_declarations.back()->is_object() + ( + current_declarations.back()->is_object() + || current_declarations.back()->is_alias() + || ( + current_declarations.back()->is_function() + && current_declarations.back() == having_signature_emitted + ) + ) && current_declarations.back()->parent_is_namespace() ) ) @@ -2973,7 +2971,7 @@ class cppfront // Second, emit the UFCS argument list - prefix.emplace_back(ufcs_string + "(" + funcname + ", ", args.value().open_pos ); + prefix.emplace_back(ufcs_string + "(" + funcname + ")(", args.value().open_pos ); suffix.emplace_back(")", args.value().close_pos ); if (!args.value().text_chunks.empty()) { for (auto&& e: args.value().text_chunks) { @@ -4899,6 +4897,16 @@ class cppfront printer.print_extra("\n"); } + auto stack_value = [](T& var, std::type_identity_t const& value) { + return finally([&var, old = std::exchange(var, value)]() { + var = old; + }); + }; + auto stack = stack_value(having_signature_emitted, &n); + + current_declarations.push_back(&n); + auto guard = finally([&]{ current_declarations.pop_back(); }); + // Handle aliases if (n.is_alias()) @@ -5012,9 +5020,6 @@ class cppfront return; } - current_declarations.push_back(&n); - auto guard = finally([&]{ current_declarations.pop_back(); }); - // If this is a function that has multiple return values, // first we need to emit the struct that contains the returns if ( @@ -5690,7 +5695,8 @@ class cppfront function_returns.emplace_back(nullptr); // no return type at all } - for (auto&& c : func->contracts) + for (auto stack = stack_value(having_signature_emitted, nullptr); + auto&& c : func->contracts) { auto print = std::string(); printer.emit_to_string(&print); @@ -5757,6 +5763,7 @@ class cppfront emit_requires_clause(); + having_signature_emitted = nullptr; emit( *n.initializer, true, func->position(), func->returns.index() == function_type_node::empty, diff --git a/source/reflect.h b/source/reflect.h index 4fb124920..95f7c439d 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -729,49 +729,49 @@ namespace meta { ) -> std::unique_ptr { - CPP2_UFCS(push_back, generated_lines, std::vector()); - auto lines {&CPP2_UFCS_0(back, generated_lines)}; + CPP2_UFCS(push_back)(generated_lines, std::vector()); + auto lines {&CPP2_UFCS(back)(generated_lines)}; auto add_line {[&, _1 = lines](cpp2::in s) -> void{ - (void) CPP2_UFCS(emplace_back, (*cpp2::assert_not_null(_1)), s, source_line::category::cpp2); + static_cast(CPP2_UFCS(emplace_back)((*cpp2::assert_not_null(_1)), s, source_line::category::cpp2)); }}; { -auto newline_pos = CPP2_UFCS(find, source, '\n'); +auto newline_pos = CPP2_UFCS(find)(source, '\n'); // First split this string into source_lines // #line 72 "reflect.h2" - if ( cpp2::cmp_greater(CPP2_UFCS_0(ssize, source),1) + if ( cpp2::cmp_greater(CPP2_UFCS(ssize)(source),1) && newline_pos!=source.npos) { while( newline_pos!=std::string_view::npos ) { - add_line(CPP2_UFCS(substr, source, 0, newline_pos)); - CPP2_UFCS(remove_prefix, source, newline_pos + 1); - newline_pos = CPP2_UFCS(find, source, '\n'); + add_line(CPP2_UFCS(substr)(source, 0, newline_pos)); + CPP2_UFCS(remove_prefix)(source, newline_pos + 1); + newline_pos = CPP2_UFCS(find)(source, '\n'); } } } #line 83 "reflect.h2" - if (!(CPP2_UFCS_0(empty, source))) { + if (!(CPP2_UFCS(empty)(source))) { std::move(add_line)(std::move(source)); } // Now lex this source fragment to generate // a single grammar_map entry, whose .second // is the vector of tokens - (void) CPP2_UFCS(emplace_back, generated_lexers, *cpp2::assert_not_null(errors)); - auto tokens {&CPP2_UFCS_0(back, generated_lexers)}; - CPP2_UFCS(lex, (*cpp2::assert_not_null(tokens)), *cpp2::assert_not_null(std::move(lines)), true); + static_cast(CPP2_UFCS(emplace_back)(generated_lexers, *cpp2::assert_not_null(errors))); + auto tokens {&CPP2_UFCS(back)(generated_lexers)}; + CPP2_UFCS(lex)((*cpp2::assert_not_null(tokens)), *cpp2::assert_not_null(std::move(lines)), true); - cpp2::Default.expects(std::ssize(CPP2_UFCS_0(get_map, (*cpp2::assert_not_null(tokens))))==1, ""); + cpp2::Default.expects(std::ssize(CPP2_UFCS(get_map)((*cpp2::assert_not_null(tokens))))==1, ""); // Now parse this single declaration from // the lexed tokens - return CPP2_UFCS(parse_one_declaration, parser, - (*cpp2::assert_not_null(CPP2_UFCS_0(begin, CPP2_UFCS_0(get_map, *cpp2::assert_not_null(std::move(tokens)))))).second, + return CPP2_UFCS(parse_one_declaration)(parser, + (*cpp2::assert_not_null(CPP2_UFCS(begin)(CPP2_UFCS(get_map)(*cpp2::assert_not_null(std::move(tokens)))))).second, *cpp2::assert_not_null(generated_tokens) ); } @@ -796,10 +796,10 @@ auto newline_pos = CPP2_UFCS(find, source, '\n'); auto compiler_services::error(cpp2::in msg) const -> void { auto message {cpp2::as_(msg)}; - if (!(CPP2_UFCS_0(empty, meta_function_name))) { + if (!(CPP2_UFCS(empty)(meta_function_name))) { message = "while applying @" + meta_function_name + " - " + message; } - (void) CPP2_UFCS(emplace_back, (*cpp2::assert_not_null(errors)), position(), std::move(message)); + static_cast(CPP2_UFCS(emplace_back)((*cpp2::assert_not_null(errors)), position(), std::move(message))); } compiler_services::~compiler_services() noexcept{} @@ -825,7 +825,7 @@ compiler_services::compiler_services(compiler_services const& that) cpp2::Default.expects(n, "a meta::declaration must point to a valid declaration_node, not null"); } - [[nodiscard]] auto declaration_base::position() const -> source_position { return CPP2_UFCS_0(position, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration_base::position() const -> source_position { return CPP2_UFCS(position)((*cpp2::assert_not_null(n))); } declaration_base::~declaration_base() noexcept{} declaration_base::declaration_base(declaration_base const& that) @@ -844,50 +844,50 @@ declaration_base::declaration_base(declaration_base const& that) } - [[nodiscard]] auto declaration::is_public() const -> bool { return CPP2_UFCS_0(is_public, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_protected() const -> bool { return CPP2_UFCS_0(is_protected, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_private() const -> bool { return CPP2_UFCS_0(is_private, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_default_access() const -> bool { return CPP2_UFCS_0(is_default_access, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_public() const -> bool { return CPP2_UFCS(is_public)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_protected() const -> bool { return CPP2_UFCS(is_protected)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_private() const -> bool { return CPP2_UFCS(is_private)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_default_access() const -> bool { return CPP2_UFCS(is_default_access)((*cpp2::assert_not_null(n))); } - auto declaration::default_to_public() -> void { (void) CPP2_UFCS_0(make_public, (*cpp2::assert_not_null(n))); } - auto declaration::default_to_protected() -> void { (void) CPP2_UFCS_0(make_protected, (*cpp2::assert_not_null(n))); } - auto declaration::default_to_private() -> void { (void) CPP2_UFCS_0(make_private, (*cpp2::assert_not_null(n))); } + auto declaration::default_to_public() -> void { static_cast(CPP2_UFCS(make_public)((*cpp2::assert_not_null(n)))); } + auto declaration::default_to_protected() -> void { static_cast(CPP2_UFCS(make_protected)((*cpp2::assert_not_null(n)))); } + auto declaration::default_to_private() -> void { static_cast(CPP2_UFCS(make_private)((*cpp2::assert_not_null(n)))); } - [[nodiscard]] auto declaration::make_public() -> bool { return CPP2_UFCS_0(make_public, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::make_protected() -> bool { return CPP2_UFCS_0(make_protected, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::make_private() -> bool { return CPP2_UFCS_0(make_private, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::make_public() -> bool { return CPP2_UFCS(make_public)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::make_protected() -> bool { return CPP2_UFCS(make_protected)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::make_private() -> bool { return CPP2_UFCS(make_private)((*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::has_name() const -> bool { return CPP2_UFCS_0(has_name, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::has_name(cpp2::in s) const -> bool { return CPP2_UFCS(has_name, (*cpp2::assert_not_null(n)), s); } + [[nodiscard]] auto declaration::has_name() const -> bool { return CPP2_UFCS(has_name)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::has_name(cpp2::in s) const -> bool { return CPP2_UFCS(has_name)((*cpp2::assert_not_null(n)), s); } [[nodiscard]] auto declaration::name() const -> std::string_view{ - if (has_name()) {return CPP2_UFCS_0(as_string_view, (*cpp2::assert_not_null(CPP2_UFCS_0(name, *cpp2::assert_not_null(n))))); } + if (has_name()) {return CPP2_UFCS(as_string_view)((*cpp2::assert_not_null(CPP2_UFCS(name)(*cpp2::assert_not_null(n))))); } else { return ""; } } - [[nodiscard]] auto declaration::has_initializer() const -> bool { return CPP2_UFCS_0(has_initializer, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::has_initializer() const -> bool { return CPP2_UFCS(has_initializer)((*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_global() const -> bool { return CPP2_UFCS_0(is_global, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_function() const -> bool { return CPP2_UFCS_0(is_function, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_object() const -> bool { return CPP2_UFCS_0(is_object, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_type() const -> bool { return CPP2_UFCS_0(is_type, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_namespace() const -> bool { return CPP2_UFCS_0(is_namespace, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_alias() const -> bool { return CPP2_UFCS_0(is_alias, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_global() const -> bool { return CPP2_UFCS(is_global)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_function() const -> bool { return CPP2_UFCS(is_function)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_object() const -> bool { return CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_type() const -> bool { return CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_namespace() const -> bool { return CPP2_UFCS(is_namespace)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_alias() const -> bool { return CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))); } [[nodiscard]] auto declaration::as_function() const -> function_declaration { return function_declaration(n, (*this)); } [[nodiscard]] auto declaration::as_object() const -> object_declaration { return object_declaration(n, (*this)); } [[nodiscard]] auto declaration::as_type() const -> type_declaration { return type_declaration(n, (*this)); } [[nodiscard]] auto declaration::get_parent() const -> declaration { return declaration(n, (*this)); } - [[nodiscard]] auto declaration::parent_is_function() const -> bool { return CPP2_UFCS_0(parent_is_function, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::parent_is_object() const -> bool { return CPP2_UFCS_0(parent_is_object, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::parent_is_type() const -> bool { return CPP2_UFCS_0(parent_is_type, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::parent_is_namespace() const -> bool { return CPP2_UFCS_0(parent_is_namespace, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::parent_is_alias() const -> bool { return CPP2_UFCS_0(parent_is_alias, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::parent_is_polymorphic() const -> bool { return CPP2_UFCS_0(parent_is_polymorphic, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_function() const -> bool { return CPP2_UFCS(parent_is_function)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_object() const -> bool { return CPP2_UFCS(parent_is_object)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_type() const -> bool { return CPP2_UFCS(parent_is_type)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_namespace() const -> bool { return CPP2_UFCS(parent_is_namespace)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_alias() const -> bool { return CPP2_UFCS(parent_is_alias)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_polymorphic() const -> bool { return CPP2_UFCS(parent_is_polymorphic)((*cpp2::assert_not_null(n))); } - auto declaration::make_constexpr() -> void { CPP2_UFCS_0(make_constexpr, (*cpp2::assert_not_null(n))); } - auto declaration::make_static() -> void { CPP2_UFCS_0(make_static, (*cpp2::assert_not_null(n))); } + auto declaration::make_constexpr() -> void { CPP2_UFCS(make_constexpr)((*cpp2::assert_not_null(n))); } + auto declaration::make_static() -> void { CPP2_UFCS(make_static)((*cpp2::assert_not_null(n))); } declaration::~declaration() noexcept{} declaration::declaration(declaration const& that) @@ -903,46 +903,46 @@ declaration::declaration(declaration const& that) #line 273 "reflect.h2" { - cpp2::Default.expects(CPP2_UFCS_0(is_function, (*cpp2::assert_not_null(n))), ""); + cpp2::Default.expects(CPP2_UFCS(is_function)((*cpp2::assert_not_null(n))), ""); } - [[nodiscard]] auto function_declaration::index_of_parameter_named(cpp2::in s) const -> int { return CPP2_UFCS(index_of_parameter_named, (*cpp2::assert_not_null(n)), s); } - [[nodiscard]] auto function_declaration::has_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_parameter_named, (*cpp2::assert_not_null(n)), s); } - [[nodiscard]] auto function_declaration::has_in_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_in_parameter_named, (*cpp2::assert_not_null(n)), s); } - [[nodiscard]] auto function_declaration::has_out_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_out_parameter_named, (*cpp2::assert_not_null(n)), s); } - [[nodiscard]] auto function_declaration::has_move_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_move_parameter_named, (*cpp2::assert_not_null(n)), s); } + [[nodiscard]] auto function_declaration::index_of_parameter_named(cpp2::in s) const -> int { return CPP2_UFCS(index_of_parameter_named)((*cpp2::assert_not_null(n)), s); } + [[nodiscard]] auto function_declaration::has_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_parameter_named)((*cpp2::assert_not_null(n)), s); } + [[nodiscard]] auto function_declaration::has_in_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_in_parameter_named)((*cpp2::assert_not_null(n)), s); } + [[nodiscard]] auto function_declaration::has_out_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_out_parameter_named)((*cpp2::assert_not_null(n)), s); } + [[nodiscard]] auto function_declaration::has_move_parameter_named(cpp2::in s) const -> bool { return CPP2_UFCS(has_move_parameter_named)((*cpp2::assert_not_null(n)), s); } [[nodiscard]] auto function_declaration::has_parameter_with_name_and_pass(cpp2::in s, cpp2::in pass) const -> bool { - return CPP2_UFCS(has_parameter_with_name_and_pass, (*cpp2::assert_not_null(n)), s, pass); } - [[nodiscard]] auto function_declaration::is_function_with_this() const -> bool { return CPP2_UFCS_0(is_function_with_this, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_virtual() const -> bool { return CPP2_UFCS_0(is_virtual_function, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_defaultable() const -> bool { return CPP2_UFCS_0(is_defaultable_function, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_constructor() const -> bool { return CPP2_UFCS_0(is_constructor, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_default_constructor() const -> bool { return CPP2_UFCS_0(is_default_constructor, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_move() const -> bool { return CPP2_UFCS_0(is_move, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_swap() const -> bool { return CPP2_UFCS_0(is_swap, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_constructor_with_that() const -> bool { return CPP2_UFCS_0(is_constructor_with_that, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_constructor_with_in_that() const -> bool { return CPP2_UFCS_0(is_constructor_with_in_that, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_constructor_with_move_that() const -> bool { return CPP2_UFCS_0(is_constructor_with_move_that, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_assignment() const -> bool { return CPP2_UFCS_0(is_assignment, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_assignment_with_that() const -> bool { return CPP2_UFCS_0(is_assignment_with_that, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_assignment_with_in_that() const -> bool { return CPP2_UFCS_0(is_assignment_with_in_that, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_assignment_with_move_that() const -> bool { return CPP2_UFCS_0(is_assignment_with_move_that, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_destructor() const -> bool { return CPP2_UFCS_0(is_destructor, (*cpp2::assert_not_null(n))); } + return CPP2_UFCS(has_parameter_with_name_and_pass)((*cpp2::assert_not_null(n)), s, pass); } + [[nodiscard]] auto function_declaration::is_function_with_this() const -> bool { return CPP2_UFCS(is_function_with_this)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_virtual() const -> bool { return CPP2_UFCS(is_virtual_function)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_defaultable() const -> bool { return CPP2_UFCS(is_defaultable_function)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_constructor() const -> bool { return CPP2_UFCS(is_constructor)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_default_constructor() const -> bool { return CPP2_UFCS(is_default_constructor)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_move() const -> bool { return CPP2_UFCS(is_move)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_swap() const -> bool { return CPP2_UFCS(is_swap)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_constructor_with_that() const -> bool { return CPP2_UFCS(is_constructor_with_that)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_constructor_with_in_that() const -> bool { return CPP2_UFCS(is_constructor_with_in_that)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_constructor_with_move_that() const -> bool { return CPP2_UFCS(is_constructor_with_move_that)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_assignment() const -> bool { return CPP2_UFCS(is_assignment)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_assignment_with_that() const -> bool { return CPP2_UFCS(is_assignment_with_that)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_assignment_with_in_that() const -> bool { return CPP2_UFCS(is_assignment_with_in_that)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_assignment_with_move_that() const -> bool { return CPP2_UFCS(is_assignment_with_move_that)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_destructor() const -> bool { return CPP2_UFCS(is_destructor)((*cpp2::assert_not_null(n))); } [[nodiscard]] auto function_declaration::is_copy_or_move() const -> bool { return is_constructor_with_that() || is_assignment_with_that(); } - [[nodiscard]] auto function_declaration::has_declared_return_type() const -> bool { return CPP2_UFCS_0(has_declared_return_type, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::has_bool_return_type() const -> bool { return CPP2_UFCS_0(has_bool_return_type, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::has_non_void_return_type() const -> bool { return CPP2_UFCS_0(has_non_void_return_type, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::has_declared_return_type() const -> bool { return CPP2_UFCS(has_declared_return_type)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::has_bool_return_type() const -> bool { return CPP2_UFCS(has_bool_return_type)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::has_non_void_return_type() const -> bool { return CPP2_UFCS(has_non_void_return_type)((*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::unnamed_return_type() const -> std::string { return CPP2_UFCS_0(unnamed_return_type_to_string, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::unnamed_return_type() const -> std::string { return CPP2_UFCS(unnamed_return_type_to_string)((*cpp2::assert_not_null(n))); } - [[nodiscard]] auto function_declaration::is_binary_comparison_function() const -> bool { return CPP2_UFCS_0(is_binary_comparison_function, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::is_binary_comparison_function() const -> bool { return CPP2_UFCS(is_binary_comparison_function)((*cpp2::assert_not_null(n))); } - auto function_declaration::default_to_virtual() -> void { (void) CPP2_UFCS_0(make_function_virtual, (*cpp2::assert_not_null(n))); } + auto function_declaration::default_to_virtual() -> void { static_cast(CPP2_UFCS(make_function_virtual)((*cpp2::assert_not_null(n)))); } - [[nodiscard]] auto function_declaration::make_virtual() -> bool { return CPP2_UFCS_0(make_function_virtual, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::make_virtual() -> bool { return CPP2_UFCS(make_function_virtual)((*cpp2::assert_not_null(n))); } function_declaration::function_declaration(function_declaration const& that) : declaration{ static_cast(that) }{} @@ -957,21 +957,21 @@ declaration::declaration(declaration const& that) #line 330 "reflect.h2" { - cpp2::Default.expects(CPP2_UFCS_0(is_object, (*cpp2::assert_not_null(n))), ""); + cpp2::Default.expects(CPP2_UFCS(is_object)((*cpp2::assert_not_null(n))), ""); } - [[nodiscard]] auto object_declaration::is_const() const -> bool { return CPP2_UFCS_0(is_const, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto object_declaration::has_wildcard_type() const -> bool { return CPP2_UFCS_0(has_wildcard_type, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto object_declaration::is_const() const -> bool { return CPP2_UFCS(is_const)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto object_declaration::has_wildcard_type() const -> bool { return CPP2_UFCS(has_wildcard_type)((*cpp2::assert_not_null(n))); } [[nodiscard]] auto object_declaration::type() const -> std::string{ - auto ret {CPP2_UFCS_0(object_type, (*cpp2::assert_not_null(n)))}; + auto ret {CPP2_UFCS(object_type)((*cpp2::assert_not_null(n)))}; require(!(contains(ret, "(*ERROR*)")), "cannot to_string this type: " + ret); return ret; } [[nodiscard]] auto object_declaration::initializer() const -> std::string{ - auto ret {CPP2_UFCS_0(object_initializer, (*cpp2::assert_not_null(n)))}; + auto ret {CPP2_UFCS(object_initializer)((*cpp2::assert_not_null(n)))}; require(!(contains(ret, "(*ERROR*)")), "cannot to_string this initializer: " + ret); return ret; @@ -990,19 +990,19 @@ declaration::declaration(declaration const& that) #line 366 "reflect.h2" { - cpp2::Default.expects(CPP2_UFCS_0(is_type, (*cpp2::assert_not_null(n))), ""); + cpp2::Default.expects(CPP2_UFCS(is_type)((*cpp2::assert_not_null(n))), ""); } - [[nodiscard]] auto type_declaration::is_polymorphic() const -> bool { return CPP2_UFCS_0(is_polymorphic, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto type_declaration::is_final() const -> bool { return CPP2_UFCS_0(is_type_final, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto type_declaration::make_final() -> bool { return CPP2_UFCS_0(make_type_final, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto type_declaration::is_polymorphic() const -> bool { return CPP2_UFCS(is_polymorphic)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto type_declaration::is_final() const -> bool { return CPP2_UFCS(is_type_final)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto type_declaration::make_final() -> bool { return CPP2_UFCS(make_type_final)((*cpp2::assert_not_null(n))); } [[nodiscard]] auto type_declaration::get_member_functions() const -> std::vector { std::vector ret {}; - for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::functions) ) { - (void) CPP2_UFCS(emplace_back, ret, d, (*this)); + for ( auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::functions) ) { + static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); } return ret; } @@ -1011,8 +1011,8 @@ declaration::declaration(declaration const& that) std::vector { std::vector ret {}; - for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::objects) ) { - (void) CPP2_UFCS(emplace_back, ret, d, (*this)); + for ( auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::objects) ) { + static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); } return ret; } @@ -1021,8 +1021,8 @@ declaration::declaration(declaration const& that) std::vector { std::vector ret {}; - for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::types) ) { - (void) CPP2_UFCS(emplace_back, ret, d, (*this)); + for ( auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::types) ) { + static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); } return ret; } @@ -1031,8 +1031,8 @@ declaration::declaration(declaration const& that) std::vector { std::vector ret {}; - for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::all) ) { - (void) CPP2_UFCS(emplace_back, ret, d, (*this)); + for ( auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::all) ) { + static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); } return ret; } @@ -1046,7 +1046,7 @@ declaration::declaration(declaration const& that) cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; #line 423 "reflect.h2" - auto declared {CPP2_UFCS_0(find_declared_value_set_functions, (*cpp2::assert_not_null(n)))}; + auto declared {CPP2_UFCS(find_declared_value_set_functions)((*cpp2::assert_not_null(n)))}; out_this_in_that.construct(declared.out_this_in_that != nullptr); out_this_move_that.construct(declared.out_this_move_that!=nullptr); inout_this_in_that.construct(declared.inout_this_in_that!=nullptr); @@ -1058,14 +1058,14 @@ declaration::declaration(declaration const& that) { auto decl {parse_statement(source)}; if (decl) { - return CPP2_UFCS(add_type_member, (*cpp2::assert_not_null(n)), std::move(decl)); + return CPP2_UFCS(add_type_member)((*cpp2::assert_not_null(n)), std::move(decl)); } return false; } - auto type_declaration::remove_all_members() -> void { CPP2_UFCS_0(type_remove_all_members, (*cpp2::assert_not_null(n))); } + auto type_declaration::remove_all_members() -> void { CPP2_UFCS(type_remove_all_members)((*cpp2::assert_not_null(n))); } - auto type_declaration::disable_member_function_generation() -> void { CPP2_UFCS_0(type_disable_member_function_generation, (*cpp2::assert_not_null(n))); } + auto type_declaration::disable_member_function_generation() -> void { CPP2_UFCS(type_disable_member_function_generation)((*cpp2::assert_not_null(n))); } type_declaration::type_declaration(type_declaration const& that) : declaration{ static_cast(that) }{} @@ -1073,7 +1073,7 @@ declaration::declaration(declaration const& that) #line 458 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { - CPP2_UFCS(require, t, CPP2_UFCS(add_member, t, "operator=: (virtual move this) = { }"), + CPP2_UFCS(require)(t, CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"), "could not add virtual destructor"); } @@ -1082,25 +1082,25 @@ auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; - for ( auto& m : CPP2_UFCS_0(get_members, t) ) + for ( auto& m : CPP2_UFCS(get_members)(t) ) { - CPP2_UFCS(require, m, !(CPP2_UFCS_0(is_object, m)), + CPP2_UFCS(require)(m, !(CPP2_UFCS(is_object)(m)), "interfaces may not contain data objects"); - if (CPP2_UFCS_0(is_function, m)) { - auto mf {CPP2_UFCS_0(as_function, m)}; - CPP2_UFCS(require, mf, !(CPP2_UFCS_0(is_copy_or_move, mf)), + if (CPP2_UFCS(is_function)(m)) { + auto mf {CPP2_UFCS(as_function)(m)}; + CPP2_UFCS(require)(mf, !(CPP2_UFCS(is_copy_or_move)(mf)), "interfaces may not copy or move; consider a virtual clone() instead"); - CPP2_UFCS(require, mf, !(CPP2_UFCS_0(has_initializer, mf)), + CPP2_UFCS(require)(mf, !(CPP2_UFCS(has_initializer)(mf)), "interface functions must not have a function body; remove the '=' initializer"); - CPP2_UFCS(require, mf, CPP2_UFCS_0(make_public, mf), + CPP2_UFCS(require)(mf, CPP2_UFCS(make_public)(mf), "interface functions must be public"); - CPP2_UFCS_0(default_to_virtual, mf); - has_dtor |= CPP2_UFCS_0(is_destructor, mf); + CPP2_UFCS(default_to_virtual)(mf); + has_dtor |= CPP2_UFCS(is_destructor)(mf); } } if (!(std::move(has_dtor))) { - CPP2_UFCS_0(add_virtual_destructor, t); + CPP2_UFCS(add_virtual_destructor)(t); } } @@ -1109,23 +1109,23 @@ auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; - for ( auto& mf : CPP2_UFCS_0(get_member_functions, t) ) + for ( auto& mf : CPP2_UFCS(get_member_functions)(t) ) { - if (CPP2_UFCS_0(is_default_access, mf)) { - CPP2_UFCS_0(default_to_public, mf); + if (CPP2_UFCS(is_default_access)(mf)) { + CPP2_UFCS(default_to_public)(mf); } - CPP2_UFCS(require, mf, !(CPP2_UFCS_0(is_copy_or_move, mf)), + CPP2_UFCS(require)(mf, !(CPP2_UFCS(is_copy_or_move)(mf)), "polymorphic base types may not copy or move; consider a virtual clone() instead"); - if (CPP2_UFCS_0(is_destructor, mf)) { + if (CPP2_UFCS(is_destructor)(mf)) { has_dtor = true; - CPP2_UFCS(require, mf, (CPP2_UFCS_0(is_public, mf) && CPP2_UFCS_0(is_virtual, mf)) - || (CPP2_UFCS_0(is_protected, mf) && !(CPP2_UFCS_0(is_virtual, mf))), + CPP2_UFCS(require)(mf, (CPP2_UFCS(is_public)(mf) && CPP2_UFCS(is_virtual)(mf)) + || (CPP2_UFCS(is_protected)(mf) && !(CPP2_UFCS(is_virtual)(mf))), "a polymorphic base type destructor must be public and virtual, or protected and nonvirtual"); } } if (!(std::move(has_dtor))) { - CPP2_UFCS_0(add_virtual_destructor, t); + CPP2_UFCS(add_virtual_destructor)(t); } } @@ -1137,20 +1137,20 @@ auto ordered_impl( { auto has_spaceship {false}; - for ( auto& mf : CPP2_UFCS_0(get_member_functions, t) ) + for ( auto& mf : CPP2_UFCS(get_member_functions)(t) ) { - if (CPP2_UFCS(has_name, mf, "operator<=>")) { + if (CPP2_UFCS(has_name)(mf, "operator<=>")) { has_spaceship = true; - auto return_name {CPP2_UFCS_0(unnamed_return_type, mf)}; - if (CPP2_UFCS(find, return_name, ordering)==return_name.npos) + auto return_name {CPP2_UFCS(unnamed_return_type)(mf)}; + if (CPP2_UFCS(find)(return_name, ordering)==return_name.npos) { - CPP2_UFCS(error, mf, "operator<=> must return std::" + cpp2::as_(ordering)); + CPP2_UFCS(error)(mf, "operator<=> must return std::" + cpp2::as_(ordering)); } } } if (!(std::move(has_spaceship))) { - CPP2_UFCS(require, t, CPP2_UFCS(add_member, t, "operator<=>: (this, that) -> std::" + (cpp2::as_(ordering)) + ";"), + CPP2_UFCS(require)(t, CPP2_UFCS(add_member)(t, "operator<=>: (this, that) -> std::" + (cpp2::as_(ordering)) + ";"), "could not add operator<=> with std::" + (cpp2::as_(ordering))); } } @@ -1180,7 +1180,7 @@ auto copyable(meta::type_declaration& t) -> void // they must also have written the most general one - we can't // assume we can safely generate it for them since they've opted // into customized semantics - auto smfs {CPP2_UFCS_0(query_declared_value_set_functions, t)}; + auto smfs {CPP2_UFCS(query_declared_value_set_functions)(t)}; if ( !(smfs.out_this_in_that) && ( smfs.out_this_move_that @@ -1188,10 +1188,10 @@ auto copyable(meta::type_declaration& t) -> void || smfs.inout_this_move_that)) { - CPP2_UFCS(error, t, "this type is partially copyable/movable - when you provide any of the more-specific operator= signatures, you must also provide the one with the general signature (out this, that); alternatively, consider removing all the operator= functions and let them all be generated for you with default memberwise semantics"); + CPP2_UFCS(error)(t, "this type is partially copyable/movable - when you provide any of the more-specific operator= signatures, you must also provide the one with the general signature (out this, that); alternatively, consider removing all the operator= functions and let them all be generated for you with default memberwise semantics"); } else {if (!(std::move(smfs).out_this_in_that)) { - CPP2_UFCS(require, t, CPP2_UFCS(add_member, t, "operator=: (out this, that) = { }"), + CPP2_UFCS(require)(t, CPP2_UFCS(add_member)(t, "operator=: (out this, that) = { }"), "could not add general operator=:(out this, that)"); }} } @@ -1199,19 +1199,19 @@ auto copyable(meta::type_declaration& t) -> void #line 665 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { - CPP2_UFCS_0(copyable, t); + CPP2_UFCS(copyable)(t); auto has_default_ctor {false}; - for ( auto& mf : CPP2_UFCS_0(get_member_functions, t) ) { - has_default_ctor |= CPP2_UFCS_0(is_default_constructor, mf); - CPP2_UFCS(require, mf, !(CPP2_UFCS_0(is_protected, mf)) && !(CPP2_UFCS_0(is_virtual, mf)), + for ( auto& mf : CPP2_UFCS(get_member_functions)(t) ) { + has_default_ctor |= CPP2_UFCS(is_default_constructor)(mf); + CPP2_UFCS(require)(mf, !(CPP2_UFCS(is_protected)(mf)) && !(CPP2_UFCS(is_virtual)(mf)), "a value type may not have a protected or virtual function"); - CPP2_UFCS(require, mf, !(CPP2_UFCS_0(is_destructor, mf)) || CPP2_UFCS_0(is_public, mf), + CPP2_UFCS(require)(mf, !(CPP2_UFCS(is_destructor)(mf)) || CPP2_UFCS(is_public)(mf), "a value type may not have a non-public destructor"); } if (!(std::move(has_default_ctor))) { - CPP2_UFCS(require, t, CPP2_UFCS(add_member, t, "operator=: (out this) = { }"), + CPP2_UFCS(require)(t, CPP2_UFCS(add_member)(t, "operator=: (out this) = { }"), "could not add default constructor"); } } @@ -1219,38 +1219,38 @@ auto basic_value(meta::type_declaration& t) -> void #line 694 "reflect.h2" auto value(meta::type_declaration& t) -> void { - CPP2_UFCS_0(ordered, t); - CPP2_UFCS_0(basic_value, t); + CPP2_UFCS(ordered)(t); + CPP2_UFCS(basic_value)(t); } auto weakly_ordered_value(meta::type_declaration& t) -> void { - CPP2_UFCS_0(weakly_ordered, t); - CPP2_UFCS_0(basic_value, t); + CPP2_UFCS(weakly_ordered)(t); + CPP2_UFCS(basic_value)(t); } auto partially_ordered_value(meta::type_declaration& t) -> void { - CPP2_UFCS_0(partially_ordered, t); - CPP2_UFCS_0(basic_value, t); + CPP2_UFCS(partially_ordered)(t); + CPP2_UFCS(basic_value)(t); } #line 738 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { - for ( auto& m : CPP2_UFCS_0(get_members, t) ) + for ( auto& m : CPP2_UFCS(get_members)(t) ) { - CPP2_UFCS(require, m, CPP2_UFCS_0(make_public, m), + CPP2_UFCS(require)(m, CPP2_UFCS(make_public)(m), "all struct members must be public"); - if (CPP2_UFCS_0(is_function, m)) { - auto mf {CPP2_UFCS_0(as_function, m)}; - CPP2_UFCS(require, t, !(CPP2_UFCS_0(is_virtual, mf)), + if (CPP2_UFCS(is_function)(m)) { + auto mf {CPP2_UFCS(as_function)(m)}; + CPP2_UFCS(require)(t, !(CPP2_UFCS(is_virtual)(mf)), "a struct may not have a virtual function"); - CPP2_UFCS(require, t, !(CPP2_UFCS(has_name, mf, "operator=")), + CPP2_UFCS(require)(t, !(CPP2_UFCS(has_name)(mf, "operator=")), "a struct may not have a user-defined operator="); } } - CPP2_UFCS_0(disable_member_function_generation, t); + CPP2_UFCS(disable_member_function_generation)(t); } #line 818 "reflect.h2"