From ba64eaab043d2449da787963c181e46bbd2b74be Mon Sep 17 00:00:00 2001 From: Andreas Fertig Date: Wed, 25 Jun 2025 17:47:42 +0200 Subject: [PATCH] Added support for P2662r3. --- CodeGenerator.cpp | 17 +++++++++++++ CodeGeneratorTypes.h | 1 + tests/p2662Test.cpp | 20 +++++++++++++++ tests/p2662Test.expect | 58 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 tests/p2662Test.cpp create mode 100644 tests/p2662Test.expect diff --git a/CodeGenerator.cpp b/CodeGenerator.cpp index b2e081c1..4ad899ef 100644 --- a/CodeGenerator.cpp +++ b/CodeGenerator.cpp @@ -2112,6 +2112,23 @@ void CodeGenerator::InsertArg(const CXXFoldExpr* stmt) } //----------------------------------------------------------------------------- +void CodeGenerator::InsertArg(const PackIndexingExpr* stmt) +{ + if(stmt->isFullySubstituted()) { + const auto* constExpr = dyn_cast_or_null(stmt->getIndexExpr()); + + mOutputFormatHelper.Append(BuildInternalVarName(GetName(*stmt->getPackDecl())), + constExpr->getAPValueResult().getInt()); + + } else { + mOutputFormatHelper.Append(GetName(*stmt->getPackDecl()), "...["); + + InsertArg(stmt->getIndexExpr()); + mOutputFormatHelper.Append("]"); + } +} +//----------------------------------------------------------------------------- + void CodeGenerator::InsertArg(const CXXInheritedCtorInitExpr* stmt) { const auto& constructorDecl = *stmt->getConstructor(); diff --git a/CodeGeneratorTypes.h b/CodeGeneratorTypes.h index 91299e82..9aa07225 100644 --- a/CodeGeneratorTypes.h +++ b/CodeGeneratorTypes.h @@ -136,6 +136,7 @@ SUPPORTED_STMT(SourceLocExpr) SUPPORTED_STMT(CXXParenListInitExpr) SUPPORTED_STMT(CppInsightsCommentStmt) SUPPORTED_STMT(CXXPseudoDestructorExpr) +SUPPORTED_STMT(PackIndexingExpr) #undef IGNORED_DECL #undef IGNORED_STMT diff --git a/tests/p2662Test.cpp b/tests/p2662Test.cpp new file mode 100644 index 00000000..3ca73191 --- /dev/null +++ b/tests/p2662Test.cpp @@ -0,0 +1,20 @@ +// cmdline:-std=c++26 + +template +constexpr auto first_plus_last(T... values) -> T...[0] +{ + return T...[0](values...[0] + values...[sizeof...(values) - 1]); +} + +// first_plus_last(); // ill formed +static_assert(first_plus_last(1, 2, 10) == 11); + +auto res = [](auto... pack) { + decltype(pack...[0]) x5; // type is int + decltype((pack...[0])) x6{x5}; // type is int& + + return 0; +}(0, 3.14, 'c'); + +int main() {} + diff --git a/tests/p2662Test.expect b/tests/p2662Test.expect new file mode 100644 index 00000000..d6255a23 --- /dev/null +++ b/tests/p2662Test.expect @@ -0,0 +1,58 @@ +template +inline constexpr T...[0] first_plus_last(T... values) +{ + return T...[0](values...[0] + values...[sizeof...(values) - 1]); +} + +/* First instantiated from: p2662Test.cpp:10 */ +#ifdef INSIGHTS_USE_TEMPLATE +template<> +inline constexpr int first_plus_last(int __values0, int __values1, int __values2) +{ + return int(__values0 + __values2); +} +#endif + + +/* PASSED: static_assert(first_plus_last(1, 2, 10) == 11); */ + + +class __lambda_12_12 +{ + public: + template + inline /*constexpr */ auto operator()(type_parameter_0_0... pack) const + { + decltype(pack...[0]) x5; + decltype((pack...[0])) x6 = {x5}; + return 0; + } + + #ifdef INSIGHTS_USE_TEMPLATE + template<> + inline /*constexpr */ int operator()(int __pack0, double __pack1, char __pack2) const + { + int x5; + int & x6 = {x5}; + return 0; + } + #endif + + private: + template + static inline /*constexpr */ auto __invoke(type_parameter_0_0... pack) + { + return __lambda_12_12{}.operator()(pack...); + } + + public: + // /*constexpr */ __lambda_12_12() = default; + +} __lambda_12_12{}; + +int res = __lambda_12_12.operator()(0, 3.1400000000000001, 'c'); + +int main() +{ + return 0; +}