Commit Graph

4 Commits

Author SHA1 Message Date
William S Fulton c6e9f82d07 Visual C++ warning fixes in testcases 2023-07-08 09:38:52 +01:00
William S Fulton 9924c5c3e1 Partial template specialization fixes to support default arguments
Default argments come from the primary template's parameter list.

Example:
  template<class Y, class T=int> struct X { void primary() {} };
  // Previously the specialization below resulted in:
  // Error: Inconsistent argument count in template partial specialization. 1 2
  template<class YY> struct X<YY*> { void special(YY*) {} };

  // Both of these correctly wrap the partially specialized template
  %template(StringPtr) X<const char *>;
  %template(ShortPtr) X<short *, int>;
2023-03-01 19:42:00 +00:00
William S Fulton 63bf998b30 Make new testcase c++98 compliant 2023-02-17 18:44:56 +00:00
William S Fulton 817c700ced Template partial specialization improvements
Closes #1300

Changes to support the first example below (partial specialization of
template parameter types like Vect<int>). Previous implementation and
design could only handle one template parameter name per template
specialization argument, such as Vect<TS> for the first template
specialization argument (for first example below)
  template<class TS, typename TTS> class Foo<Vect<TS>, int> { ... };
and not
  template<class TS, typename TTS> class Foo<Vect<TS, TTS>, int> { ... };
New approach is to not modify 'templateparms' in the template node,
(except to fill in default args from primary template)
Previous implementation also assumed a template parameter could not be
used more than once in the specialized arguments, such as
  template<typename T> struct Hey<T, T> { void specialA() {} };

Examples
========
1) For primary:
  template<class T, typename TT> class Foo { ... };
and specialization:
  template<class TS, typename TTS> class Foo<Vect<TS>, TTS> { ... };

Fix specialization template from (wrong)
| templateparms - 'Vect< TS >,typename TTS'
to (correct/new way)
| templateparms - 'class TS,typename TTS'

2) For primary:
  template<typename P1 = int, typename P2 = double> struct Partialler { void primary(P1, P2) {}; };
and specialization:
  template<typename S1, typename S2> struct Partialler<S2, S1*> { void special(S1*, S2, bool) {}; };

Specialized template changes from (wrong)
| templateparms - 'typename S2=int,typename S1=double'
to (correct/new way, default args are removed)
| templateparms - 'typename S1,typename S2'

and subsequent change to partialargs from
| partialargs  - "Partialler<($1,p.$2)>"
to
| partialargs  - "Partialler<($2,p.$1)>"
so that the $n number is now more logically the nth template parameter in templateparms

3) For primary:
  template<typename X, typename Y> struct Hey { void primary() {} };
and specialization:
  template<typename T> struct Hey<T, T> { void specialA() {} };

old (wrong/old way)
| templateparms - 'typename T,typename T'
new (correct/new way)
| templateparms - 'typename T'

These are unchanged and are okay:
| partialargs  - "Hey<($1,$1)>"

4) For primary:
  enum Hello { hi, hello };
  template <Hello, class A> struct C {};
and specialization:
  template <class A> struct C<hello,A> { ... };

old (wrong/old way)
| templateparms - 'hello,class A'
new (correct/new way)
| templateparms - 'class A'

and subsequent changes to partialargs from
| partialargs  - "C<(hi,$2)>"
to
| partialargs  - "C<(hi,$1)>"

Test-suite
==========
Identical output as before in Python but in Java, an unimportant change
in cpp11_variadic_function_templates.i results in one variadic parameter
name being different.

New testcase template_partial_specialization_more.i with more testcases
added including above examples that are not already in the test-suite.
2023-02-17 08:24:25 +00:00