| %module cpp23_explicit_object_parameter | |
| // C++23 explicit object parameters ("deducing this"). A member function can declare its first | |
| // parameter with the 'this' specifier, naming the object the function is called on. That parameter | |
| // is not one of the function's arguments, so the wrapped method takes only the parameters declared | |
| // after it - the object is passed the same way it is for an ordinary member function. | |
| // A lambda can have an explicit object parameter too, but a lambda is wrapped as an opaque object. | |
| %warnfilter(SWIGWARN_CPP11_LAMBDA) recurse; | |
| // An rvalue reference to the class can only be called on an rvalue, so it is ignored as the | |
| // equivalent 'void method() &&' spelling of it is. | |
| %warnfilter(SWIGWARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED) Counter::by_rvalue_ref; | |
| %warnfilter(SWIGWARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED) Counter::by_rvalue_ref_defarg; | |
| %inline %{ | |
| struct Counter { | |
| int value; | |
| Counter() : value(10) {} | |
| // Explicit object parameter by lvalue reference. | |
| int by_lvalue_ref(this Counter &self) { return self.value + 1; } | |
| // Explicit object parameter by const lvalue reference. | |
| int by_const_ref(this const Counter &self) { return self.value + 2; } | |
| // Explicit object parameter by value. | |
| int by_value(this Counter self) { return self.value + 3; } | |
| // Deduced explicit object parameter. This is a function template in C++, but the object type is | |
| // deduced from the object the wrapper passes, so it wraps as an ordinary member function. | |
| int deduced(this auto &&self) { return self.value + 4; } | |
| // Deduced explicit object parameter with a trailing return type. | |
| auto deduced_trailing(this auto &&self) -> int { return self.value + 5; } | |
| // An rvalue reference to the class, which binds no lvalue and so is ignored. The deduced forms | |
| // above are forwarding references rather than rvalue references and are wrapped as usual. | |
| int by_rvalue_ref(this Counter &&self) { return self.value + 6; } | |
| // The overload added for the default argument is ignored too. | |
| int by_rvalue_ref_defarg(this Counter &&self, int a = 6) { return self.value + a; } | |
| // Ordinary parameters follow the explicit object parameter and are the only arguments wrapped. | |
| int add(this Counter &self, int a, int b) { return self.value + a + b; } | |
| // Declaration and out of class definition. | |
| int declared_only(this Counter &self); | |
| // An ordinary member function and a static member function declared after a member function with | |
| // an explicit object parameter are unaffected by it. | |
| int implicit_object() const { return value + 8; } | |
| static int no_object() { return 9; } | |
| }; | |
| inline int Counter::declared_only(this Counter &self) { return self.value + 7; } | |
| // A member function returning a pointer, so that the declarator is not the simplest form. | |
| struct Chain { | |
| int value; | |
| Chain() : value(20) {} | |
| Chain *self_ptr(this Chain &self) { return &self; } | |
| }; | |
| // A lambda with an explicit object parameter, the usual way of writing a recursive lambda. | |
| auto recurse = [](this auto&& self, int n) -> int { return n <= 1 ? 1 : n * self(n - 1); }; | |
| %} |