Commit Graph

4 Commits

Author SHA1 Message Date
William S Fulton ef00c8af06 C++20: avoid 'Numeric auto' with trailing return type in abbreviated_template test
clang and MSVC reject a return type-constraint combined with a trailing return type.
The constrained-return form is now covered separately via the new half_numeric.
2026-05-14 01:27:45 +01:00
William S Fulton 81406ae5f6 C++20: parse abbreviated function templates with constrained auto return type
Three new grammar rules in 'cpp_declaration' parallel the existing
'storage_class AUTO declarator cpp_const ...' alternatives, accepting
a leading 'idcolon' before AUTO so a constrained auto return type
('Numeric auto fn(...)') parses.  Each new rule mirrors the action of
its plain AUTO counterpart and additionally attaches the captured
concept-id as a 'concept-id' atom on the cdecl's 'constraint' attribute:

  Numeric auto half(int x) -> int { return x / 2; }                    // wrappable
  Numeric auto cube_constrained(Sized auto x) -> int { return x*x*x; } // wrappable
  Numeric auto times2(int x) { return x * 2; }                         // ignored with warning
  Numeric auto times3(int x);                                          // ignored with warning

When a trailing return type is present SWIG wraps the function using
that type and the constraint is metadata only; without one the
function inherits plain 'auto fn(...)' behaviour and is ignored with
a warning since SWIG cannot deduce the return type.

As a side fix, the existing 'storage_class AUTO declarator cpp_const
ARROW ...' rule now also calls promote_abbreviated_template, so a
constrained auto parameter combined with an explicit trailing return
('auto fn(Concept auto x) -> int') introduces an invented type
template parameter for the auto parameter and instantiates correctly
via %template (previously: 'X is not defined as a template' error).

cpp20_abbreviated_template.i (and matching Python/Java runmes) gain
'half', 'cube_constrained', 'twice_n_arrow', 'times2' and 'times3'
cases covering all five forms from the constrained auto return type
matrix; the two ignored with warning declarations are silenced via per name
%warnfilter(SWIGWARN_CPP14_AUTO).

Assisted-by: Claude Code (Opus 4.7)
2026-05-12 23:04:20 +01:00
William S Fulton 0039cb9206 C++20: parse abbreviated function templates with constrained auto
A type constrained 'auto' parameter (e.g. 'Numeric auto') is now
accepted in parameter type position - via a new
'idcolon AUTO parameter_declarator' alternative in parm_no_dox.  The
invented type template parameter generated for each such auto parm
carries the type-constraint as a 'concept-id' constraint atom on its
'constraint' attribute, matching the requires-clause infrastructure
already used by explicit templates.

  int twice_numeric(Numeric auto x) { return x + x; }
  %template(twice_numeric_int) twice_numeric<int>;

Each constrained auto parm gets its own invented type template parameter
and constraint, so multi parm forms work too:

  double scale_mixed(Numeric auto x, Numeric auto factor);
  int add_same_concept(Sized auto a, Sized auto b);

cpp20_concepts_lambda.i picks up the constrained auto lambda case
('[](Numeric auto x){}') that previously failed to parse.

Assisted-by: Claude Code (Opus 4.7)
2026-05-12 23:04:20 +01:00
William S Fulton 0d88926e79 C++14/20: parse auto parameters in functions and lambdas
Adds an AUTO parameter_declarator alternative to parm_no_dox.  Placing
the new alternative in parm_no_dox rather than type_right scopes the
'auto' keyword to parameter context only, so it does not clash with
the dedicated 'storage_class AUTO declarator ...' rules at top level
and the existing %expect 7 conflict count is unchanged.

Functions whose parms include 'auto' are converted to a function
template - one invented type template parameter (named
"__dummy_auto_<N>__") per auto parm - via promote_abbreviated_template()
called from c_decl, so abbreviated function templates wrap through the
existing %template instantiation machinery.

Lambdas (which already route through parms) get the same fix
transparently and parse without choking, matching the C++14 generic
lambda form.

The function must declare an explicit (non-auto) return type for SWIG
to wrap it. The C++14 auto return restriction, (cpp14_auto_return_type
testcase) still applies.

  // C++14 generic lambda
  auto twice = [](auto x) { return x + x; };

  // C++20 abbreviated function template
  int twice(auto x) { return x + x; }
  %template(twice_int) twice<int>;

Assisted-by: Claude Code (Opus 4.7)
2026-05-12 23:04:20 +01:00