@@ -414,6 +414,34 @@ namespace deduction_substitution_failure {
414414 int bi = B<char , char >; // expected-note {{during template argument deduction for variable template partial specialization 'B<T, typename Fail<T>::error>' [with T = char]}}
415415}
416416
417+ namespace deduce_pack_from_argument {
418+ template <typename ... T>
419+ void separator (args_tag<T...>, T..., int , T...) {}
420+ template <typename ... T>
421+ void separator_dependent (args_tag<T...>, type_identity_t <T>..., int , type_identity_t <T>...) {}
422+ template <typename ... Y, typename ... T>
423+ void separator_multiple_parameters (args_tag<Y...>, args_tag<T...>, type_identity_t <T>..., int mid, type_identity_t <T>...) {}
424+
425+ void test_separator () {
426+ separator (args_tag<int , int >{}, 4 , 8 , 42 , 16 , 25 );
427+ separator (args_tag<>{}, 42 );
428+ separator_dependent (args_tag<int , int >{}, 4 , 8 , 42 , 16 , 25 );
429+ separator_dependent (args_tag<>{}, 42 );
430+ separator_multiple_parameters (args_tag<const int , const int >{}, args_tag<int , int >{}, 8 , 9 , 15 , 16 , 23 );
431+ }
432+
433+ template <typename ... Y, typename ... T> void no_separator (args_tag<T...>, T..., T...) {}
434+ template <typename ... Y, typename ... T>
435+ void no_separator_dependent (args_tag<Y...>, args_tag<T...>, type_identity_t <T>..., type_identity_t <T>...) {}
436+
437+ void test_no_separator () {
438+ no_separator (args_tag<int , int >{}, 1 , 2 , 3 , 4 );
439+ no_separator (args_tag<>{});
440+ no_separator_dependent (args_tag<const int , const int >{}, args_tag<int , int >{}, 8 , 9 , 15 , 16 );
441+ no_separator_dependent (args_tag<>{}, args_tag<>{});
442+ }
443+ }
444+
417445namespace deduction_after_explicit_pack {
418446 template <typename ...T, typename U> int *f (T ...t, int &r, U *u) {
419447 return u;
@@ -442,29 +470,6 @@ namespace deduction_after_explicit_pack {
442470 i<int , int >(0 , 1 , 2 , 3 , 4 , 5 ); // expected-error {{no match}}
443471 }
444472
445- template <typename ... T>
446- void bar (args_tag<T...>, type_identity_t <T>..., int mid, type_identity_t <T>...) {}
447- void call_bar () {
448- bar (args_tag<int , int >{}, 4 , 8 , 1001 , 16 , 23 );
449- }
450-
451- template <typename ... Y, typename ... T>
452- void foo (args_tag<Y...>, args_tag<T...>, type_identity_t <T>..., int mid, type_identity_t <T>...) {}
453- void call_foo () {
454- foo (args_tag<const int ,const int , const int >{}, args_tag<int , int , int >{}, 4 , 8 , 9 , 15 , 16 , 23 , 1 );
455- }
456-
457- template <typename ... Y, typename ... T>
458- void foo2 (args_tag<Y...>, args_tag<T...>, type_identity_t <T>..., type_identity_t <T>...) {}
459- void call_foo2 () {
460- foo2 (args_tag<const int ,const int , const int >{}, args_tag<int , int , int >{}, 4 , 8 , 9 , 15 , 16 , 23 );
461- }
462-
463- template <typename ... Y, typename ... T> void baz (args_tag<T...>, T..., T...) {}
464- void call_baz () {
465- baz (args_tag<int , int >{}, 1 , 2 , 3 , 4 );
466- }
467-
468473 // GCC alarmingly accepts this by deducing T={int} by matching the second
469474 // parameter against the first argument, then passing the first argument
470475 // through the first parameter.
0 commit comments