Skip to content

Commit

Permalink
C++23 deducing this
Browse files Browse the repository at this point in the history
  • Loading branch information
guwirth committed Aug 28, 2024
1 parent 41ab59e commit c60c634
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 10 deletions.
6 changes: 0 additions & 6 deletions cxx-squid/dox/diff-cpp20-cpp23_grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,6 @@ elaborated-type-specifier:
class-key nested-name-specifier templateopt simple-template-id
enum nested-name-specifieropt identifier

parameter-declaration:
attribute-specifier-seqopt thisopt decl-specifier-seq declarator
attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
attribute-specifier-seqopt thisopt decl-specifier-seq abstract-declaratoropt
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt = initializer-clause

using-enum-declaration:
using enum using-enum-declarator ;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1428,10 +1428,10 @@ private static void declarations(LexerfulGrammarBuilder b) {
// sample: template<bool x=false> string f();
b.sequence(b.optional(attributeSpecifierSeq), parameterDeclSpecifierSeq, declarator,
"=", LITERAL), // syntax sugar
b.sequence(b.optional(attributeSpecifierSeq), b.optional(vcAtlAttribute), parameterDeclSpecifierSeq, declarator,
b.optional("=", initializerClause)), // C++
b.sequence(b.optional(attributeSpecifierSeq), parameterDeclSpecifierSeq, b.optional(abstractDeclarator),
b.optional("=", initializerClause))) // C++
b.sequence(b.optional(attributeSpecifierSeq), b.optional(CxxKeyword.THIS), b.optional(vcAtlAttribute),
parameterDeclSpecifierSeq, declarator, b.optional("=", initializerClause)), // C++
b.sequence(b.optional(attributeSpecifierSeq), b.optional(CxxKeyword.THIS), parameterDeclSpecifierSeq,
b.optional(abstractDeclarator), b.optional("=", initializerClause))) // C++
);

b.rule(parameterDeclSpecifierSeq).is( // is decl-specifier-seq
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,12 +410,18 @@ void parameterDeclaration() {

assertThatParser()
.matches("parameterDeclSpecifierSeq declarator")
.matches("this parameterDeclSpecifierSeq declarator")
.matches("attributeSpecifierSeq parameterDeclSpecifierSeq declarator")
.matches("attributeSpecifierSeq this parameterDeclSpecifierSeq declarator")
.matches("parameterDeclSpecifierSeq declarator = initializerClause")
.matches("attributeSpecifierSeq parameterDeclSpecifierSeq declarator = initializerClause")
.matches("parameterDeclSpecifierSeq")
.matches("this parameterDeclSpecifierSeq")
.matches("attributeSpecifierSeq this parameterDeclSpecifierSeq")
.matches("parameterDeclSpecifierSeq abstractDeclarator")
.matches("this parameterDeclSpecifierSeq abstractDeclarator")
.matches("attributeSpecifierSeq parameterDeclSpecifierSeq abstractDeclarator")
.matches("attributeSpecifierSeq this parameterDeclSpecifierSeq abstractDeclarator")
.matches("parameterDeclSpecifierSeq = initializerClause")
.matches("parameterDeclSpecifierSeq abstractDeclarator = initializerClause")
.matches("attributeSpecifierSeq parameterDeclSpecifierSeq abstractDeclarator = initializerClause");
Expand All @@ -433,6 +439,9 @@ void parameterDeclaration_reallife() {
.matches("string")
.matches("::P& c")
.matches("bool (A::*bar)(void)")
// C++23
.matches("this Self&& self")
.matches("this Y const&")
// CLI extension
.matches("const int^ i")
.matches("const int% i")
Expand Down
33 changes: 33 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++23/deducing-this.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
struct X {
void foo(this X const& self, int i); // same as void foo(int i) const &;
// void foo(int i) const &; // Error: already declared
void bar(this X self, int i); // pass object by value: makes a copy of “*this”
};

struct Y {
template<typename Self>
void foo(this Self&&, int);
};

struct D : Y {};

void ex(Y& y, D& d)
{
y.foo(1); // Self = Y&
move(x).foo(2); // Self = Y
d.foo(3); // Self = D&
}

// a CRTP trait
struct add_postfix_increment {
template<typename Self>
auto operator++(this Self&& self, int) {
auto tmp = self; // Self deduces to "some_type"
++self;
return tmp;
}
};

struct some_type : add_postfix_increment {
some_type& operator++() { /*...*/ }
};

0 comments on commit c60c634

Please sign in to comment.