@@ -830,60 +830,124 @@ $(GNAME TemplateSequenceParameter):
830
830
831
831
$(P If the last template parameter in the $(I TemplateParameterList)
832
832
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
836
844
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.
839
848
)
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*.)
845
855
)
846
856
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:)
849
862
850
863
$(SPEC_RUNNABLE_EXAMPLE_RUN
851
864
---
852
- import std.stdio;
865
+ import std.stdio : writeln ;
853
866
854
- template print(args...)
867
+ template print(args...) // args must be a ValueSeq
855
868
{
856
869
void f()
857
870
{
858
- writeln("args are ", args); // args is a ValueSeq
871
+ writeln("args are ", args);
859
872
}
860
873
}
861
874
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
863
889
{
864
- void f(Args args) // args is a ValueSeq
890
+ void f(Types args) // args is a ValueSeq
865
891
{
866
892
writeln("args are ", args);
867
893
}
868
894
}
869
895
870
896
void main()
871
897
{
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
874
899
}
875
900
---
876
901
)
877
902
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
+ ---
882
939
)
883
940
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
885
942
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.)
886
948
)
949
+ $(P Sequences can 'unroll' code for each element using a
950
+ $(DDSUBLINK spec/statement, foreach_over_tuples, `foreach` statement).)
887
951
888
952
$(H4 $(LNAME2 typeseq_deduction, Type Sequence Deduction))
889
953
0 commit comments