Skip to content

Commit 13f0f1c

Browse files
authored
Merge pull request #3225 from ntrel/seq-param
[spec/template.dd] Improve TemplateSequenceParameter docs Signed-off-by: Dennis <[email protected]> Merged-on-behalf-of: Dennis <[email protected]>
2 parents 5eda82f + 330ed6c commit 13f0f1c

File tree

2 files changed

+92
-24
lines changed

2 files changed

+92
-24
lines changed

spec/template.dd

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -830,60 +830,124 @@ $(GNAME TemplateSequenceParameter):
830830

831831
$(P If the last template parameter in the $(I TemplateParameterList)
832832
is declared as a $(I TemplateSequenceParameter),
833-
it is a match with any trailing template arguments.
834-
Such a sequence of arguments can be defined using the template
835-
$(REF AliasSeq, std,meta) and will thus henceforth
833+
it is a match with zero or more trailing template arguments.
834+
Any argument that can be passed to a $(GLINK TemplateAliasParameter)
835+
can be passed to a sequence parameter.
836+
)
837+
$(P Such a sequence of arguments can itself be aliased for use outside
838+
a template. The $(REF AliasSeq, std,meta) template simply
839+
aliases its sequence parameter:)
840+
---
841+
alias AliasSeq(Args...) = Args;
842+
---
843+
$(P A *TemplateSequenceParameter* will thus henceforth
836844
be referred to by that name for clarity.
837-
An $(I AliasSeq) is not itself a type, value, or symbol.
838-
It is a compile-time sequence of any mix of types, values or symbols.
845+
An $(I AliasSeq) is not itself a type, value, or symbol. It is a
846+
$(DDLINK articles/ctarguments, Compile-time Sequences, compile-time sequence)
847+
of any mix of types, values or symbols, or none.
839848
)
840-
841-
$(P An $(I AliasSeq) whose elements consist entirely of types is
842-
called a type sequence or $(I TypeSeq).
843-
An $(I AliasSeq) whose elements consist entirely of values is
844-
called a value sequence or $(I ValueSeq).
849+
$(UL
850+
$(LI An $(I AliasSeq) whose elements consist entirely of types is
851+
called a type sequence or $(I TypeSeq).)
852+
$(LI An $(I AliasSeq) whose elements consist entirely of values is
853+
called a value sequence or $(I ValueSeq).)
854+
$(LI `typeof` can be used on a *ValueSeq* to obtain a *TypeSeq*.)
845855
)
846856

847-
$(P An $(I AliasSeq) can be used as an argument list to instantiate
848-
another template, or as the list of parameters for a function.)
857+
$(P The elements of an $(I AliasSeq) are automatically expanded
858+
when it is referenced in a declaration or expression.
859+
An $(I AliasSeq) can be used as arguments to instantiate a
860+
template. A *ValueSeq* can be used as arguments to call a
861+
function:)
849862

850863
$(SPEC_RUNNABLE_EXAMPLE_RUN
851864
---
852-
import std.stdio;
865+
import std.stdio : writeln;
853866

854-
template print(args...)
867+
template print(args...) // args must be a ValueSeq
855868
{
856869
void f()
857870
{
858-
writeln("args are ", args); // args is a ValueSeq
871+
writeln("args are ", args);
859872
}
860873
}
861874

862-
template write(Args...) // Args is a TypeSeq
875+
void main()
876+
{
877+
print!(1, 'a', 6.8).f(); // prints: args are 1a6.8
878+
}
879+
---
880+
)
881+
882+
$(P A *TypeSeq* can be used to declare parameters for a function:)
883+
884+
$(SPEC_RUNNABLE_EXAMPLE_RUN
885+
---
886+
import std.stdio : writeln;
887+
888+
template print(Types...) // Types must be a TypeSeq
863889
{
864-
void f(Args args) // args is a ValueSeq
890+
void f(Types args) // args is a ValueSeq
865891
{
866892
writeln("args are ", args);
867893
}
868894
}
869895

870896
void main()
871897
{
872-
print!(1,'a',6.8).f(); // prints: args are 1a6.8
873-
write!(int, char, double).f(1, 'a', 6.8); // prints: args are 1a6.8
898+
print!(int, char, double).f(1, 'a', 6.8); // prints: args are 1a6.8
874899
}
875900
---
876901
)
877902

878-
$(P The number of elements in an $(I AliasSeq) can be retrieved with
879-
the $(D .length) property. The $(I n)th element can be retrieved
880-
by indexing the $(I AliasSeq) with [$(I n)],
881-
and sub-sequences are denoted by the slicing syntax.
903+
$(P A *TypeSeq* can similarly be used to
904+
$(DDSUBLINK articles/ctarguments, type-seq-instantiation, declare variables).
905+
Parameters or variables declared with a *TypeSeq* are called an
906+
*lvalue sequence*.)
907+
908+
$(H4 $(LNAME2 seq-ops, Sequence Operations))
909+
910+
$(UL
911+
$(LI The number of elements in an $(I AliasSeq) can be retrieved with
912+
the $(D .length) property.)
913+
$(LI The $(I n)th element can be retrieved by
914+
$(DDSUBLINK spec/expression, index_expressions, indexing) an
915+
$(I AliasSeq) with `Seq[n]`. Indexes must be known at compile-time.
916+
The result is an lvalue when the element is a variable.)
917+
$(LI $(DDSUBLINK spec/expression, slice_expressions, Slicing)
918+
produces a new sequence with a subset of the elements of the original sequence.)
919+
)
920+
921+
$(SPEC_RUNNABLE_EXAMPLE_RUN
922+
---
923+
import std.meta : AliasSeq;
924+
925+
int v = 4;
926+
alias nums = AliasSeq!(1, 2, 3, v);
927+
static assert(nums.length == 4);
928+
static assert(nums[1] == 2);
929+
930+
// nums[3] is bound to v, an lvalue
931+
nums[3]++;
932+
assert(v == 5);
933+
934+
// slice first 3 elements
935+
alias trio = nums[0 .. $-1];
936+
// expand into an array literal
937+
static assert([trio] == [1, 2, 3]);
938+
---
882939
)
883940

884-
$(P $(I AliasSeq)-s are static compile-time entities, there is no way
941+
$(P $(I AliasSeq)s are static compile-time entities, there is no way
885942
to dynamically change, add, or remove elements either at compile-time or run-time.
943+
Instead, either:)
944+
$(UL
945+
$(LI Construct a new sequence using the original sequence (or a slice of it) and additional elements before or after it.)
946+
$(LI Use $(DDSUBLINK spec/declaration, AliasAssign, Alias Assignment)
947+
to build new sequences iteratively.)
886948
)
949+
$(P Sequences can 'unroll' code for each element using a
950+
$(DDSUBLINK spec/statement, foreach_over_tuples, `foreach` statement).)
887951

888952
$(H4 $(LNAME2 typeseq_deduction, Type Sequence Deduction))
889953

spec/type.dd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,10 @@ $(GNAME Typeof):
468468
}
469469
--------------------
470470

471+
$(P If *Expression* is a
472+
$(DDSUBLINK spec/template, variadic-templates, $(I ValueSeq))
473+
it will produce a *TypeSeq* containing the types of each element.)
474+
471475
$(P Special cases: )
472476
$(OL
473477
$(LI $(D typeof(this)) will generate the type of what $(D this)

0 commit comments

Comments
 (0)