Skip to content

Commit a7978cb

Browse files
committed
add AliasAssign to spec
1 parent e5bcad1 commit a7978cb

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

spec/declaration.dd

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ $(GNAME Declaration):
99
$(GLINK2 function, FuncDeclaration)
1010
$(GLINK VarDeclarations)
1111
$(GLINK AliasDeclaration)
12+
$(GLINK AliasAssign)
1213
$(GLINK2 struct, AggregateDeclaration)
1314
$(GLINK2 enum, EnumDeclaration)
1415
$(GLINK2 module, ImportDeclaration)
@@ -502,6 +503,75 @@ a = 2; // sets `S.i` to `2`
502503
b = 4; // sets `S.j` to `4`
503504
-----------
504505

506+
$(H2 $(LNAME2 AliasAssign, Alias Assign))
507+
508+
$(GRAMMAR
509+
$(GNAME AliasAssign):
510+
$(I Identifier) $(D =) $(GLINK Type)
511+
)
512+
513+
$(P An $(GLINK AliasDeclaration) can have a new value assigned to it with an
514+
$(I AliasAssign):)
515+
516+
---
517+
template Gorgon(T)
518+
{
519+
alias A = long;
520+
A = T; // assign new value to A
521+
alias Gorgon = A;
522+
}
523+
pragma(msg, Gorgon!int); // prints int
524+
---
525+
526+
$(UL
527+
$(LI The $(I AliasAssign) and its corresponding $(I AliasDeclaration) must both be
528+
declared in the same $(GLINK2 template, TemplateDeclaration).)
529+
530+
$(LI The corresponding $(I AliasDeclaration) must appear lexically before the
531+
$(I AliasAssign).)
532+
533+
$(LI The corresponding $(I AliasDeclaration) may not refer to overloaded symbols.)
534+
535+
$(LI The value of an $(I AliasDeclaration) or left hand side (lvalue) of an $(I AliasAssign) may not be used prior
536+
to another $(I AliasAssign) to the same lvalue other than in the right hand side of that $(I AliasAssign).)
537+
538+
)
539+
540+
$(BEST_PRACTICE
541+
$(I AliasAssign) is particularly useful when using an iterative
542+
computation rather than a recursive one, as it avoids creating
543+
the large number of intermediate templates that the recursive one
544+
engenders.
545+
---
546+
template AliasSeq(T...) { alias AliasSeq = T; }
547+
548+
static if (0) // recursive method for comparison
549+
{
550+
template Reverse(T...)
551+
{
552+
static if (T.length == 0)
553+
alias Reverse = AliasSeq!();
554+
else
555+
alias Reverse = AliasSeq!(Reverse!(T[1 .. T.length]), T[0]);
556+
}
557+
}
558+
else // iterative method minimizes template instantiations
559+
{
560+
template Reverse(T...)
561+
{
562+
alias A = AliasSeq!();
563+
static foreach (t; T)
564+
A = AliasSeq!(t, A); // Alias Assign
565+
alias Reverse = A;
566+
}
567+
}
568+
569+
enum X = 3;
570+
alias TK = Reverse!(int, const uint, X);
571+
pragma(msg, TK); // prints tuple(3, (const(uint)), (int))
572+
---
573+
)
574+
505575
$(H2 $(LNAME2 extern, Extern Declarations))
506576

507577
$(P Variable declarations with the storage class $(D extern) are not allocated

0 commit comments

Comments
 (0)