%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); };
%}
