diff --git a/include/cpp2util.h b/include/cpp2util.h index 4f9677f40c..e8978a832f 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -116,7 +116,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 #ifdef __cpp_lib_expected #include @@ -526,7 +526,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 @@ -575,7 +575,7 @@ struct { template [[nodiscard]] auto cpp2_new(auto&& ...args) const -> std::shared_ptr { // Prefer { } to ( ) as noted for unique.new - // + // // Note this does mean we don't get the make_shared optimization a lot // of the time -- we can restore that as soon as make_shared improves to // allow list initialization. But the make_shared optimization isn't a @@ -745,13 +745,22 @@ class out { // //----------------------------------------------------------------------- // +// Workaround . +#define CPP2_FORCE_INLINE_LAMBDA_CLANG /* empty */ + #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_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 */ + #undef CPP2_FORCE_INLINE_LAMBDA_CLANG + #define CPP2_FORCE_INLINE_LAMBDA_CLANG __attribute__((always_inline)) + #else + #define CPP2_FORCE_INLINE_LAMBDA __attribute__((always_inline)) + #endif #if defined(__clang_major__) // Also check __cplusplus, only to satisfy Clang -pedantic-errors @@ -776,85 +785,77 @@ class out { #endif #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)...); \ - } else { \ - return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (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__) +// Ideally, the expression `CPP2_UFCS_IS_NOTHROW` expands to +// is in the _noexcept-specifier_ of the UFCS lambda, but without 'std::declval'. +// To workaround [GCC bug 101043](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101043), +// we instead make it a template parameter of the UFCS lambda. +// But using a template parameter, Clang also ICEs on an application. +// So we use these `NOTHROW` macros to fall back to the ideal for when not using GCC. +#define CPP2_UFCS_IS_NOTHROW(QUALID,TEMPKW,...) \ + requires { requires requires { std::declval().CPP2_UFCS_REMPARENS QUALID TEMPKW __VA_ARGS__(std::declval()...); }; \ + requires noexcept(std::declval().CPP2_UFCS_REMPARENS QUALID TEMPKW __VA_ARGS__(std::declval()...)); } \ +|| requires { requires !requires { std::declval().CPP2_UFCS_REMPARENS QUALID TEMPKW __VA_ARGS__(std::declval()...); }; \ + requires noexcept(CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(std::declval(), std::declval()...)); } +#define CPP2_UFCS_IS_NOTHROW_PARAM(...) /*empty*/ +#define CPP2_UFCS_IS_NOTHROW_ARG(QUALID,TEMPKW,...) CPP2_UFCS_IS_NOTHROW(QUALID,TEMPKW,__VA_ARGS__) +#if defined(__GNUC__) && !defined(__clang__) + #undef CPP2_UFCS_IS_NOTHROW_PARAM + #undef CPP2_UFCS_IS_NOTHROW_ARG + #define CPP2_UFCS_IS_NOTHROW_PARAM(QUALID,TEMPKW,...) , bool IsNothrow = CPP2_UFCS_IS_NOTHROW(QUALID,TEMPKW,__VA_ARGS__) + #define CPP2_UFCS_IS_NOTHROW_ARG(...) IsNothrow + #if __GNUC__ < 11 + #undef CPP2_UFCS_IS_NOTHROW_PARAM + #undef CPP2_UFCS_IS_NOTHROW_ARG + #define CPP2_UFCS_IS_NOTHROW_PARAM(...) /*empty*/ + #define CPP2_UFCS_IS_NOTHROW_ARG(...) false // GCC 10 UFCS is always potentially-throwing. + #endif +#endif -#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) +// Ideally, the expression `CPP2_UFCS_CONSTRAINT_ARG` expands to +// is in the _requires-clause_ of the UFCS lambda. +// To workaround an MSVC bug within a member function 'F' where UFCS is also for 'F' +// (), +// we instead make it a template parameter of the UFCS lambda. +// But using a template parameter, Clang also ICEs and GCC rejects a local 'F'. +// Also, Clang rejects the SFINAE test case when using 'std::declval'. +// So we use these `CONSTRAINT` macros to fall back to the ideal for when not using MSVC. +#define CPP2_UFCS_CONSTRAINT_PARAM(...) /*empty*/ +#define CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,...) \ + requires { CPP2_FORWARD(obj).CPP2_UFCS_REMPARENS QUALID TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); } \ +|| requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } +#if defined(_MSC_VER) + #undef CPP2_UFCS_CONSTRAINT_PARAM + #undef CPP2_UFCS_CONSTRAINT_ARG + #define CPP2_UFCS_CONSTRAINT_PARAM(QUALID,TEMPKW,...) , bool IsViable = \ + requires { std::declval().CPP2_UFCS_REMPARENS QUALID TEMPKW __VA_ARGS__(std::declval()...); } \ +|| requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(std::declval(), std::declval()...); } + #define CPP2_UFCS_CONSTRAINT_ARG(...) IsViable +#endif -#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)...); \ +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ +[LAMBDADEFCAPT]< \ + typename Obj, typename... Params \ + CPP2_UFCS_IS_NOTHROW_PARAM(QUALID,TEMPKW,__VA_ARGS__) \ + CPP2_UFCS_CONSTRAINT_PARAM(QUALID,TEMPKW,__VA_ARGS__) \ + > \ + CPP2_LAMBDA_NO_DISCARD (Obj&& obj, Params&& ...params) CPP2_FORCE_INLINE_LAMBDA_CLANG \ + noexcept(CPP2_UFCS_IS_NOTHROW_ARG(QUALID,TEMPKW,__VA_ARGS__)) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \ + requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \ + if constexpr (requires{ CPP2_FORWARD(obj).CPP2_UFCS_REMPARENS QUALID TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); }) { \ + return CPP2_FORWARD(obj).CPP2_UFCS_REMPARENS QUALID TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); \ } else { \ - return FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \ + return CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(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_QUALIFIED_TEMPLATE(QUALID,...) CPP2_UFCS_(&,QUALID,template,__VA_ARGS__) +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) +#define CPP2_UFCS_TEMPLATE_NONLOCAL(...) CPP2_UFCS_(,(),template,__VA_ARGS__) +#define CPP2_UFCS_QUALIFIED_TEMPLATE_NONLOCAL(QUALID,...) CPP2_UFCS_(,QUALID,template,__VA_ARGS__) //----------------------------------------------------------------------- @@ -914,7 +915,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}; @@ -1054,8 +1055,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; @@ -1063,8 +1064,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; @@ -1726,7 +1727,7 @@ constexpr auto unsafe_narrow( X&& x ) noexcept -> decltype(auto) // Returns a function object that takes a 'value' of the same type as // 'flags', and evaluates to true if and only if 'value' has set all of // the bits set in 'flags' -// +// //----------------------------------------------------------------------- // template 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 0000000000..9fff24aedc --- /dev/null +++ b/regression-tests/mixed-bugfix-for-ufcs-non-local.cpp2 @@ -0,0 +1,49 @@ +namespace ns { + +template struct t { }; +constexpr bool f(const t&) { return true; } +constexpr t o{}; + +} // namespace ns + +ns: namespace = { + +// Variables. + +v0: <_: t> bool == false; // Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context) + +v1: t == t(); // Fails on Clang 12 (lambda in unevaluated context). + +v2: bool == o.f(); + +// Functions. + +g: <_: t> () = { } // Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context) + +g: (_: t) = { } // Fails on Clang 12 (lambda in unevaluated context). + +g: () pre(o.f()) = { } + +h: () -> t = o; // Fails on Clang 12 (lambda in unevaluated context). + +// Aliases. + +a: <_: t> type == bool; // Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context) + +b: <_: t> _ == false; // Fails on GCC ([GCC109781][]). + +c: type == t; // Fails on Clang 12 (lambda in unevaluated context) and Clang 12 (a lambda expression cannot appear in this context) + +d: _ == t(); // Fails on Clang 12 (lambda in unevaluated context). + +u: @struct type = { + b: bool == o.f(); + c: bool == :(x: std::type_identity_t) x;(true); // Fails on Clang 12 (lambda in unevaluated context). + g: (s, sz) pre(s.sz() != 0) = { } +} + +} // namespace ns + +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 0000000000..de09b983de --- /dev/null +++ b/regression-tests/pure2-bugfix-for-ufcs-arguments.cpp2 @@ -0,0 +1,71 @@ +print_res: (x: i32) -> i32 = { + std::cout << x; + if x == 9 { std::cout << '\n'; } + return x; +} + +t: @struct type = { + f: (inout this) -> i32 = print_res(0); + f: (inout this, _) -> i32 = print_res(1); + f: <_> (inout this) -> i32 = print_res(2); + f: <_> (inout this, _) -> i32 = print_res(3); + f: <_, U> (inout this, _, _) -> i32 = print_res(4); +} + +f: (_: t) -> i32 = print_res(5); +f: (_: t, _) -> i32 = print_res(6); +f: <_> (_: t) -> i32 = print_res(7); +f: <_> (_: t, _) -> i32 = print_res(8); +f: <_, U> (_: t, _, _) -> i32 = print_res(9); + +m: t = (); +n: const t = (); +a: <_, U> _ == 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: () = { + _ = m.f(); + _ = m.f(0); + _ = m.f(); + _ = m.f(0); + _ = m.f(0, 0); + _ = n.f(); + _ = n.f(0); + _ = n.f(); + _ = n.f(0); + _ = n.f(0, 0); + _ = a.f(0, 0); + + _ = :(a, f) = { _ = a.f(a).f(); }; + // _ = 0.std::min(0); + _ = 0.ns::t<0, 0>::f<0>(); +} + +// _: i32 = 0.std::min(0); +_: i32 = 0.ns::t<0, 0>::f<0>(); + +ns: namespace = { +t: @struct type = { + f: (_: int) -> i32 = 0; +} +} // namespace ns + +A: @struct type = { + f: (this) = { } +} + +B: @struct type = { + m: A; + f: (this) = m.f(); +} diff --git a/regression-tests/pure2-bugfix-for-ufcs-name-lookup.cpp2 b/regression-tests/pure2-bugfix-for-ufcs-name-lookup.cpp2 new file mode 100644 index 0000000000..e82c5d06b6 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-ufcs-name-lookup.cpp2 @@ -0,0 +1,111 @@ +identity: @struct type = { + operator(): (this, forward x) -> forward _ == x; +} + +t: @struct type = { + f: (this) -> int == 0; +} + +u: @struct type = { } + +ns: namespace = { +f: (_) -> int == 1; +} // namespace ns + +// v: @struct type = { +// f :== :(_) 0; // Pending on #706. +// g: (i) i.f(); +// } + +main: () = { + { + f: int = t().f(); + assert(f == 0); + } + { + f := t().f(); + assert(f == 0); + } + { + f: _ = t().f(); + assert(f == 0); + } + (f := t().f()) assert(f == 0); + (f: _ = t().f()) assert(f == 0); + { + f :== t().f(); + static_assert(f == 0); + } + { + f: _ == t().f(); + static_assert(f == 0); + } + { + f := :(f) -> _ = { + assert(t().f() == 0); + return u().f(); + }(identity()); + _ = f; + } + { // Rejected by MSVC. + // f := : (copy _: std::integral_constant) -> _ = { + // assert(t().f() == 0); + // return u().f(); + // }(:std::integral_constant = ()); + // _ = f; + } + { + f := :() = { + (f: identity = identity()) assert(t().f() == 0); + (f: identity = identity()) _ = u().f(); + }; + _ = f; + } + { + f := :() = { + using ns::f; + static_assert(t().f() == 0); + // static_assert(u().f() == 1); + }; + _ = f; + } + { + f := :() = { + static_assert(t().f() == 0); + g := : (_: T) -> std::void_t = {}; + static_assert(!std::is_invocable_v); + using ns::f; + }; + _ = f; + } + { + f := :() = { + using ns::f; + _ = :() = { + static_assert(t().f() == 0); + // static_assert(u().f() == 1); + }; + { + static_assert(t().f() == 0); + // static_assert(u().f() == 1); + } + }; + _ = f; + } + { + f := :() = { + _ = :() = { + static_assert(t().f() == 0); + g := : (_: T) -> std::void_t = {}; + static_assert(!std::is_invocable_v); + }; + { + static_assert(t().f() == 0); + g := : (_: T) -> std::void_t = {}; + static_assert(!std::is_invocable_v); + } + using ns::f; + }; + _ = 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 0000000000..1bf7fa2ebb --- /dev/null +++ b/regression-tests/pure2-bugfix-for-ufcs-noexcept.cpp2 @@ -0,0 +1,6 @@ +t: type = { + swap: (virtual inout this, that) = { } // Non-`virtual` blocked on #508, idiomatic form on #507. +} +main: () = { + static_assert(noexcept(t().swap(t()))); // Fails on Clang 12 (lambda in unevaluated context) and GCC 10 (static assertion failed) +} 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 0000000000..fbd6edb5c6 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-ufcs-sfinae.cpp2 @@ -0,0 +1,8 @@ +f: () -> std::type_identity_t = { } // Fails on Clang 12 (lambda in unevaluated context). + +B: type = { } + +main: () = { + g := : (_: T) -> std::void_t())> = {}; + static_assert(!std::is_invocable_v); +} diff --git a/regression-tests/test-results/clang-12/mixed-bugfix-for-ufcs-non-local.cpp.output b/regression-tests/test-results/clang-12/mixed-bugfix-for-ufcs-non-local.cpp.output new file mode 100644 index 0000000000..d048988f6a --- /dev/null +++ b/regression-tests/test-results/clang-12/mixed-bugfix-for-ufcs-non-local.cpp.output @@ -0,0 +1,118 @@ +mixed-bugfix-for-ufcs-non-local.cpp2:13:12: error: a lambda expression cannot appear in this context +template _> bool inline constexpr v0 = false;// Fails on GCC ([GCC109781][]). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:15:3: error: a lambda expression cannot appear in this context +t inline constexpr v1 = t();// Fails on Clang 12 (lambda in unevaluated context). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:21:12: error: a lambda expression cannot appear in this context +template _> auto g() -> void; + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:23:36: error: a lambda expression cannot appear in this context +auto g([[maybe_unused]] cpp2::in> unnamed_param_1) -> void; + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:27:29: error: a lambda expression cannot appear in this context +[[nodiscard]] auto h() -> t; + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:31:12: error: a lambda expression cannot appear in this context +template _> using a = bool;// Fails on GCC ([GCC109781][]). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:33:12: error: a lambda expression cannot appear in this context +template _> auto inline constexpr b = false;// Fails on GCC ([GCC109781][]). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:35:13: error: a lambda expression cannot appear in this context +using c = t;// Fails on Clang 12 (lambda in unevaluated context). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:37:29: error: a lambda expression cannot appear in this context +auto inline constexpr d = t();// Fails on Clang 12 (lambda in unevaluated context). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:21:12: error: a lambda expression cannot appear in this context +template _> auto g() -> void{}// Fails on GCC ([GCC109781][]). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:23:36: error: a lambda expression cannot appear in this context +auto g([[maybe_unused]] cpp2::in> unnamed_param_1) -> void{}// Fails on Clang 12 (lambda in unevaluated context). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:27:29: error: a lambda expression cannot appear in this context +[[nodiscard]] auto h() -> t { return o; }// Fails on Clang 12 (lambda in unevaluated context). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +mixed-bugfix-for-ufcs-non-local.cpp2:41:79: error: lambda expression in an unevaluated operand + inline CPP2_CONSTEXPR bool u::c = [](cpp2::in> x) -> auto { return x; }(true); + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +13 errors generated. diff --git a/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-arguments.cpp.execution b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-arguments.cpp.execution new file mode 100644 index 0000000000..0e41b78197 --- /dev/null +++ b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-arguments.cpp.execution @@ -0,0 +1,4 @@ +0123456789 +9 +0123456789 +9 diff --git a/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-arguments.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-arguments.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-name-lookup.cpp.execution b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-name-lookup.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-name-lookup.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-name-lookup.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-noexcept.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-noexcept.cpp.output new file mode 100644 index 0000000000..b3ac087cb2 --- /dev/null +++ b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-noexcept.cpp.output @@ -0,0 +1,10 @@ +pure2-bugfix-for-ufcs-noexcept.cpp2:5:26: error: lambda expression in an unevaluated operand + static_assert(noexcept(CPP2_UFCS(swap)(t(), t())));// Fails on Clang 12 (lambda in unevaluated context). + ^ +../../../include/cpp2util.h:853:59: note: expanded from macro 'CPP2_UFCS' +#define CPP2_UFCS(...) CPP2_UFCS_(&,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +1 error generated. diff --git a/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-sfinae.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-sfinae.cpp.output new file mode 100644 index 0000000000..8f671cfa58 --- /dev/null +++ b/regression-tests/test-results/clang-12/pure2-bugfix-for-ufcs-sfinae.cpp.output @@ -0,0 +1,19 @@ +pure2-bugfix-for-ufcs-sfinae.cpp2:1:78: error: lambda expression in an unevaluated operand +template [[nodiscard]] auto f() -> std::type_identity_t; + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +pure2-bugfix-for-ufcs-sfinae.cpp2:1:78: error: lambda expression in an unevaluated operand +template [[nodiscard]] auto f() -> std::type_identity_t{}// Fails on Clang 12 (lambda in unevaluated context). + ^ +../../../include/cpp2util.h:856:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL' +#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + ^ +../../../include/cpp2util.h:837:53: note: expanded from macro 'CPP2_UFCS_' +#define CPP2_UFCS_(LAMBDADEFCAPT,QUALID,TEMPKW,...) \ + ^ +2 errors generated. 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 0000000000..e69de29bb2 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 0000000000..e69de29bb2 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 0000000000..0e41b78197 --- /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 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-name-lookup.cpp.execution b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-name-lookup.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-name-lookup.cpp.output b/regression-tests/test-results/clang-18/pure2-bugfix-for-ufcs-name-lookup.cpp.output new file mode 100644 index 0000000000..e69de29bb2 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 0000000000..e69de29bb2 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 0000000000..e69de29bb2 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 0000000000..e69de29bb2 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 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/mixed-bugfix-for-ufcs-non-local.cpp.execution b/regression-tests/test-results/gcc-10/mixed-bugfix-for-ufcs-non-local.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/mixed-bugfix-for-ufcs-non-local.cpp.output b/regression-tests/test-results/gcc-10/mixed-bugfix-for-ufcs-non-local.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-arguments.cpp.execution b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-arguments.cpp.execution new file mode 100644 index 0000000000..0e41b78197 --- /dev/null +++ b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-arguments.cpp.execution @@ -0,0 +1,4 @@ +0123456789 +9 +0123456789 +9 diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-arguments.cpp.output b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-arguments.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-name-lookup.cpp.execution b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-name-lookup.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-name-lookup.cpp.output b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-name-lookup.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-noexcept.cpp.output b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-noexcept.cpp.output new file mode 100644 index 0000000000..ebd7cf28ff --- /dev/null +++ b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-noexcept.cpp.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-ufcs-noexcept.cpp2: In function ‘int main()’: +pure2-bugfix-for-ufcs-noexcept.cpp2:5:17: error: static assertion failed diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-sfinae.cpp.execution b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-sfinae.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-sfinae.cpp.output b/regression-tests/test-results/gcc-10/pure2-bugfix-for-ufcs-sfinae.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-print.cpp.output b/regression-tests/test-results/gcc-10/pure2-print.cpp.output index 7c05268029..21251be66a 100644 --- a/regression-tests/test-results/gcc-10/pure2-print.cpp.output +++ b/regression-tests/test-results/gcc-10/pure2-print.cpp.output @@ -9,7 +9,7 @@ pure2-print.cpp2:66:1: note: in expansion of macro ‘CPP2_REQUIRES_’ pure2-print.cpp2:94:1: note: in expansion of macro ‘CPP2_REQUIRES_’ pure2-print.cpp2:7:41: error: ‘constexpr const T outer::object_alias’ is not a static data member of ‘class outer’ pure2-print.cpp2:7:48: error: template definition of non-template ‘constexpr const T outer::object_alias’ -pure2-print.cpp2:65:14: error: no declaration matches ‘void outer::mytype::variadic(const auto:98& ...) requires (is_convertible_v::type>::type, int> && ...)’ +pure2-print.cpp2:65:14: error: no declaration matches ‘void outer::mytype::variadic(const auto:90& ...) requires (is_convertible_v::type>::type, int> && ...)’ pure2-print.cpp2:65:29: note: candidate is: ‘template static void outer::mytype::variadic(const auto:89& ...)’ pure2-print.cpp2:8:19: note: ‘class outer::mytype’ defined here pure2-print.cpp2:93:37: error: no declaration matches ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’ 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 0000000000..1a79da6a8d --- /dev/null +++ b/regression-tests/test-results/gcc-13/mixed-bugfix-for-ufcs-non-local.cpp.output @@ -0,0 +1,41 @@ +In file included from mixed-bugfix-for-ufcs-non-local.cpp:6: +../../../include/cpp2util.h:838:1: error: lambda-expression in template parameter type + 838 | [LAMBDADEFCAPT]< \ + | ^ +../../../include/cpp2util.h:856:59: note: in expansion of macro ‘CPP2_UFCS_’ + 856 | #define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + | ^~~~~~~~~~ +mixed-bugfix-for-ufcs-non-local.cpp2:13:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’ +mixed-bugfix-for-ufcs-non-local.cpp2:13:36: error: template argument 1 is invalid +../../../include/cpp2util.h:838:1: error: lambda-expression in template parameter type + 838 | [LAMBDADEFCAPT]< \ + | ^ +../../../include/cpp2util.h:856:59: note: in expansion of macro ‘CPP2_UFCS_’ + 856 | #define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + | ^~~~~~~~~~ +mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’ +mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid +../../../include/cpp2util.h:838:1: error: lambda-expression in template parameter type + 838 | [LAMBDADEFCAPT]< \ + | ^ +../../../include/cpp2util.h:856:59: note: in expansion of macro ‘CPP2_UFCS_’ + 856 | #define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + | ^~~~~~~~~~ +mixed-bugfix-for-ufcs-non-local.cpp2:31:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’ +mixed-bugfix-for-ufcs-non-local.cpp2:31:36: error: template argument 1 is invalid +../../../include/cpp2util.h:838:1: error: lambda-expression in template parameter type + 838 | [LAMBDADEFCAPT]< \ + | ^ +../../../include/cpp2util.h:856:59: note: in expansion of macro ‘CPP2_UFCS_’ + 856 | #define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + | ^~~~~~~~~~ +mixed-bugfix-for-ufcs-non-local.cpp2:33:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’ +mixed-bugfix-for-ufcs-non-local.cpp2:33:36: error: template argument 1 is invalid +../../../include/cpp2util.h:838:1: error: lambda-expression in template parameter type + 838 | [LAMBDADEFCAPT]< \ + | ^ +../../../include/cpp2util.h:856:59: note: in expansion of macro ‘CPP2_UFCS_’ + 856 | #define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,(),,__VA_ARGS__) + | ^~~~~~~~~~ +mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’ +mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid 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 0000000000..0e41b78197 --- /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 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-name-lookup.cpp.execution b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-name-lookup.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-name-lookup.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-ufcs-name-lookup.cpp.output new file mode 100644 index 0000000000..e69de29bb2 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 0000000000..e69de29bb2 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 0000000000..e69de29bb2 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 0000000000..e69de29bb2 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 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/mixed-bounds-check.cpp b/regression-tests/test-results/mixed-bounds-check.cpp index 70c25cd1f6..91c26a71d4 100644 --- a/regression-tests/test-results/mixed-bounds-check.cpp +++ b/regression-tests/test-results/mixed-bounds-check.cpp @@ -26,7 +26,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 25537d4d8a..b23b224459 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 @@ -40,7 +40,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 28376f1cfa..3f1c032b66 100644 --- a/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp +++ b/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp @@ -38,7 +38,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 0000000000..1482528fd1 --- /dev/null +++ b/regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp @@ -0,0 +1,104 @@ + + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "mixed-bugfix-for-ufcs-non-local.cpp2" + +#line 9 "mixed-bugfix-for-ufcs-non-local.cpp2" +namespace ns { + +#line 39 "mixed-bugfix-for-ufcs-non-local.cpp2" +class u; + + +#line 45 "mixed-bugfix-for-ufcs-non-local.cpp2" +} + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "mixed-bugfix-for-ufcs-non-local.cpp2" +namespace ns { + +template struct t { }; +constexpr bool f(const t&) { return true; } +constexpr t o{}; + +} // namespace ns + +#line 9 "mixed-bugfix-for-ufcs-non-local.cpp2" +namespace ns { + +// Variables. + +template _> bool inline constexpr v0 = false;// Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context) + +t inline constexpr v1 = t();// Fails on Clang 12 (lambda in unevaluated context). + +bool inline constexpr v2 = CPP2_UFCS_NONLOCAL(f)(o); + +// Functions. + +template _> auto g() -> void; + +auto g([[maybe_unused]] cpp2::in> unnamed_param_1) -> void; + +auto g() -> void; + +[[nodiscard]] auto h() -> t; + +// Aliases. + +template _> using a = bool;// Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context) + +template _> auto inline constexpr b = false;// Fails on GCC ([GCC109781][]). + +using c = t;// Fails on Clang 12 (lambda in unevaluated context) and Clang 12 (a lambda expression cannot appear in this context) + +auto inline constexpr d = t();// Fails on Clang 12 (lambda in unevaluated context). + +class u { + public: static const bool b; + public: static const bool c; + public: static auto g(auto const& s, auto const& sz) -> void; +}; + +} // namespace ns + +auto main() -> int; + +// [GCC109781]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109781 + + +//=== Cpp2 function definitions ================================================= + +#line 1 "mixed-bugfix-for-ufcs-non-local.cpp2" + +#line 9 "mixed-bugfix-for-ufcs-non-local.cpp2" +namespace ns { + +#line 21 "mixed-bugfix-for-ufcs-non-local.cpp2" +template _> auto g() -> void{}// Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context) + +auto g([[maybe_unused]] cpp2::in> unnamed_param_1) -> void{}// Fails on Clang 12 (lambda in unevaluated context). + +auto g() -> void{ + cpp2::Default.expects(CPP2_UFCS(f)(o), ""); } + +#line 27 "mixed-bugfix-for-ufcs-non-local.cpp2" +[[nodiscard]] auto h() -> t { return o; }// Fails on Clang 12 (lambda in unevaluated context). + +#line 40 "mixed-bugfix-for-ufcs-non-local.cpp2" + inline CPP2_CONSTEXPR bool u::b = CPP2_UFCS_NONLOCAL(f)(o); + inline CPP2_CONSTEXPR bool u::c = [](cpp2::in> x) mutable -> auto { return x; }(true);// Fails on Clang 12 (lambda in unevaluated context). + auto u::g(auto const& s, auto const& sz) -> void{ + cpp2::Default.expects(CPP2_UFCS(sz)(s) != 0, ""); } + +#line 45 "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 0000000000..560fb3c5c0 --- /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 1b7893e484..52076d5c8b 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 @@ -47,9 +47,9 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void #line 22 "mixed-captures-in-expressions-and-postconditions.cpp2" { cpp2::finally_presuccess cpp2_finally_presuccess; - cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), ""); - cpp2_finally_presuccess.add([&, _1 = CPP2_UFCS_0(ssize, vec)]{cpp2::Default.expects(CPP2_UFCS_0(ssize, vec) == _1 + 1, "");} ); + cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS(ssize)(vec)), ""); + cpp2_finally_presuccess.add([&, _1 = CPP2_UFCS(ssize)(vec)]{cpp2::Default.expects(CPP2_UFCS(ssize)(vec) == _1 + 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-fixed-type-aliases.cpp b/regression-tests/test-results/mixed-fixed-type-aliases.cpp index f73fa042d2..9fb424959e 100644 --- a/regression-tests/test-results/mixed-fixed-type-aliases.cpp +++ b/regression-tests/test-results/mixed-fixed-type-aliases.cpp @@ -57,7 +57,7 @@ auto test(auto const& x) -> void{ test(std::move(z)); for ( auto const& arg : args ) - std::cout << CPP2_UFCS_0(filename, std::filesystem::path(arg)) << "\n"; + std::cout << CPP2_UFCS(filename)(std::filesystem::path(arg)) << "\n"; std::cout << cpp2::to_string(mytype::myvalue) + "\n"; } 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 571d076d41..9d5b37d186 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 @@ -32,7 +32,7 @@ std::string y {"\n"}; std::ranges::for_each(vec, [_0 = (&y)](auto const& x) mutable -> 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) mutable -> 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 59273a7443..5d5ac18632 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 @@ -61,9 +61,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 537ad68968..87ed59800f 100644 --- a/regression-tests/test-results/mixed-initialization-safety-3.cpp +++ b/regression-tests/test-results/mixed-initialization-safety-3.cpp @@ -55,9 +55,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 20f619d6f2..6695daa92d 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 786216c8b5..c826a236de 100644 --- a/regression-tests/test-results/mixed-postexpression-with-capture.cpp +++ b/regression-tests/test-results/mixed-postexpression-with-capture.cpp @@ -58,10 +58,10 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void #line 19 "mixed-postexpression-with-capture.cpp2" { cpp2::finally_presuccess cpp2_finally_presuccess; - cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), ""); - cpp2_finally_presuccess.add([&, _1 = CPP2_UFCS_0(size, vec)]{cpp2::Default.expects(CPP2_UFCS_0(size, vec) == _1 + 1, "");} ); + cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS(ssize)(vec)), ""); + cpp2_finally_presuccess.add([&, _1 = CPP2_UFCS(size)(vec)]{cpp2::Default.expects(CPP2_UFCS(size)(vec) == _1 + 1, "");} ); #line 20 "mixed-postexpression-with-capture.cpp2" - CPP2_UFCS(push_back, vec, val); + CPP2_UFCS(push_back)(vec, val); } [[nodiscard]] auto make_string() -> make_string_ret @@ -69,7 +69,7 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void { cpp2::finally_presuccess cpp2_finally_presuccess; std::string ret {"xyzzy"}; - cpp2_finally_presuccess.add([&, _1 = CPP2_UFCS_0(length, ret)]{cpp2::Default.expects(CPP2_UFCS_0(length, ret) == _1 + 5, "");} ); + cpp2_finally_presuccess.add([&, _1 = CPP2_UFCS(length)(ret)]{cpp2::Default.expects(CPP2_UFCS(length)(ret) == _1 + 5, "");} ); #line 26 "mixed-postexpression-with-capture.cpp2" ret += " and "; cpp2_finally_presuccess.run(); return std::move(ret); } @@ -81,7 +81,7 @@ cpp2_finally_presuccess.run(); return std::move(ret); } cpp2::finally_presuccess cpp2_finally_presuccess; std::string a {"xyzzy"}; std::string b {"plugh"}; -cpp2_finally_presuccess.add([&]{cpp2::Default.expects([_0 = CPP2_UFCS_0(length, a), _1 = CPP2_UFCS_0(length, b), _2 = 5]{ return _0==_1 && _1==_2; }(), "");} ); +cpp2_finally_presuccess.add([&]{cpp2::Default.expects([_0 = CPP2_UFCS(length)(a), _1 = CPP2_UFCS(length)(b), _2 = 5]{ return _0==_1 && _1==_2; }(), "");} ); #line 30 "mixed-postexpression-with-capture.cpp2" cpp2_finally_presuccess.run(); return { std::move(a), std::move(b) }; 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 57ca722e6a..84d7c27a7f 100644 --- a/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp +++ b/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp @@ -29,12 +29,12 @@ auto call([[maybe_unused]] auto const& unnamed_param_1, [[maybe_unused]] auto co [[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 336af2ac2d..322f0bd1ff 100644 --- a/regression-tests/test-results/mixed-string-interpolation.cpp +++ b/regression-tests/test-results/mixed-string-interpolation.cpp @@ -32,7 +32,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 a1e4b43a86..6f77b35e69 100644 --- a/regression-tests/test-results/mixed-type-safety-1.cpp +++ b/regression-tests/test-results/mixed-type-safety-1.cpp @@ -57,7 +57,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, std::move(c))}; // safe by Lifetime + Shape* s {CPP2_UFCS(get)(std::move(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 35d8198584..b0e49b28a7 100644 --- a/regression-tests/test-results/mixed-ufcs-multiple-template-arguments.cpp +++ b/regression-tests/test-results/mixed-ufcs-multiple-template-arguments.cpp @@ -41,6 +41,6 @@ struct X { std::cout << substr<4,8>(test_string) << "\n"; X x {std::move(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/msvc-2022/mixed-bugfix-for-ufcs-non-local.cpp.execution b/regression-tests/test-results/msvc-2022/mixed-bugfix-for-ufcs-non-local.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/msvc-2022/mixed-bugfix-for-ufcs-non-local.cpp.output b/regression-tests/test-results/msvc-2022/mixed-bugfix-for-ufcs-non-local.cpp.output new file mode 100644 index 0000000000..f3f5e9025f --- /dev/null +++ b/regression-tests/test-results/msvc-2022/mixed-bugfix-for-ufcs-non-local.cpp.output @@ -0,0 +1 @@ +mixed-bugfix-for-ufcs-non-local.cpp diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-arguments.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-arguments.cpp.execution new file mode 100644 index 0000000000..0e41b78197 --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-arguments.cpp.execution @@ -0,0 +1,4 @@ +0123456789 +9 +0123456789 +9 diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-arguments.cpp.output b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-arguments.cpp.output new file mode 100644 index 0000000000..c20b9908a1 --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-arguments.cpp.output @@ -0,0 +1 @@ +pure2-bugfix-for-ufcs-arguments.cpp diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-name-lookup.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-name-lookup.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-name-lookup.cpp.output b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-name-lookup.cpp.output new file mode 100644 index 0000000000..cfe4625ad4 --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-name-lookup.cpp.output @@ -0,0 +1 @@ +pure2-bugfix-for-ufcs-name-lookup.cpp diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-noexcept.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-noexcept.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-noexcept.cpp.output b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-noexcept.cpp.output new file mode 100644 index 0000000000..c7322ce84c --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-noexcept.cpp.output @@ -0,0 +1 @@ +pure2-bugfix-for-ufcs-noexcept.cpp diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-sfinae.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-sfinae.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-sfinae.cpp.output b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-sfinae.cpp.output new file mode 100644 index 0000000000..5d72f97501 --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-ufcs-sfinae.cpp.output @@ -0,0 +1 @@ +pure2-bugfix-for-ufcs-sfinae.cpp diff --git a/regression-tests/test-results/pure2-bounds-safety-span.cpp b/regression-tests/test-results/pure2-bounds-safety-span.cpp index fe8957d96f..17966588e7 100644 --- a/regression-tests/test-results/pure2-bounds-safety-span.cpp +++ b/regression-tests/test-results/pure2-bounds-safety-span.cpp @@ -35,7 +35,7 @@ auto print_and_decorate(auto const& thing) -> void; static_cast(std::move(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 0000000000..2aaf66023e --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-arguments.cpp @@ -0,0 +1,159 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-bugfix-for-ufcs-arguments.cpp2" + +#line 7 "pure2-bugfix-for-ufcs-arguments.cpp2" +class t; + + +#line 58 "pure2-bugfix-for-ufcs-arguments.cpp2" +namespace ns { +template class t; + + +} + +class A; + + +#line 68 "pure2-bugfix-for-ufcs-arguments.cpp2" +class B; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-ufcs-arguments.cpp2" +[[nodiscard]] auto print_res(cpp2::in x) -> cpp2::i32; + +#line 7 "pure2-bugfix-for-ufcs-arguments.cpp2" +class t { + public: [[nodiscard]] auto f() & -> cpp2::i32; + public: [[nodiscard]] auto f([[maybe_unused]] auto const& unnamed_param_2) & -> cpp2::i32; + public: template [[nodiscard]] auto f() & -> cpp2::i32; + public: template [[nodiscard]] auto f([[maybe_unused]] auto const& unnamed_param_2) & -> cpp2::i32; + public: template [[nodiscard]] auto f([[maybe_unused]] auto const& unnamed_param_2, [[maybe_unused]] auto const& unnamed_param_3) & -> cpp2::i32; +}; + +[[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1) -> cpp2::i32; +[[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2) -> cpp2::i32; +template [[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1) -> cpp2::i32; +template [[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2) -> cpp2::i32; +template [[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2, [[maybe_unused]] auto const& unnamed_param_3) -> cpp2::i32; + +extern t m; +extern t const n; +template auto inline constexpr a = n; + +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; +extern cpp2::i32 auto_32_1; +extern cpp2::i32 auto_33_1; +extern cpp2::i32 auto_34_1; +extern cpp2::i32 auto_35_1; + +auto main() -> int; + +#line 55 "pure2-bugfix-for-ufcs-arguments.cpp2" +// _: i32 = 0.std::min(0); +extern cpp2::i32 auto_56_1; + +namespace ns { +template class t { + public: template [[nodiscard]] static auto f([[maybe_unused]] cpp2::in unnamed_param_1) -> cpp2::i32; +}; +} // namespace ns + +class A { + public: auto f() const& -> void; +}; + +class B { + public: A m; + public: auto f() const& -> void; +}; + + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-bugfix-for-ufcs-arguments.cpp2" +[[nodiscard]] auto print_res(cpp2::in x) -> cpp2::i32{ +#line 2 "pure2-bugfix-for-ufcs-arguments.cpp2" + std::cout << x; + if (x == 9) {std::cout << '\n'; } + return x; +} + +#line 8 "pure2-bugfix-for-ufcs-arguments.cpp2" + [[nodiscard]] auto t::f() & -> cpp2::i32 { return print_res(0); } + [[nodiscard]] auto t::f([[maybe_unused]] auto const& unnamed_param_2) & -> cpp2::i32 { return print_res(1); } + template [[nodiscard]] auto t::f() & -> cpp2::i32 { return print_res(2); } + template [[nodiscard]] auto t::f([[maybe_unused]] auto const& unnamed_param_2) & -> cpp2::i32 { return print_res(3); } + template [[nodiscard]] auto t::f([[maybe_unused]] auto const& unnamed_param_2, [[maybe_unused]] auto const& unnamed_param_3) & -> cpp2::i32 { return print_res(4); } + +#line 15 "pure2-bugfix-for-ufcs-arguments.cpp2" +[[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1) -> cpp2::i32 { return print_res(5); } +[[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2) -> cpp2::i32 { return print_res(6); } +template [[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1) -> cpp2::i32 { return print_res(7); } +template [[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2) -> cpp2::i32 { return print_res(8); } +template [[nodiscard]] auto f([[maybe_unused]] cpp2::in unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2, [[maybe_unused]] auto const& unnamed_param_3) -> cpp2::i32 { return print_res(9); } + +t m {}; +t const n {}; + +#line 25 "pure2-bugfix-for-ufcs-arguments.cpp2" +cpp2::i32 auto_25_1 {CPP2_UFCS_NONLOCAL(f)(m)}; +cpp2::i32 auto_26_1 {CPP2_UFCS_NONLOCAL(f)(m, 0)}; +cpp2::i32 auto_27_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(m)}; +cpp2::i32 auto_28_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(m, 0)}; +cpp2::i32 auto_29_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(m, 0, 0)}; +cpp2::i32 auto_30_1 {CPP2_UFCS_NONLOCAL(f)(n)}; +cpp2::i32 auto_31_1 {CPP2_UFCS_NONLOCAL(f)(n, 0)}; +cpp2::i32 auto_32_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(n)}; +cpp2::i32 auto_33_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(n, 0)}; +cpp2::i32 auto_34_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(n, 0, 0)}; +cpp2::i32 auto_35_1 {CPP2_UFCS_TEMPLATE_NONLOCAL(f)(a, 0, 0)}; + +auto main() -> int{ + static_cast(CPP2_UFCS(f)(m)); + static_cast(CPP2_UFCS(f)(m, 0)); + static_cast(CPP2_UFCS_TEMPLATE(f)(m)); + static_cast(CPP2_UFCS_TEMPLATE(f)(m, 0)); + static_cast(CPP2_UFCS_TEMPLATE(f)(m, 0, 0)); + static_cast(CPP2_UFCS(f)(n)); + static_cast(CPP2_UFCS(f)(n, 0)); + static_cast(CPP2_UFCS_TEMPLATE(f)(n)); + static_cast(CPP2_UFCS_TEMPLATE(f)(n, 0)); + static_cast(CPP2_UFCS_TEMPLATE(f)(n, 0, 0)); + static_cast(CPP2_UFCS_TEMPLATE(f)(a, 0, 0)); + + static_cast([](auto const& a, auto const& f) mutable -> void{static_cast(CPP2_UFCS(f)(CPP2_UFCS(f)(a, a))); }); + // _ = 0.std::min(0); + static_cast(CPP2_UFCS_QUALIFIED_TEMPLATE((ns::t<0,0>::),f<0>)(0)); +} + +#line 56 "pure2-bugfix-for-ufcs-arguments.cpp2" +cpp2::i32 auto_56_1 {CPP2_UFCS_QUALIFIED_TEMPLATE_NONLOCAL((ns::t<0,0>::),f<0>)(0)}; + +namespace ns { + + template template [[nodiscard]] auto t::f([[maybe_unused]] cpp2::in unnamed_param_1) -> cpp2::i32 { return 0; } + +} + +#line 65 "pure2-bugfix-for-ufcs-arguments.cpp2" + auto A::f() const& -> void{} + +#line 70 "pure2-bugfix-for-ufcs-arguments.cpp2" + auto B::f() const& -> void { CPP2_UFCS(f)(m); } + 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 0000000000..e230534bf5 --- /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-name-lookup.cpp b/regression-tests/test-results/pure2-bugfix-for-ufcs-name-lookup.cpp new file mode 100644 index 0000000000..82f964e1f4 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-name-lookup.cpp @@ -0,0 +1,177 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-bugfix-for-ufcs-name-lookup.cpp2" +class identity; +#line 2 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + + +#line 5 "pure2-bugfix-for-ufcs-name-lookup.cpp2" +class t; + + +#line 9 "pure2-bugfix-for-ufcs-name-lookup.cpp2" +class u; + +namespace ns { + +} + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-ufcs-name-lookup.cpp2" +class identity { +#line 2 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + public: [[nodiscard]] constexpr auto operator()(auto&& x) const& -> auto&&; +}; + +class t { + public: [[nodiscard]] constexpr auto f() const& -> int; +}; + +class u {}; + +namespace ns { +[[nodiscard]] constexpr auto f([[maybe_unused]] auto const& unnamed_param_1) -> int; +} // namespace ns + +// v: @struct type = { +// f :== :(_) 0; // Pending on #706. +// g: (i) i.f(); +// } + +auto main() -> int; + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + +#line 2 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + [[nodiscard]] constexpr auto identity::operator()(auto&& x) const& -> auto&& { return CPP2_FORWARD(x); } + +#line 6 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + [[nodiscard]] constexpr auto t::f() const& -> int { return 0; } + +#line 11 "pure2-bugfix-for-ufcs-name-lookup.cpp2" +namespace ns { +[[nodiscard]] constexpr auto f([[maybe_unused]] auto const& unnamed_param_1) -> int { return 1; } +} + +#line 20 "pure2-bugfix-for-ufcs-name-lookup.cpp2" +auto main() -> int{ + { + int f {CPP2_UFCS(f)(t())}; + cpp2::Default.expects(std::move(f) == 0, ""); + } + { + auto f {t().f()}; + cpp2::Default.expects(std::move(f) == 0, ""); + } + { + auto f {t().f()}; + cpp2::Default.expects(std::move(f) == 0, ""); + } +{ +auto const& f = t().f(); +#line 33 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + cpp2::Default.expects(f == 0, ""); +} +{ +auto const& f = t().f(); +#line 34 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + cpp2::Default.expects(f == 0, ""); +} +#line 35 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + { + auto constexpr f = t().f(); + static_assert(f == 0); + } + { + auto constexpr f = t().f(); + static_assert(f == 0); + } + { + auto f {[](auto const& f) mutable -> auto{ + cpp2::Default.expects(CPP2_UFCS(f)(t()) == 0, ""); + return CPP2_UFCS(f)(u()); + }(identity())}; + static_cast(std::move(f)); + } + { // Rejected by MSVC. + // f := : (copy _: std::integral_constant) -> _ = { + // assert(t().f() == 0); + // return u().f(); + // }(:std::integral_constant = ()); + // _ = f; + } + { + auto f {[]() mutable -> void{ +{ +cpp2::in f = identity(); +#line 59 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + cpp2::Default.expects(CPP2_UFCS(f)(t()) == 0, ""); +} +{ +cpp2::in f = identity(); +#line 60 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + static_cast(CPP2_UFCS(f)(u())); +} +#line 61 "pure2-bugfix-for-ufcs-name-lookup.cpp2" + }}; + static_cast(std::move(f)); + } + { + auto f {[]() mutable -> void{ + using ns::f; + static_assert(CPP2_UFCS(f)(t()) == 0); + // static_assert(u().f() == 1); + }}; + static_cast(std::move(f)); + } + { + auto f {[]() mutable -> void{ + static_assert(t().f() == 0); + auto g {[]([[maybe_unused]] T const& unnamed_param_1) mutable -> std::void_t{}}; + static_assert(!(std::is_invocable_v)); + using ns::f; + }}; + static_cast(std::move(f)); + } + { + auto f {[]() mutable -> void{ + using ns::f; + static_cast([]() mutable -> void{ + static_assert(CPP2_UFCS(f)(t()) == 0); + // static_assert(u().f() == 1); + }); + { + static_assert(CPP2_UFCS(f)(t()) == 0); + // static_assert(u().f() == 1); + } + }}; + static_cast(std::move(f)); + } + { + auto f {[]() mutable -> void{ + static_cast([]() mutable -> void{ + static_assert(t().f() == 0); + auto g {[]([[maybe_unused]] T const& unnamed_param_1) mutable -> std::void_t{}}; + static_assert(!(std::is_invocable_v)); + }); + { + static_assert(t().f() == 0); + auto g {[]([[maybe_unused]] T const& unnamed_param_1) mutable -> std::void_t{}}; + static_assert(!(std::is_invocable_v)); + } + using ns::f; + }}; + static_cast(std::move(f)); + } +} + diff --git a/regression-tests/test-results/pure2-bugfix-for-ufcs-name-lookup.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-ufcs-name-lookup.cpp2.output new file mode 100644 index 0000000000..3b1880cad2 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-name-lookup.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-ufcs-name-lookup.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 0000000000..3f6ce3590a --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-noexcept.cpp @@ -0,0 +1,38 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-bugfix-for-ufcs-noexcept.cpp2" +class t; +#line 2 "pure2-bugfix-for-ufcs-noexcept.cpp2" + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-ufcs-noexcept.cpp2" +class t { +#line 2 "pure2-bugfix-for-ufcs-noexcept.cpp2" + public: virtual 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 1 "pure2-bugfix-for-ufcs-noexcept.cpp2" + +#line 2 "pure2-bugfix-for-ufcs-noexcept.cpp2" + auto t::swap([[maybe_unused]] t const& that) noexcept -> void{}// Non-`virtual` blocked on #508, idiomatic form on #507. + +auto main() -> int{ + static_assert(noexcept(CPP2_UFCS(swap)(t(), t())));// Fails on Clang 12 (lambda in unevaluated context) and GCC 10 (static assertion failed) +} + 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 0000000000..6ff4d0ebb6 --- /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 0000000000..670896b1b5 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp @@ -0,0 +1,40 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-bugfix-for-ufcs-sfinae.cpp2" + +#line 3 "pure2-bugfix-for-ufcs-sfinae.cpp2" +class B; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-ufcs-sfinae.cpp2" +template [[nodiscard]] auto f() -> std::type_identity_t; + +#line 3 "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 4 "pure2-bugfix-for-ufcs-sfinae.cpp2" + +auto main() -> int; + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-bugfix-for-ufcs-sfinae.cpp2" +template [[nodiscard]] auto f() -> std::type_identity_t{}// Fails on Clang 12 (lambda in unevaluated context). + +#line 5 "pure2-bugfix-for-ufcs-sfinae.cpp2" +auto main() -> int{ + auto g {[]([[maybe_unused]] T const& unnamed_param_1) mutable -> std::void_t())>{}}; + static_assert(!(std::is_invocable_v)); +} + 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 0000000000..9d817f3073 --- /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-enum.cpp b/regression-tests/test-results/pure2-enum.cpp index 496db02a53..31b802e61a 100644 --- a/regression-tests/test-results/pure2-enum.cpp +++ b/regression-tests/test-results/pure2-enum.cpp @@ -234,7 +234,7 @@ inline CPP2_CONSTEXPR file_attributes file_attributes::none = 0; #line 28 "pure2-enum.cpp2" auto main() -> int{ auto j {janus::past}; - CPP2_UFCS_0(flip, j); + CPP2_UFCS(flip)(j); static_cast(std::move(j)); // x : skat_game = 9; // error, can't construct skat_game from integer @@ -246,8 +246,8 @@ auto main() -> int{ // if x == 9 { } // error, can't compare skat_game and integer // if x == rgb::red { } // error, can't compare skat_game and rgb color - std::cout << "x.to_string() is " + cpp2::to_string(CPP2_UFCS_0(to_string, x)) + "\n"; - std::cout << "x2.to_string() is " + cpp2::to_string(CPP2_UFCS_0(to_string, std::move(x2))) + "\n"; + std::cout << "x.to_string() is " + cpp2::to_string(CPP2_UFCS(to_string)(x)) + "\n"; + std::cout << "x2.to_string() is " + cpp2::to_string(CPP2_UFCS(to_string)(std::move(x2))) + "\n"; std::cout << "with if else: "; if (x == skat_game::diamonds) { // ok, can compare two skat_games @@ -279,41 +279,41 @@ auto main() -> int{ x = skat_game::diamonds; // ok, can assign one skat_game from another - std::cout << "file_attributes::cached.get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, file_attributes::cached)) + "\n"; - std::cout << "file_attributes::current.get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, file_attributes::current)) + "\n"; - std::cout << "file_attributes::obsolete.get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, file_attributes::obsolete)) + "\n"; - std::cout << "file_attributes::cached_and_current.get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, file_attributes::cached_and_current)) + "\n"; + std::cout << "file_attributes::cached.get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(file_attributes::cached)) + "\n"; + std::cout << "file_attributes::current.get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(file_attributes::current)) + "\n"; + std::cout << "file_attributes::obsolete.get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(file_attributes::obsolete)) + "\n"; + std::cout << "file_attributes::cached_and_current.get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(file_attributes::cached_and_current)) + "\n"; file_attributes f {file_attributes::cached_and_current}; f &= file_attributes::cached | file_attributes::obsolete; - std::cout << "f. get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, f)) + "\n"; + std::cout << "f. get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(f)) + "\n"; auto f2 {file_attributes::cached}; - std::cout << "f2.get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, f2)) + "\n"; + std::cout << "f2.get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(f2)) + "\n"; - std::cout << "f is " << CPP2_UFCS_0(to_string, f) << "\n"; - std::cout << "f2 is " << CPP2_UFCS_0(to_string, f2) << "\n"; + std::cout << "f is " << CPP2_UFCS(to_string)(f) << "\n"; + std::cout << "f2 is " << CPP2_UFCS(to_string)(f2) << "\n"; - CPP2_UFCS(clear, f2, f2); - std::cout << "f2 is " << CPP2_UFCS_0(to_string, f2) << "\n"; - CPP2_UFCS(set, f2, file_attributes::cached); - std::cout << "f2 is " << CPP2_UFCS_0(to_string, f2) << "\n"; + CPP2_UFCS(clear)(f2, f2); + std::cout << "f2 is " << CPP2_UFCS(to_string)(f2) << "\n"; + CPP2_UFCS(set)(f2, file_attributes::cached); + std::cout << "f2 is " << CPP2_UFCS(to_string)(f2) << "\n"; - std::cout << "f. get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, f)) + "\n"; - std::cout << "f2.get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, f2)) + "\n"; + std::cout << "f. get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(f)) + "\n"; + std::cout << "f2.get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(f2)) + "\n"; std::cout << "f is (f2) is " + cpp2::to_string(cpp2::is(f, (f2))) + "\n"; std::cout << "f2 is (f ) is " + cpp2::to_string(cpp2::is(f2, (f))) + "\n\n"; - CPP2_UFCS(clear, f, f2); - CPP2_UFCS(set, f, file_attributes::current | f2); + CPP2_UFCS(clear)(f, f2); + CPP2_UFCS(set)(f, file_attributes::current | f2); f |= file_attributes::obsolete; f2 |= file_attributes::current; - std::cout << "f is " << CPP2_UFCS_0(to_string, f) << "\n"; - std::cout << "f2 is " << CPP2_UFCS_0(to_string, f2) << "\n"; - std::cout << "f. get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, f)) + "\n"; - std::cout << "f2.get_raw_value() is " + cpp2::to_string(CPP2_UFCS_0(get_raw_value, f2)) + "\n"; + std::cout << "f is " << CPP2_UFCS(to_string)(f) << "\n"; + std::cout << "f2 is " << CPP2_UFCS(to_string)(f2) << "\n"; + std::cout << "f. get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(f)) + "\n"; + std::cout << "f2.get_raw_value() is " + cpp2::to_string(CPP2_UFCS(get_raw_value)(f2)) + "\n"; std::cout << "f == f2 is " + cpp2::to_string(f == f2 ) + "\n"; std::cout << "f is (f2) is " + cpp2::to_string(cpp2::is(f, (f2))) + "\n"; std::cout << "f2 is (f ) is " + cpp2::to_string(cpp2::is(f2, (f))) + "\n"; 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 1d23607bf2..bca795385b 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** 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 c8efedd8cd..7db678fe93 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-interpolation.cpp b/regression-tests/test-results/pure2-interpolation.cpp index accfacaed4..9659c51349 100644 --- a/regression-tests/test-results/pure2-interpolation.cpp +++ b/regression-tests/test-results/pure2-interpolation.cpp @@ -61,9 +61,9 @@ auto const& x = item(); #line 25 "pure2-interpolation.cpp2" { - std::cout << std::left << std::setw(20) << CPP2_UFCS_0(name, x) << " color " << std::left << std::setw(10) << CPP2_UFCS_0(color, x) << " price " << std::setw(10) << std::setprecision(3) << CPP2_UFCS_0(price, x) << " in stock = " << std::boolalpha << (cpp2::cmp_greater(CPP2_UFCS_0(count, x),0)) << "\n"; + std::cout << std::left << std::setw(20) << CPP2_UFCS(name)(x) << " color " << std::left << std::setw(10) << CPP2_UFCS(color)(x) << " price " << std::setw(10) << std::setprecision(3) << CPP2_UFCS(price)(x) << " in stock = " << std::boolalpha << (cpp2::cmp_greater(CPP2_UFCS(count)(x),0)) << "\n"; - std::cout << cpp2::to_string(CPP2_UFCS_0(name, x), "{:20}") + " color " + cpp2::to_string(CPP2_UFCS_0(color, x), "{:10}") + " price " + cpp2::to_string(CPP2_UFCS_0(price, x), "{: <10.2f}") + " in stock = " + cpp2::to_string(cpp2::cmp_greater(CPP2_UFCS_0(count, x),0)) + "\n"; + std::cout << cpp2::to_string(CPP2_UFCS(name)(x), "{:20}") + " color " + cpp2::to_string(CPP2_UFCS(color)(x), "{:10}") + " price " + cpp2::to_string(CPP2_UFCS(price)(x), "{: <10.2f}") + " in stock = " + cpp2::to_string(cpp2::cmp_greater(CPP2_UFCS(count)(x),0)) + "\n"; } } 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 4b41c06d87..5fcc86c9c1 100644 --- a/regression-tests/test-results/pure2-intro-example-hello-2022.cpp +++ b/regression-tests/test-results/pure2-intro-example-hello-2022.cpp @@ -36,7 +36,7 @@ auto print_it(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 print_it(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 9ea76e0b0a..02bce27abb 100644 --- a/regression-tests/test-results/pure2-intro-example-three-loops.cpp +++ b/regression-tests/test-results/pure2-intro-example-three-loops.cpp @@ -44,7 +44,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-print.cpp b/regression-tests/test-results/pure2-print.cpp index ff88280cb1..ecf7323227 100644 --- a/regression-tests/test-results/pure2-print.cpp +++ b/regression-tests/test-results/pure2-print.cpp @@ -99,11 +99,11 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42; if (cpp2::cmp_less(*cpp2::assert_not_null(p),0)) { ret = -*cpp2::assert_not_null(std::move(p)); } - ret += strlen(s) - 10 + CPP2_UFCS_0(strlen, std::move(s)) * (16 / (3 & 2)) % 3; + ret += strlen(s) - 10 + CPP2_UFCS(strlen)(std::move(s)) * (16 / (3 & 2)) % 3; map m {}; CPP2_ASSERT_IN_BOUNDS(m, 0) = cpp2::as_("har"); - ret -= CPP2_UFCS_0(length, h("x", m)); + ret -= CPP2_UFCS(length)(h("x", m)); static_cast(std::move(m)); return ret; @@ -113,22 +113,22 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42; #line 34 "pure2-print.cpp2" { - cpp2::Default.expects(CPP2_UFCS_0(empty, m) == false || false, "message"); - cpp2::Bounds.expects([_0 = 0, _1 = CPP2_UFCS_0(ssize, m), _2 = 100]{ return cpp2::cmp_less(_0,_1) && cpp2::cmp_less(_1,_2); }() && true != false, ""); + cpp2::Default.expects(CPP2_UFCS(empty)(m) == false || false, "message"); + cpp2::Bounds.expects([_0 = 0, _1 = CPP2_UFCS(ssize)(m), _2 = 100]{ return cpp2::cmp_less(_0,_1) && cpp2::cmp_less(_1,_2); }() && true != false, ""); #line 35 "pure2-print.cpp2" auto a {[]() mutable -> void{}}; auto b {[]() mutable -> void{}}; auto c {[]() mutable -> void{}}; - for( ; CPP2_UFCS_0(empty, s); a() ) {break; } + for( ; CPP2_UFCS(empty)(s); a() ) {break; } - do {} while ( CPP2_UFCS_0(empty, s) && [&]{ b() ; return true; }() ); + do {} while ( CPP2_UFCS(empty)(s) && [&]{ b() ; return true; }() ); for ( [[maybe_unused]] auto const& unnamed_param_1 : m ) { { do {goto CONTINUE_43_13; } while (false); c(); } CPP2_CONTINUE_BREAK(43_13) } #line 45 "pure2-print.cpp2" - if (cpp2::is(!(CPP2_UFCS_0(empty, s)), (true))) {std::move(a)(); } - else {if (!(CPP2_UFCS_0(empty, m))) {std::move(b)(); } + if (cpp2::is(!(CPP2_UFCS(empty)(s)), (true))) {std::move(a)(); } + else {if (!(CPP2_UFCS(empty)(m))) {std::move(b)(); } else {std::move(c)(); }} cpp2::Default.expects(true, ""); @@ -167,9 +167,9 @@ requires ((std::is_convertible_v && ...)) {(std::cout << .. #line 80 "pure2-print.cpp2" ::outer::mytype var {}; - cout << CPP2_UFCS(g, var, 42) << "\n"; + cout << CPP2_UFCS(g)(var, 42) << "\n"; - cout << [&] () -> namespace_alias::string { auto&& _expr = CPP2_UFCS(g, std::move(var), 42); + cout << [&] () -> namespace_alias::string { auto&& _expr = CPP2_UFCS(g)(std::move(var), 42); if (cpp2::is(_expr, 43)) { if constexpr( requires{"forty-and-three";} ) if constexpr( std::is_convertible_v ) return "forty-and-three"; else return namespace_alias::string{}; else return namespace_alias::string{}; } else return "default case"; } () << "\n"; diff --git a/regression-tests/test-results/pure2-stdio-with-raii.cpp b/regression-tests/test-results/pure2-stdio-with-raii.cpp index 5ff84f1f4a..288673a879 100644 --- a/regression-tests/test-results/pure2-stdio-with-raii.cpp +++ b/regression-tests/test-results/pure2-stdio-with-raii.cpp @@ -26,6 +26,6 @@ [[nodiscard]] auto main() -> int{ std::string s {"Fred"}; 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 b274a9e907..4ae3e58ae0 100644 --- a/regression-tests/test-results/pure2-stdio.cpp +++ b/regression-tests/test-results/pure2-stdio.cpp @@ -29,7 +29,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 c8b2d26ffb..5475cb418e 100644 --- a/regression-tests/test-results/pure2-type-safety-1.cpp +++ b/regression-tests/test-results/pure2-type-safety-1.cpp @@ -43,7 +43,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 acd3c5d5c9..f504f31411 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 b8f3773413..36923c68da 100644 --- a/regression-tests/test-results/pure2-types-basics.cpp +++ b/regression-tests/test-results/pure2-types-basics.cpp @@ -177,19 +177,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 auto_74_5 {"abracadabra"}; N::myclass auto_75_5 {}; N::myclass auto_76_5 {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-down-upcast.cpp b/regression-tests/test-results/pure2-types-down-upcast.cpp index 8efea7e256..04773a6933 100644 --- a/regression-tests/test-results/pure2-types-down-upcast.cpp +++ b/regression-tests/test-results/pure2-types-down-upcast.cpp @@ -77,18 +77,18 @@ auto func_const(cpp2::in b) -> void{std::cout << "Call B const: " + cpp2::to_ auto test_const_foo() -> void{ A s {}; A const* sC {&s}; - CPP2_UFCS_0(const_foo, s); - CPP2_UFCS_0(const_foo, (*cpp2::assert_not_null(sC))); - CPP2_UFCS_0(const_foo, (cpp2::as_(s))); - CPP2_UFCS_0(const_foo, (cpp2::as_(*cpp2::assert_not_null(sC)))); + CPP2_UFCS(const_foo)(s); + CPP2_UFCS(const_foo)((*cpp2::assert_not_null(sC))); + CPP2_UFCS(const_foo)((cpp2::as_(s))); + CPP2_UFCS(const_foo)((cpp2::as_(*cpp2::assert_not_null(sC)))); static_cast(std::move(s)); static_cast(std::move(sC)); } auto test_mut_foo() -> void{ A s {}; - CPP2_UFCS_0(mut_foo, s); - CPP2_UFCS_0(mut_foo, (cpp2::as_(s))); + CPP2_UFCS(mut_foo)(s); + CPP2_UFCS(mut_foo)((cpp2::as_(s))); static_cast(std::move(s)); } diff --git a/regression-tests/test-results/pure2-types-inheritance.cpp b/regression-tests/test-results/pure2-types-inheritance.cpp index 6053247428..200fe752dd 100644 --- a/regression-tests/test-results/pure2-types-inheritance.cpp +++ b/regression-tests/test-results/pure2-types-inheritance.cpp @@ -128,18 +128,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 90e02ce982..3e7490c648 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 @@ -152,7 +152,7 @@ namespace N { // Exercise '_' anonymous objects too while we're at it cpp2::finally auto_37_9 {[&]() mutable -> 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 } } @@ -166,7 +166,7 @@ namespace N { #line 51 "pure2-types-order-independence-and-nesting.cpp2" 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 { @@ -186,7 +186,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 93bbb2edd3..51eb83cb9d 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 @@ -120,24 +120,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 e277b12bde..0184f7b9da 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 @@ -125,24 +125,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 8ee8527bb2..4176a137cd 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 @@ -124,24 +124,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 d2be0d5605..daeb6165f7 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 @@ -124,24 +124,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 2f658ba124..359cdcb1f9 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 @@ -130,24 +130,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 5df1797c63..5fb031b397 100644 --- a/regression-tests/test-results/pure2-types-that-parameters.cpp +++ b/regression-tests/test-results/pure2-types-that-parameters.cpp @@ -85,16 +85,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 b04ddeffd5..592a89e3ed 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 @@ -38,27 +38,27 @@ extern int y; [[nodiscard]] auto main() -> int{ #line 2 "pure2-ufcs-member-access-and-chaining.cpp2" 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)); + static_cast(CPP2_UFCS(ufcs)(j)); - static_cast(CPP2_UFCS_0(ufcs, fun())); + static_cast(CPP2_UFCS(ufcs)(fun())); auto k {fun()}; - 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)))); + static_cast(CPP2_UFCS(ufcs)((std::move(j)))); - CPP2_UFCS_0(no_return, 42); + CPP2_UFCS(no_return)(42); - CPP2_UFCS_0(no_return, std::move(res)); + CPP2_UFCS(no_return)(std::move(res)); } auto no_return([[maybe_unused]] auto const& unnamed_param_1) -> void{} @@ -80,5 +80,5 @@ auto no_return([[maybe_unused]] auto const& unnamed_param_1) -> void{} #line 42 "pure2-ufcs-member-access-and-chaining.cpp2" [[nodiscard]] auto f([[maybe_unused]] auto const& unnamed_param_1) -> int { return 0; } -int y {CPP2_UFCS_0_NONLOCAL(f, 0)}; +int y {CPP2_UFCS_NONLOCAL(f)(0)}; diff --git a/regression-tests/test-results/pure2-union.cpp b/regression-tests/test-results/pure2-union.cpp index 484ced7333..e11a7a6b7a 100644 --- a/regression-tests/test-results/pure2-union.cpp +++ b/regression-tests/test-results/pure2-union.cpp @@ -107,26 +107,26 @@ name_or_number::name_or_number(){} name_or_number::name_or_number(name_or_number const& that) : _storage{ } , _discriminator{ -1 }{ -if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));} -if (CPP2_UFCS_0(is_num, that)) {set_num(CPP2_UFCS_0(num, that));} +if (CPP2_UFCS(is_name)(that)) {set_name(CPP2_UFCS(name)(that));} +if (CPP2_UFCS(is_num)(that)) {set_num(CPP2_UFCS(num)(that));} } name_or_number::name_or_number(name_or_number&& that) noexcept : _storage{ } , _discriminator{ -1 }{ -if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));} -if (CPP2_UFCS_0(is_num, std::move(that))) {set_num(CPP2_UFCS_0(num, std::move(that)));} +if (CPP2_UFCS(is_name)(std::move(that))) {set_name(CPP2_UFCS(name)(std::move(that)));} +if (CPP2_UFCS(is_num)(std::move(that))) {set_num(CPP2_UFCS(num)(std::move(that)));} } auto name_or_number::operator=(name_or_number const& that) -> name_or_number& { -if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));} -if (CPP2_UFCS_0(is_num, that)) {set_num(CPP2_UFCS_0(num, that));} +if (CPP2_UFCS(is_name)(that)) {set_name(CPP2_UFCS(name)(that));} +if (CPP2_UFCS(is_num)(that)) {set_num(CPP2_UFCS(num)(that));} return *this; } auto name_or_number::operator=(name_or_number&& that) noexcept -> name_or_number& { -if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));} -if (CPP2_UFCS_0(is_num, std::move(that))) {set_num(CPP2_UFCS_0(num, std::move(that)));} +if (CPP2_UFCS(is_name)(std::move(that))) {set_name(CPP2_UFCS(name)(std::move(that)));} +if (CPP2_UFCS(is_num)(std::move(that))) {set_num(CPP2_UFCS(num)(std::move(that)));} return *this; } #line 12 "pure2-union.cpp2" @@ -163,33 +163,33 @@ template name_or_other::name_or_other(){} template name_or_other::name_or_other(name_or_other const& that) : _storage{ } , _discriminator{ -1 }{ - if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));} - if (CPP2_UFCS_0(is_other, that)) {set_other(CPP2_UFCS_0(other, that));} + if (CPP2_UFCS(is_name)(that)) {set_name(CPP2_UFCS(name)(that));} + if (CPP2_UFCS(is_other)(that)) {set_other(CPP2_UFCS(other)(that));} } template name_or_other::name_or_other(name_or_other&& that) noexcept : _storage{ } , _discriminator{ -1 }{ - if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));} - if (CPP2_UFCS_0(is_other, std::move(that))) {set_other(CPP2_UFCS_0(other, std::move(that)));} + if (CPP2_UFCS(is_name)(std::move(that))) {set_name(CPP2_UFCS(name)(std::move(that)));} + if (CPP2_UFCS(is_other)(std::move(that))) {set_other(CPP2_UFCS(other)(std::move(that)));} } template auto name_or_other::operator=(name_or_other const& that) -> name_or_other& { - if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));} - if (CPP2_UFCS_0(is_other, that)) {set_other(CPP2_UFCS_0(other, that));} + if (CPP2_UFCS(is_name)(that)) {set_name(CPP2_UFCS(name)(that));} + if (CPP2_UFCS(is_other)(that)) {set_other(CPP2_UFCS(other)(that));} return *this; } template auto name_or_other::operator=(name_or_other&& that) noexcept -> name_or_other& { - if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));} - if (CPP2_UFCS_0(is_other, std::move(that))) {set_other(CPP2_UFCS_0(other, std::move(that)));} + if (CPP2_UFCS(is_name)(std::move(that))) {set_name(CPP2_UFCS(name)(std::move(that)));} + if (CPP2_UFCS(is_other)(std::move(that))) {set_other(CPP2_UFCS(other)(std::move(that)));} return *this; } #line 19 "pure2-union.cpp2" auto print_name(cpp2::in non) -> void{ - if (CPP2_UFCS_0(is_name, non)) { - std::cout << CPP2_UFCS_0(name, non) << "\n"; + if (CPP2_UFCS(is_name)(non)) { + std::cout << CPP2_UFCS(name)(non) << "\n"; } else { std::cout << "(not a name)\n"; @@ -200,16 +200,16 @@ auto main() -> int{ name_or_number x {}; std::cout << "sizeof(x) is " + cpp2::to_string(sizeof(x)) + "\n"; - CPP2_UFCS_0(print_name, x); + CPP2_UFCS(print_name)(x); - CPP2_UFCS(set_name, x, "xyzzy", cpp2::as_()); + CPP2_UFCS(set_name)(x, "xyzzy", cpp2::as_()); - CPP2_UFCS_0(print_name, std::move(x)); + CPP2_UFCS(print_name)(std::move(x)); { name_or_other val {}; - CPP2_UFCS(set_other, val, 42); - std::cout << CPP2_UFCS_0(to_string, std::move(val)); + CPP2_UFCS(set_other)(val, 42); + std::cout << CPP2_UFCS(to_string)(std::move(val)); } } diff --git a/source/reflect.h b/source/reflect.h index 94946ab112..fa0a0d0a21 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -745,14 +745,14 @@ namespace meta { auto compiler_services::set_metafunction_name(cpp2::in name, cpp2::in> args) & -> void{ metafunction_name = name; metafunction_args = args; - metafunctions_used = CPP2_UFCS_0(empty, args); + metafunctions_used = CPP2_UFCS(empty)(args); } [[nodiscard]] auto compiler_services::get_metafunction_name() const& -> std::string_view { return metafunction_name; } [[nodiscard]] auto compiler_services::get_argument(cpp2::in index) & -> std::string{ metafunctions_used = true; - if (([_0 = 0, _1 = index, _2 = CPP2_UFCS_0(ssize, metafunction_args)]{ return cpp2::cmp_less_eq(_0,_1) && cpp2::cmp_less(_1,_2); }())) { + if (([_0 = 0, _1 = index, _2 = CPP2_UFCS(ssize)(metafunction_args)]{ return cpp2::cmp_less_eq(_0,_1) && cpp2::cmp_less(_1,_2); }())) { return CPP2_ASSERT_IN_BOUNDS(metafunction_args, index); } return ""; @@ -766,49 +766,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) mutable -> void{ - static_cast(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 88 "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 99 "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 - static_cast(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) ); } @@ -833,10 +833,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, metafunction_name))) { + if (!(CPP2_UFCS(empty)(metafunction_name))) { message = "while applying @" + metafunction_name + " - " + message; } - static_cast(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{} @@ -864,9 +864,9 @@ 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))); } - [[nodiscard]] auto declaration_base::print() const& -> std::string { return CPP2_UFCS(pretty_print_visualize, (*cpp2::assert_not_null(n)), 0); } + [[nodiscard]] auto declaration_base::print() const& -> std::string { return CPP2_UFCS(pretty_print_visualize)((*cpp2::assert_not_null(n)), 0); } declaration_base::~declaration_base() noexcept{} declaration_base::declaration_base(declaration_base const& that) @@ -885,43 +885,43 @@ 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 { static_cast(CPP2_UFCS_0(make_public, (*cpp2::assert_not_null(n)))); } - auto declaration::default_to_protected() & -> void { static_cast(CPP2_UFCS_0(make_protected, (*cpp2::assert_not_null(n)))); } - auto declaration::default_to_private() & -> void { static_cast(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_base_object() const& -> bool { return CPP2_UFCS_0(is_base_object, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_member_object() const& -> bool { return CPP2_UFCS_0(is_member_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_base_object() const& -> bool { return CPP2_UFCS(is_base_object)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_member_object() const& -> bool { return CPP2_UFCS(is_member_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::is_type_alias() const& -> bool { return CPP2_UFCS_0(is_type_alias, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_namespace_alias() const& -> bool { return CPP2_UFCS_0(is_namespace_alias, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_object_alias() const& -> bool { return CPP2_UFCS_0(is_object_alias, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_type_alias() const& -> bool { return CPP2_UFCS(is_type_alias)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_namespace_alias() const& -> bool { return CPP2_UFCS(is_namespace_alias)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_object_alias() const& -> bool { return CPP2_UFCS(is_object_alias)((*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::is_function_expression() const& -> bool { return CPP2_UFCS_0(is_function_expression, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::is_function_expression() const& -> bool { return CPP2_UFCS(is_function_expression)((*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)); } @@ -930,24 +930,24 @@ declaration_base::declaration_base(declaration_base const& that) [[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_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_type_alias() const& -> bool { return CPP2_UFCS_0(parent_is_type_alias, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::parent_is_namespace_alias() const& -> bool { return CPP2_UFCS_0(parent_is_namespace_alias, (*cpp2::assert_not_null(n))); } - [[nodiscard]] auto declaration::parent_is_object_alias() const& -> bool { return CPP2_UFCS_0(parent_is_object_alias, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_type_alias() const& -> bool { return CPP2_UFCS(parent_is_type_alias)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_namespace_alias() const& -> bool { return CPP2_UFCS(parent_is_namespace_alias)((*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::parent_is_object_alias() const& -> bool { return CPP2_UFCS(parent_is_object_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_polymorphic() const& -> bool { return CPP2_UFCS(parent_is_polymorphic)((*cpp2::assert_not_null(n))); } auto declaration::mark_for_removal_from_enclosing_type() & -> void { cpp2::Type.expects(parent_is_type(), ""); #line 292 "reflect.h2" - auto test {CPP2_UFCS_0(type_member_mark_for_removal, (*cpp2::assert_not_null(n)))}; + auto test {CPP2_UFCS(type_member_mark_for_removal)((*cpp2::assert_not_null(n)))}; cpp2::Default.expects(std::move(test), ""); // ... to ensure this assert is true } @@ -965,46 +965,46 @@ declaration::declaration(declaration const& that) #line 310 "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 { static_cast(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) }{} @@ -1019,21 +1019,21 @@ declaration::declaration(declaration const& that) #line 367 "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; @@ -1052,14 +1052,14 @@ declaration::declaration(declaration const& that) #line 403 "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))), ""); } auto type_declaration::reserve_names(cpp2::in name, auto&& ...etc) const& -> void { // etc is not declared ':string_view' for compatibility with GCC 10.x for ( auto const& m : get_members() ) { - CPP2_UFCS(require, m, !(CPP2_UFCS(has_name, m, name)), + CPP2_UFCS(require)(m, !(CPP2_UFCS(has_name)(m, name)), "in a '" + cpp2::to_string(get_metafunction_name()) + "' type, the name '" + cpp2::to_string(name) + "' is reserved for use by the '" + cpp2::to_string(get_metafunction_name()) + "' implementation"); } if constexpr (!(CPP2_PACK_EMPTY(etc))) { @@ -1067,16 +1067,16 @@ declaration::declaration(declaration const& that) } } - [[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) ) { - static_cast(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; } @@ -1085,8 +1085,8 @@ declaration::declaration(declaration const& that) { std::vector ret {}; - 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))); + 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; } @@ -1095,8 +1095,8 @@ declaration::declaration(declaration const& that) { std::vector ret {}; - 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))); + 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; } @@ -1105,8 +1105,8 @@ declaration::declaration(declaration const& that) { std::vector ret {}; - for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::aliases) ) { - static_cast(CPP2_UFCS(emplace_back, ret, d, (*this))); + for ( auto const& d : CPP2_UFCS(get_type_scope_declarations)((*cpp2::assert_not_null(n)), declaration_node::aliases) ) { + static_cast(CPP2_UFCS(emplace_back)(ret, d, (*this))); } return ret; } @@ -1115,8 +1115,8 @@ declaration::declaration(declaration const& that) { std::vector ret {}; - 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))); + 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; } @@ -1130,7 +1130,7 @@ declaration::declaration(declaration const& that) cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; #line 482 "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); @@ -1140,15 +1140,15 @@ declaration::declaration(declaration const& that) auto type_declaration::add_member(cpp2::in source) & -> void { auto decl {parse_statement(source)}; - if (!(decl) || !(CPP2_UFCS(add_type_member, (*cpp2::assert_not_null(n)), std::move(decl)))) { + if (!(decl) || !(CPP2_UFCS(add_type_member)((*cpp2::assert_not_null(n)), std::move(decl)))) { error(std::string("error attempting to add member:\n") + source); } } - auto type_declaration::remove_marked_members() & -> void { CPP2_UFCS_0(type_remove_marked_members, (*cpp2::assert_not_null(n))); } - auto type_declaration::remove_all_members() & -> void { CPP2_UFCS_0(type_remove_all_members, (*cpp2::assert_not_null(n))); } + auto type_declaration::remove_marked_members() & -> void { CPP2_UFCS(type_remove_marked_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) }{} @@ -1163,7 +1163,7 @@ declaration::declaration(declaration const& that) #line 516 "reflect.h2" { - cpp2::Default.expects(CPP2_UFCS_0(is_alias, (*cpp2::assert_not_null(n))), ""); + cpp2::Default.expects(CPP2_UFCS(is_alias)((*cpp2::assert_not_null(n))), ""); } alias_declaration::alias_declaration(alias_declaration const& that) @@ -1172,7 +1172,7 @@ declaration::declaration(declaration const& that) #line 535 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { - CPP2_UFCS(add_member, t, "operator=: (virtual move this) = { }"); + CPP2_UFCS(add_member)(t, "operator=: (virtual move this) = { }"); } #line 553 "reflect.h2" @@ -1180,25 +1180,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); } } @@ -1207,23 +1207,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_default_access, 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_default_access)(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); } } @@ -1235,20 +1235,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(add_member, t, "operator<=>: (this, that) -> std::" + (cpp2::as_(ordering)) + ";"); + CPP2_UFCS(add_member)(t, "operator<=>: (this, that) -> std::" + (cpp2::as_(ordering)) + ";"); } } @@ -1277,7 +1277,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 @@ -1285,67 +1285,67 @@ 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(add_member, t, "operator=: (out this, that) = { }"); + CPP2_UFCS(add_member)(t, "operator=: (out this, that) = { }"); }} } #line 739 "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_0(is_default_access, mf), + CPP2_UFCS(require)(mf, !(CPP2_UFCS(is_destructor)(mf)) || CPP2_UFCS(is_public)(mf) || CPP2_UFCS(is_default_access)(mf), "a value type may not have a non-public destructor"); } if (!(std::move(has_default_ctor))) { - CPP2_UFCS(add_member, t, "operator=: (out this) = { }"); + CPP2_UFCS(add_member)(t, "operator=: (out this) = { }"); } } #line 767 "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 811 "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 852 "reflect.h2" @@ -1360,14 +1360,14 @@ auto basic_enum( cpp2::i64 max_value {}; cpp2::deferred_init underlying_type; - CPP2_UFCS(reserve_names, t, "operator=", "operator<=>"); + CPP2_UFCS(reserve_names)(t, "operator=", "operator<=>"); if (bitwise) { - CPP2_UFCS(reserve_names, t, "has", "set", "clear", "to_string", "get_raw_value", "none"); + CPP2_UFCS(reserve_names)(t, "has", "set", "clear", "to_string", "get_raw_value", "none"); } // 1. Gather: The names of all the user-written members, and find/compute the type - underlying_type.construct(CPP2_UFCS(get_argument, t, 0));// use the first template argument, if there was one + underlying_type.construct(CPP2_UFCS(get_argument)(t, 0));// use the first template argument, if there was one auto found_non_numeric {false}; { @@ -1375,23 +1375,23 @@ std::string value = "-1"; #line 875 "reflect.h2" for ( - auto const& m : CPP2_UFCS_0(get_members, t) ) - if ( CPP2_UFCS_0(is_member_object, m)) + auto const& m : CPP2_UFCS(get_members)(t) ) + if ( CPP2_UFCS(is_member_object)(m)) { - CPP2_UFCS(require, m, CPP2_UFCS_0(is_public, m) || CPP2_UFCS_0(is_default_access, m), + CPP2_UFCS(require)(m, CPP2_UFCS(is_public)(m) || CPP2_UFCS(is_default_access)(m), "an enumerator cannot be protected or private"); - auto mo {CPP2_UFCS_0(as_object, m)}; - if (!(CPP2_UFCS_0(has_wildcard_type, mo))) { - CPP2_UFCS(error, mo, "an explicit underlying type should be specified as a template argument to the metafunction - try 'enum' or 'flag_enum'"); + auto mo {CPP2_UFCS(as_object)(m)}; + if (!(CPP2_UFCS(has_wildcard_type)(mo))) { + CPP2_UFCS(error)(mo, "an explicit underlying type should be specified as a template argument to the metafunction - try 'enum' or 'flag_enum'"); } - auto init {CPP2_UFCS_0(initializer, mo)}; + auto init {CPP2_UFCS(initializer)(mo)}; auto is_default_or_numeric {is_empty_or_a_decimal_number(init)}; - found_non_numeric |= !(CPP2_UFCS_0(empty, init)) && !(is_default_or_numeric); - CPP2_UFCS(require, m, !(is_default_or_numeric) || !(found_non_numeric) || CPP2_UFCS(has_name, mo, "none"), - cpp2::to_string(CPP2_UFCS_0(name, mo)) + ": enumerators with non-numeric values must come after all default and numeric values"); + found_non_numeric |= !(CPP2_UFCS(empty)(init)) && !(is_default_or_numeric); + CPP2_UFCS(require)(m, !(is_default_or_numeric) || !(found_non_numeric) || CPP2_UFCS(has_name)(mo, "none"), + cpp2::to_string(CPP2_UFCS(name)(mo)) + ": enumerators with non-numeric values must come after all default and numeric values"); nextval(value, init); @@ -1404,10 +1404,10 @@ std::string value = "-1"; } // Adding local variable 'e' to work around a Clang warning - value_member_info e {cpp2::as_(CPP2_UFCS_0(name, mo)), "", value}; - CPP2_UFCS(push_back, enumerators, e); + value_member_info e {cpp2::as_(CPP2_UFCS(name)(mo)), "", value}; + CPP2_UFCS(push_back)(enumerators, e); - CPP2_UFCS_0(mark_for_removal_from_enclosing_type, mo); + CPP2_UFCS(mark_for_removal_from_enclosing_type)(mo); } } @@ -1415,7 +1415,7 @@ std::string value = "-1"; #line 912 "reflect.h2" if (underlying_type.value() == "") { - CPP2_UFCS(require, t, !(std::move(found_non_numeric)), + CPP2_UFCS(require)(t, !(std::move(found_non_numeric)), "if you write an enumerator with a non-numeric-literal value, you must specify the enumeration's underlying type"); if (!(bitwise)) { @@ -1432,7 +1432,7 @@ std::string value = "-1"; underlying_type.value() = "i64"; } else { - CPP2_UFCS(error, t, "values are outside the range representable by the largest supported underlying signed type (i64)"); + CPP2_UFCS(error)(t, "values are outside the range representable by the largest supported underlying signed type (i64)"); }}}} } else { @@ -1457,34 +1457,34 @@ std::string value = "-1"; // // Note that most values and functions are declared as '==' compile-time values, i.e. Cpp1 'constexpr' - CPP2_UFCS_0(remove_marked_members, t); + CPP2_UFCS(remove_marked_members)(t); // Generate all the common material: value and common functions - CPP2_UFCS(add_member, t, " _value : " + cpp2::to_string(underlying_type.value()) + ";"); - CPP2_UFCS(add_member, t, " private operator= : (implicit out this, _val: i64) == _value = cpp2::unsafe_narrow<" + cpp2::to_string(underlying_type.value()) + ">(_val);"); - CPP2_UFCS(add_member, t, " get_raw_value : (this) -> " + cpp2::to_string(std::move(underlying_type.value())) + " == _value;"); - CPP2_UFCS(add_member, t, " operator= : (out this, that) == { }"); - CPP2_UFCS(add_member, t, " operator<=> : (this, that) -> std::strong_ordering;"); + CPP2_UFCS(add_member)(t, " _value : " + cpp2::to_string(underlying_type.value()) + ";"); + CPP2_UFCS(add_member)(t, " private operator= : (implicit out this, _val: i64) == _value = cpp2::unsafe_narrow<" + cpp2::to_string(underlying_type.value()) + ">(_val);"); + CPP2_UFCS(add_member)(t, " get_raw_value : (this) -> " + cpp2::to_string(std::move(underlying_type.value())) + " == _value;"); + CPP2_UFCS(add_member)(t, " operator= : (out this, that) == { }"); + CPP2_UFCS(add_member)(t, " operator<=> : (this, that) -> std::strong_ordering;"); // Generate the bitwise operations and 'none' value, if appropriate if (bitwise) { value_member_info e {"none", "", "0"}; - CPP2_UFCS(push_back, enumerators, std::move(e)); - - CPP2_UFCS(add_member, t, " operator|=: ( inout this, that ) == _value |= that._value;"); - CPP2_UFCS(add_member, t, " operator&=: ( inout this, that ) == _value &= that._value;"); - CPP2_UFCS(add_member, t, " operator^=: ( inout this, that ) == _value ^= that._value;"); - CPP2_UFCS(add_member, t, " operator| : ( this, that ) -> " + cpp2::to_string(CPP2_UFCS_0(name, t)) + " == _value | that._value;"); - CPP2_UFCS(add_member, t, " operator& : ( this, that ) -> " + cpp2::to_string(CPP2_UFCS_0(name, t)) + " == _value & that._value;"); - CPP2_UFCS(add_member, t, " operator^ : ( this, that ) -> " + cpp2::to_string(CPP2_UFCS_0(name, t)) + " == _value ^ that._value;"); - CPP2_UFCS(add_member, t, " has : ( inout this, that ) -> bool == _value & that._value;"); - CPP2_UFCS(add_member, t, " set : ( inout this, that ) == _value |= that._value;"); - CPP2_UFCS(add_member, t, " clear : ( inout this, that ) == _value &= that._value~;"); + CPP2_UFCS(push_back)(enumerators, std::move(e)); + + CPP2_UFCS(add_member)(t, " operator|=: ( inout this, that ) == _value |= that._value;"); + CPP2_UFCS(add_member)(t, " operator&=: ( inout this, that ) == _value &= that._value;"); + CPP2_UFCS(add_member)(t, " operator^=: ( inout this, that ) == _value ^= that._value;"); + CPP2_UFCS(add_member)(t, " operator| : ( this, that ) -> " + cpp2::to_string(CPP2_UFCS(name)(t)) + " == _value | that._value;"); + CPP2_UFCS(add_member)(t, " operator& : ( this, that ) -> " + cpp2::to_string(CPP2_UFCS(name)(t)) + " == _value & that._value;"); + CPP2_UFCS(add_member)(t, " operator^ : ( this, that ) -> " + cpp2::to_string(CPP2_UFCS(name)(t)) + " == _value ^ that._value;"); + CPP2_UFCS(add_member)(t, " has : ( inout this, that ) -> bool == _value & that._value;"); + CPP2_UFCS(add_member)(t, " set : ( inout this, that ) == _value |= that._value;"); + CPP2_UFCS(add_member)(t, " clear : ( inout this, that ) == _value &= that._value~;"); } // Add the enumerators for ( auto const& e : enumerators ) { - CPP2_UFCS(add_member, t, " " + cpp2::to_string(e.name) + " : " + cpp2::to_string(CPP2_UFCS_0(name, t)) + " == " + cpp2::to_string(e.value) + ";"); + CPP2_UFCS(add_member)(t, " " + cpp2::to_string(e.name) + " : " + cpp2::to_string(CPP2_UFCS(name)(t)) + " == " + cpp2::to_string(e.value) + ";"); } { std::string to_string = " to_string: (this) -> std::string = { \n"; @@ -1517,10 +1517,10 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; to_string += " return _ret+\")\";\n}\n"; } else { - to_string += " return \"invalid " + cpp2::to_string(CPP2_UFCS_0(name, t)) + " value\";\n}\n"; + to_string += " return \"invalid " + cpp2::to_string(CPP2_UFCS(name)(t)) + " value\";\n}\n"; } - CPP2_UFCS(add_member, t, std::move(to_string)); + CPP2_UFCS(add_member)(t, std::move(to_string)); } } #line 1018 "reflect.h2" @@ -1530,9 +1530,9 @@ std::string to_string = " to_string: (this) -> std::string = { \n"; auto cpp2_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with an incrementing value generator - CPP2_UFCS(basic_enum, t, + CPP2_UFCS(basic_enum)(t, [](std::string& value, cpp2::in specified_value) mutable -> void{ - if (!(CPP2_UFCS_0(empty, specified_value))) { + if (!(CPP2_UFCS(empty)(specified_value))) { value = specified_value; }else { auto v {std::strtoll(&CPP2_ASSERT_IN_BOUNDS(value, 0), nullptr, 10)}; @@ -1547,9 +1547,9 @@ auto cpp2_enum(meta::type_declaration& t) -> void auto flag_enum(meta::type_declaration& t) -> void { // Let basic_enum do its thing, with a power-of-two value generator - CPP2_UFCS(basic_enum, t, + CPP2_UFCS(basic_enum)(t, [](std::string& value, cpp2::in specified_value) mutable -> void{ - if (!(CPP2_UFCS_0(empty, specified_value))) { + if (!(CPP2_UFCS(empty)(specified_value))) { value = specified_value; }else { auto v {std::strtoll(&CPP2_ASSERT_IN_BOUNDS(value, 0), nullptr, 10)}; @@ -1577,37 +1577,37 @@ auto value = 0; #line 1110 "reflect.h2" for ( - auto const& m : CPP2_UFCS_0(get_members, t) ) { do - if ( CPP2_UFCS_0(is_member_object, m)) + auto const& m : CPP2_UFCS(get_members)(t) ) { do + if ( CPP2_UFCS(is_member_object)(m)) { - CPP2_UFCS(require, m, CPP2_UFCS_0(is_public, m) || CPP2_UFCS_0(is_default_access, m), + CPP2_UFCS(require)(m, CPP2_UFCS(is_public)(m) || CPP2_UFCS(is_default_access)(m), "a union alternative cannot be protected or private"); - CPP2_UFCS(require, m, !(CPP2_UFCS(starts_with, CPP2_UFCS_0(name, m), "is_")) - && !(CPP2_UFCS(starts_with, CPP2_UFCS_0(name, m), "set_")), + CPP2_UFCS(require)(m, !(CPP2_UFCS(starts_with)(CPP2_UFCS(name)(m), "is_")) + && !(CPP2_UFCS(starts_with)(CPP2_UFCS(name)(m), "set_")), "a union alternative's name cannot start with 'is_' or 'set_' - that could cause user confusion with the 'is_alternative' and 'set_alternative' generated functions"); - auto mo {CPP2_UFCS_0(as_object, m)}; - CPP2_UFCS(require, mo, CPP2_UFCS_0(empty, CPP2_UFCS_0(initializer, mo)), + auto mo {CPP2_UFCS(as_object)(m)}; + CPP2_UFCS(require)(mo, CPP2_UFCS(empty)(CPP2_UFCS(initializer)(mo)), "a union alternative cannot have an initializer"); // Adding local variable 'e' to work around a Clang warning - value_member_info e {cpp2::as_(CPP2_UFCS_0(name, mo)), CPP2_UFCS_0(type, mo), cpp2::as_(value)}; - CPP2_UFCS(push_back, alternatives, e); + value_member_info e {cpp2::as_(CPP2_UFCS(name)(mo)), CPP2_UFCS(type)(mo), cpp2::as_(value)}; + CPP2_UFCS(push_back)(alternatives, e); - CPP2_UFCS_0(mark_for_removal_from_enclosing_type, mo); + CPP2_UFCS(mark_for_removal_from_enclosing_type)(mo); } while (false); ++value; } } #line 1133 "reflect.h2" std::string discriminator_type {}; - if (cpp2::cmp_less(CPP2_UFCS_0(ssize, alternatives),std::numeric_limits::max())) { + if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i8"; } - else {if (cpp2::cmp_less(CPP2_UFCS_0(ssize, alternatives),std::numeric_limits::max())) { + else {if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i16"; } - else {if (cpp2::cmp_less(CPP2_UFCS_0(ssize, alternatives),std::numeric_limits::max())) { + else {if (cpp2::cmp_less(CPP2_UFCS(ssize)(alternatives),std::numeric_limits::max())) { discriminator_type = "i32"; } else { @@ -1617,7 +1617,7 @@ auto value = 0; #line 1148 "reflect.h2" // 2. Replace: Erase the contents and replace with modified contents - CPP2_UFCS_0(remove_marked_members, t); + CPP2_UFCS(remove_marked_members)(t); { std::string storage = " _storage: std::aligned_storage_t bool = _discriminator == " + cpp2::to_string(a.value) + ";\n"); + CPP2_UFCS(add_member)(t, " is_" + cpp2::to_string(a.name) + ": (this) -> bool = _discriminator == " + cpp2::to_string(a.value) + ";\n"); - CPP2_UFCS(add_member, t, " " + cpp2::to_string(a.name) + ": (this) -> forward " + cpp2::to_string(a.type) + " pre(is_" + cpp2::to_string(a.name) + "()) = reinterpret_cast<* const " + cpp2::to_string(a.type) + ">(_storage&)*;\n"); + CPP2_UFCS(add_member)(t, " " + cpp2::to_string(a.name) + ": (this) -> forward " + cpp2::to_string(a.type) + " pre(is_" + cpp2::to_string(a.name) + "()) = reinterpret_cast<* const " + cpp2::to_string(a.type) + ">(_storage&)*;\n"); - CPP2_UFCS(add_member, t, " " + cpp2::to_string(a.name) + ": (inout this) -> forward " + cpp2::to_string(a.type) + " pre(is_" + cpp2::to_string(a.name) + "()) = reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&)*;\n"); + CPP2_UFCS(add_member)(t, " " + cpp2::to_string(a.name) + ": (inout this) -> forward " + cpp2::to_string(a.type) + " pre(is_" + cpp2::to_string(a.name) + "()) = reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&)*;\n"); - CPP2_UFCS(add_member, t, " set_" + cpp2::to_string(a.name) + ": (inout this, _value: " + cpp2::to_string(a.type) + ") = { if !is_" + cpp2::to_string(a.name) + "() { _destroy(); std::construct_at( reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&), _value); } else { reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&)* = _value; } _discriminator = " + cpp2::to_string(a.value) + "; }\n"); + CPP2_UFCS(add_member)(t, " set_" + cpp2::to_string(a.name) + ": (inout this, _value: " + cpp2::to_string(a.type) + ") = { if !is_" + cpp2::to_string(a.name) + "() { _destroy(); std::construct_at( reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&), _value); } else { reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&)* = _value; } _discriminator = " + cpp2::to_string(a.value) + "; }\n"); - CPP2_UFCS(add_member, t, " set_" + cpp2::to_string(a.name) + ": (inout this, forward _args...: _) = { if !is_" + cpp2::to_string(a.name) + "() { _destroy(); std::construct_at( reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&), _args...); } else { reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&)* = :" + cpp2::to_string(a.type) + " = (_args...); } _discriminator = " + cpp2::to_string(a.value) + "; }\n"); + CPP2_UFCS(add_member)(t, " set_" + cpp2::to_string(a.name) + ": (inout this, forward _args...: _) = { if !is_" + cpp2::to_string(a.name) + "() { _destroy(); std::construct_at( reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&), _args...); } else { reinterpret_cast<*" + cpp2::to_string(a.type) + ">(_storage&)* = :" + cpp2::to_string(a.type) + " = (_args...); } _discriminator = " + cpp2::to_string(a.value) + "; }\n"); } { std::string destroy = " private _destroy: (inout this) = {\n"; @@ -1674,16 +1674,16 @@ std::string destroy = " private _destroy: (inout this) = {\n"; destroy += " _discriminator = -1;\n"; destroy += " }\n"; - CPP2_UFCS(add_member, t, std::move(destroy)); + CPP2_UFCS(add_member)(t, std::move(destroy)); } } // Add the destructor #line 1198 "reflect.h2" - CPP2_UFCS(add_member, t, " operator=: (move this) = { _destroy(); }"); + CPP2_UFCS(add_member)(t, " operator=: (move this) = { _destroy(); }"); // Add default constructor - CPP2_UFCS(add_member, t, " operator=: (out this) = { }"); + CPP2_UFCS(add_member)(t, " operator=: (out this) = { }"); { std::string value_set = ""; @@ -1697,12 +1697,12 @@ std::string value_set = ""; } value_set += " }\n"; - CPP2_UFCS(add_member, t, std::string(" operator=: (out this, that) = {\n") + CPP2_UFCS(add_member)(t, std::string(" operator=: (out this, that) = {\n") + " _storage = ();\n" + " _discriminator = -1;\n" + value_set ); - CPP2_UFCS(add_member, t, std::string(" operator=: (inout this, that) = {\n") + CPP2_UFCS(add_member)(t, std::string(" operator=: (inout this, that) = {\n") + " _storage = _;\n" + " _discriminator = _;\n" + std::move(value_set) @@ -1715,7 +1715,7 @@ std::string value_set = ""; #line 1230 "reflect.h2" auto print(cpp2::in t) -> void { - std::cout << CPP2_UFCS_0(print, t) << "\n"; + std::cout << CPP2_UFCS(print)(t) << "\n"; } #line 1240 "reflect.h2" @@ -1726,13 +1726,13 @@ auto print(cpp2::in t) -> void ) -> bool { - cpp2::Default.expects(CPP2_UFCS_0(is_type, n), ""); + cpp2::Default.expects(CPP2_UFCS(is_type)(n), ""); // Check for _names reserved for the metafunction implementation for ( - auto const& m : CPP2_UFCS_0(get_members, rtype) ) + auto const& m : CPP2_UFCS(get_members)(rtype) ) { - CPP2_UFCS(require, m, !(CPP2_UFCS(starts_with, CPP2_UFCS_0(name, m), "_")) || cpp2::cmp_greater(CPP2_UFCS_0(ssize, CPP2_UFCS_0(name, m)),1), + CPP2_UFCS(require)(m, !(CPP2_UFCS(starts_with)(CPP2_UFCS(name)(m), "_")) || cpp2::cmp_greater(CPP2_UFCS(ssize)(CPP2_UFCS(name)(m)),1), "a type that applies a metafunction cannot have a body that declares a name that starts with '_' - those names are reserved for the metafunction implementation"); } @@ -1742,15 +1742,15 @@ auto print(cpp2::in t) -> void { // Convert the name and any template arguments to strings // and record that in rtype - auto name {CPP2_UFCS_0(to_string, (*cpp2::assert_not_null(meta)))}; - name = CPP2_UFCS(substr, name, 0, CPP2_UFCS(find, name, '<')); + auto name {CPP2_UFCS(to_string)((*cpp2::assert_not_null(meta)))}; + name = CPP2_UFCS(substr)(name, 0, CPP2_UFCS(find)(name, '<')); std::vector args {}; for ( - auto const& arg : CPP2_UFCS_0(template_arguments, (*cpp2::assert_not_null(meta))) ) - CPP2_UFCS(push_back, args, CPP2_UFCS_0(to_string, arg)); + auto const& arg : CPP2_UFCS(template_arguments)((*cpp2::assert_not_null(meta))) ) + CPP2_UFCS(push_back)(args, CPP2_UFCS(to_string)(arg)); - CPP2_UFCS(set_metafunction_name, rtype, name, args); + CPP2_UFCS(set_metafunction_name)(rtype, name, args); // Dispatch // @@ -1806,8 +1806,8 @@ auto print(cpp2::in t) -> void }}}}}}}}}}}}}}} if (( - !(CPP2_UFCS_0(empty, args)) - && !(CPP2_UFCS_0(arguments_were_used, rtype)))) + !(CPP2_UFCS(empty)(args)) + && !(CPP2_UFCS(arguments_were_used)(rtype)))) { error(name + " did not use its template arguments - did you mean to write '" + name + " <" + CPP2_ASSERT_IN_BOUNDS(args, 0) + "> type' (with the spaces)?"); diff --git a/source/to_cpp1.h b/source/to_cpp1.h index 5b7711ecdc..3a0c1847f0 100644 --- a/source/to_cpp1.h +++ b/source/to_cpp1.h @@ -1029,6 +1029,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; @@ -1041,8 +1043,26 @@ class cppfront }; std::vector current_args = { {} }; + struct active_using_declaration { + token const* identifier = {}; + + explicit active_using_declaration(using_statement_node const& n) { + if (auto id = get_if(&n.id->id)) { + identifier = (*id)->ids.back().id->identifier; + } + } + }; + + using source_order_name_lookup_res = + std::optional>; + + // Stack of the currently active nested declarations we're inside std::vector current_declarations = { {} }; + // Stack of the currently active names for source order name lookup: + // Like 'current_declarations' + also parameters and using declarations + std::vector current_names = { {} }; + // Maintain a stack of the functions we're currently processing, which can // be up to MaxNestedFunctions in progress (if we run out, bump the Max). // The main reason for this is to be able to pass function_info's, especially @@ -1790,7 +1810,10 @@ class cppfront //----------------------------------------------------------------------- // - auto emit(qualified_id_node const& n) + auto emit( + qualified_id_node const& n, + bool include_unqualified_id = true + ) -> void { if (!sema.check(n)) { @@ -1814,7 +1837,7 @@ class cppfront auto ident = std::string{}; printer.emit_to_string(&ident); - for (auto const& id : n.ids) + for (auto const& id : std::span{n.ids}.first(n.ids.size() - !include_unqualified_id)) { if (id.scope_op) { emit(*id.scope_op); @@ -1859,7 +1882,7 @@ class cppfront // auto emit( id_expression_node const& n, - bool is_local_name = true + bool is_local_name = true ) -> void { @@ -2471,6 +2494,8 @@ class cppfront if (n.for_namespace) { printer.print_cpp2(" namespace", n.position()); + } else { + current_names.push_back(active_using_declaration{n}); } printer.print_cpp2(" " + print_to_string(*n.id) + ";", n.position()); @@ -2772,6 +2797,89 @@ class cppfront return is_pointer_declaration(decl, deref_cnt, addr_cnt); } + + auto source_order_name_lookup(unqualified_id_node const& id) + -> source_order_name_lookup_res + { + for ( + auto first = current_names.rbegin(), last = current_names.rend() - 1; + first != last; + ++first + ) + { + if ( + auto decl = get_if(&*first); + decl + && *decl + && (*decl)->has_name(*id.identifier) + ) + { + return *decl; + } + else if ( + auto using_ = get_if(&*first); + using_ + && using_->identifier + && *using_->identifier == *id.identifier + ) + { + return *using_; + } + } + + return {}; + } + + + auto lookup_finds_variable_with_placeholder_type_under_initialization(id_expression_node const& n) + -> bool + { + if (!n.is_unqualified()) + { + return false; + } + + auto const& id = *get(n.id); + auto lookup = source_order_name_lookup(id); + + if ( + !lookup + || get_if(&*lookup) + ) + { + return false; + } + + auto decl = get(*lookup); + if ( + decl + && decl->has_name(*id.identifier) + ) + { + if ( + !decl->is_object() + && !decl->is_object_alias() + ) + { + return false; + } + + if (decl->is_object()) { + auto type = &**get_if(&decl->type); + return type->is_wildcard() + && contains(current_declarations, decl); + } + auto const& type = (**get_if(&decl->type)).type_id; + return ( + !type + || type->is_wildcard() + ) + && contains(current_declarations, decl); + } + + return false; + } + //----------------------------------------------------------------------- // auto emit( @@ -3006,8 +3114,8 @@ class cppfront } } - // Going backwards if we found LeftParen it might be UFCS - // expr_list is emitted to 'args' for future use + // Going backwards if we found LeftParen it might be UFCS + // expr_list is emitted to 'args' for future use if (i->op->type() == lexeme::LeftParen) { assert(i->op); @@ -3022,13 +3130,19 @@ class cppfront flush_args(); args.emplace(std::move(local_args)); } - // Going backwards if we found Dot and there is args variable - // it means that it should be handled by UFCS + // Going backwards if we found Dot and there is args variable + // it means that it should be handled by UFCS else if( i->op->type() == lexeme::Dot && args + // Disable UFCS if name lookup would hard-error (#550). + // That happens when it finds that the function identifier being called is the name + // of a variable with deduced type and we are in its initializer (e.g., x := y.x();) + // So lower it to a member call instead, the only possible valid meaning. + && !lookup_finds_variable_with_placeholder_type_under_initialization(*i->id_expr) ) { + // The function name is the argument to the macro auto funcname = print_to_string(*i->id_expr); // First, build the UFCS macro name @@ -3037,18 +3151,18 @@ class cppfront // If there are template arguments, use the _TEMPLATE version if (std::ssize(i->id_expr->template_arguments()) > 0) { + // If it is qualified, use the _QUALIFIED version + if (i->id_expr->is_qualified()) { + ufcs_string += "_QUALIFIED"; + // And split the unqualified id in the function name as two macro arguments + auto& id = *get(i->id_expr->id); + funcname = + "(" + + print_to_string(id, false) + + "::)," + + print_to_string(*cpp2::assert_not_null(id.ids.back().id), false, true, true); + } 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) @@ -3063,6 +3177,19 @@ class cppfront current_declarations.back()->is_object() && current_declarations.back()->parent_is_namespace() ) + || ( + ( + current_declarations.back()->is_alias() + || ( + current_declarations.back()->is_function() + && current_declarations.back() == having_signature_emitted + ) + ) + && ( + current_declarations.back()->parent_is_namespace() + || current_declarations.back()->parent_is_type() + ) + ) ) { ufcs_string += "_NONLOCAL"; @@ -3070,7 +3197,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) { @@ -3820,6 +3947,51 @@ class cppfront } + // Consider moving these `stack` functions to `common.h` to enable more general use. + + template + auto stack_value( + T& var, + std::type_identity_t const& value + ) + -> auto + { + return finally([&var, old = std::exchange(var, value)]() { + var = old; + }); + } + + template + auto stack_element( + std::vector& cont, + std::type_identity_t const& value + ) + -> auto + { + cont.push_back(value); + return finally([&]{ cont.pop_back(); }); + } + + template + auto stack_size(std::vector& cont) + -> auto + { + return finally([&, size = cont.size()]{ cont.resize(size); }); + } + + template + auto stack_size_if( + std::vector& cont, + bool cond + ) + -> std::optional + { + if (cond) { + return stack_size(cont); + } + return {}; + } + //----------------------------------------------------------------------- // auto emit( @@ -3841,6 +4013,7 @@ class cppfront && n.parameters ; + auto guard = stack_size_if(current_names, emit_parameters); if (emit_parameters) { printer.print_extra( "\n"); printer.print_extra( "{"); @@ -3968,6 +4141,8 @@ class cppfront } } + current_names.push_back(&*n.declaration); + //----------------------------------------------------------------------- // Skip 'this' parameters @@ -4252,6 +4427,7 @@ class cppfront && n.declaration->initializer ) { + auto guard = stack_element(current_declarations, &*n.declaration); printer.print_cpp2( " = ", n.declaration->initializer->position() ); emit(*n.declaration->initializer); } @@ -5135,6 +5311,11 @@ class cppfront printer.print_extra("\n"); } + auto guard0 = stack_value(having_signature_emitted, &n); + auto guard1 = stack_element(current_declarations, &n); + current_names.push_back(&n); + auto guard2 = stack_size_if(current_names, n.is_function()); + // Handle aliases if (n.is_alias()) @@ -5332,8 +5513,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 @@ -5769,7 +5948,9 @@ class cppfront func.get(), n.find_parent_declared_value_set_functions() ); - auto guard = finally([&]{ current_functions.pop(); }); + auto guard0 = finally([&]{ current_functions.pop(); }); + + auto guard1 = stack_size(current_names); // If this is at expression scope, we can't emit "[[nodiscard]] auto name" // so print the provided intro instead, which will be a Cpp1 lambda-introducer @@ -6146,6 +6327,7 @@ class cppfront { auto print = std::string(); printer.emit_to_string(&print); + auto guard = stack_value(having_signature_emitted, nullptr); emit(*c); printer.emit_to_string(); current_functions.back().prolog.statements.push_back(print); @@ -6155,6 +6337,7 @@ class cppfront emit_requires_clause(); + having_signature_emitted = nullptr; emit( *n.initializer, true, func->position(), func->returns.index() == function_type_node::empty,