File tree Expand file tree Collapse file tree 4 files changed +206
-1
lines changed
Expand file tree Collapse file tree 4 files changed +206
-1
lines changed Original file line number Diff line number Diff line change @@ -718,6 +718,17 @@ def _parse_template_specialization(self) -> TemplateSpecialization:
718718 if dtype :
719719 args .append (TemplateArgument (dtype , param_pack ))
720720 else :
721+ # special case for sizeof...(thing)
722+ if (
723+ param_pack
724+ and len (val .tokens ) == 1
725+ and val .tokens [0 ].value == "sizeof"
726+ ):
727+ val .tokens .append (Token ("..." , "ELLIPSIS" ))
728+ tok = self ._next_token_must_be ("(" )
729+ raw_toks = self ._consume_balanced_tokens (tok )
730+ val .tokens .extend (Token (tok .value , tok .type ) for tok in raw_toks )
731+
721732 args .append (TemplateArgument (val , param_pack ))
722733
723734 tok = self ._next_token_must_be ("," , ">" )
@@ -2624,6 +2635,16 @@ def _parse_declarations(
26242635 ):
26252636 return
26262637
2638+ # Check for an abbreviated template return type, promote it
2639+ if not is_typedef and parsed_type is not None and self .lex .token_if_val ("auto" ):
2640+ abv_ret_tmpl = TemplateNonTypeParam (type = parsed_type , param_idx = - 1 )
2641+ if template is None :
2642+ template = TemplateDecl (params = [abv_ret_tmpl ])
2643+ elif isinstance (template , TemplateDecl ):
2644+ template .params .append (abv_ret_tmpl )
2645+ else :
2646+ template [- 1 ].params .append (abv_ret_tmpl )
2647+
26272648 var_ok = True
26282649
26292650 if is_typedef :
Original file line number Diff line number Diff line change @@ -458,13 +458,18 @@ class TemplateNonTypeParam:
458458 // abbreviated template parameters are converted to this and param_idx is set
459459 void fn(C auto p)
460460 ~~~~~~
461+
462+ // abbreviated template parameters that are return types have param_idx = -1
463+ C auto fn()
464+ ~~~~~~
461465 """
462466
463467 type : DecoratedType
464468 name : typing .Optional [str ] = None
465469 default : typing .Optional [Value ] = None
466470
467- #: If this was promoted, the parameter index that this corresponds with
471+ #: If this was promoted, the parameter index that this corresponds with. Return
472+ #: types are set to -1
468473 param_idx : typing .Optional [int ] = None
469474
470475 #: Contains a ``...``
Original file line number Diff line number Diff line change @@ -351,3 +351,77 @@ def test_abv_template_f5() -> None:
351351 ]
352352 )
353353 )
354+
355+
356+ def test_returned_abv_template () -> None :
357+ content = """
358+ constexpr std::signed_integral auto FloorDiv(std::signed_integral auto x,
359+ std::signed_integral auto y);
360+ """
361+ data = parse_string (content , cleandoc = True )
362+
363+ assert data == ParsedData (
364+ namespace = NamespaceScope (
365+ functions = [
366+ Function (
367+ return_type = Type (
368+ typename = PQName (
369+ segments = [
370+ NameSpecifier (name = "std" ),
371+ NameSpecifier (name = "signed_integral" ),
372+ ]
373+ )
374+ ),
375+ name = PQName (segments = [NameSpecifier (name = "FloorDiv" )]),
376+ parameters = [
377+ Parameter (
378+ type = Type (typename = PQName (segments = [AutoSpecifier ()])),
379+ name = "x" ,
380+ ),
381+ Parameter (
382+ type = Type (typename = PQName (segments = [AutoSpecifier ()])),
383+ name = "y" ,
384+ ),
385+ ],
386+ constexpr = True ,
387+ template = TemplateDecl (
388+ params = [
389+ TemplateNonTypeParam (
390+ type = Type (
391+ typename = PQName (
392+ segments = [
393+ NameSpecifier (name = "std" ),
394+ NameSpecifier (name = "signed_integral" ),
395+ ]
396+ )
397+ ),
398+ param_idx = - 1 ,
399+ ),
400+ TemplateNonTypeParam (
401+ type = Type (
402+ typename = PQName (
403+ segments = [
404+ NameSpecifier (name = "std" ),
405+ NameSpecifier (name = "signed_integral" ),
406+ ]
407+ )
408+ ),
409+ param_idx = 0 ,
410+ ),
411+ TemplateNonTypeParam (
412+ type = Type (
413+ typename = PQName (
414+ segments = [
415+ NameSpecifier (name = "std" ),
416+ NameSpecifier (name = "signed_integral" ),
417+ ]
418+ )
419+ ),
420+ param_idx = 1 ,
421+ ),
422+ ]
423+ ),
424+ )
425+ ]
426+ )
427+ )
Original file line number Diff line number Diff line change @@ -2247,3 +2247,108 @@ def test_template_deduction_guide() -> None:
22472247 ]
22482248 )
22492249 )
2250+
2251+
2252+ def test_sizeof_pack () -> None :
2253+ content = """
2254+ template <std::same_as<int>... OutputIndices>
2255+ LinearSystem<States, Inputs, sizeof...(OutputIndices)> Slice(OutputIndices... outputIndices);
2256+ """
2257+ data = parse_string (content , cleandoc = True )
2258+
2259+ assert data == ParsedData (
2260+ namespace = NamespaceScope (
2261+ functions = [
2262+ Function (
2263+ return_type = Type (
2264+ typename = PQName (
2265+ segments = [
2266+ NameSpecifier (
2267+ name = "LinearSystem" ,
2268+ specialization = TemplateSpecialization (
2269+ args = [
2270+ TemplateArgument (
2271+ arg = Type (
2272+ typename = PQName (
2273+ segments = [
2274+ NameSpecifier (name = "States" )
2275+ ]
2276+ )
2277+ )
2278+ ),
2279+ TemplateArgument (
2280+ arg = Type (
2281+ typename = PQName (
2282+ segments = [
2283+ NameSpecifier (name = "Inputs" )
2284+ ]
2285+ )
2286+ )
2287+ ),
2288+ TemplateArgument (
2289+ arg = Value (
2290+ tokens = [
2291+ Token (value = "sizeof" ),
2292+ Token (value = "..." ),
2293+ Token (value = "(" ),
2294+ Token (value = "OutputIndices" ),
2295+ Token (value = ")" ),
2296+ ]
2297+ ),
2298+ param_pack = True ,
2299+ ),
2300+ ]
2301+ ),
2302+ )
2303+ ]
2304+ )
2305+ ),
2306+ name = PQName (segments = [NameSpecifier (name = "Slice" )]),
2307+ parameters = [
2308+ Parameter (
2309+ type = Type (
2310+ typename = PQName (
2311+ segments = [NameSpecifier (name = "OutputIndices" )]
2312+ )
2313+ ),
2314+ name = "outputIndices" ,
2315+ param_pack = True ,
2316+ )
2317+ ],
2318+ template = TemplateDecl (
2319+ params = [
2320+ TemplateNonTypeParam (
2321+ type = Type (
2322+ typename = PQName (
2323+ segments = [
2324+ NameSpecifier (name = "std" ),
2325+ NameSpecifier (
2326+ name = "same_as" ,
2327+ specialization = TemplateSpecialization (
2328+ args = [
2329+ TemplateArgument (
2330+ arg = Type (
2331+ typename = PQName (
2332+ segments = [
2333+ FundamentalSpecifier (
2334+ name = "int"
2335+ )
2336+ ]
2337+ )
2338+ )
2339+ )
2340+ ]
2341+ ),
2342+ ),
2343+ ]
2344+ )
2345+ ),
2346+ name = "OutputIndices" ,
2347+ param_pack = True ,
2348+ )
2349+ ]
2350+ ),
2351+ )
2352+ ]
2353+ )
2354+ )
You can’t perform that action at this time.
0 commit comments