@@ -818,60 +818,124 @@ $(GNAME TemplateSequenceParameter):
818
818
819
819
$(P If the last template parameter in the $(I TemplateParameterList)
820
820
is declared as a $(I TemplateSequenceParameter),
821
- it is a match with any trailing template arguments.
822
- Such a sequence of arguments can be defined using the template
823
- $(REF AliasSeq, std,meta) and will thus henceforth
821
+ it is a match with zero or more trailing template arguments.
822
+ Any argument that can be passed to a $(GLINK TemplateAliasParameter)
823
+ can be passed to a sequence parameter.
824
+ )
825
+ $(P Such a sequence of arguments can itself be aliased for use outside
826
+ a template. The $(REF AliasSeq, std,meta) template simply
827
+ aliases its sequence parameter:)
828
+ ---
829
+ alias AliasSeq(Args...) = Args;
830
+ ---
831
+ $(P A *TemplateSequenceParameter* will thus henceforth
824
832
be referred to by that name for clarity.
825
- An $(I AliasSeq) is not itself a type, value, or symbol.
826
- It is a compile-time sequence of any mix of types, values or symbols.
833
+ An $(I AliasSeq) is not itself a type, value, or symbol. It is a
834
+ $(DDLINK articles/ctarguments, Compile-time Sequences, compile-time sequence)
835
+ of any mix of types, values or symbols, or none.
827
836
)
828
-
829
- $(P An $(I AliasSeq) whose elements consist entirely of types is
830
- called a type sequence or $(I TypeSeq).
831
- An $(I AliasSeq) whose elements consist entirely of values is
832
- called a value sequence or $(I ValueSeq).
837
+ $(UL
838
+ $(LI An $(I AliasSeq) whose elements consist entirely of types is
839
+ called a type sequence or $(I TypeSeq).)
840
+ $(LI An $(I AliasSeq) whose elements consist entirely of values is
841
+ called a value sequence or $(I ValueSeq).)
842
+ $(LI `typeof` can be used on a *ValueSeq* to obtain a *TypeSeq*.)
833
843
)
834
844
835
- $(P An $(I AliasSeq) can be used as an argument list to instantiate
836
- another template, or as the list of parameters for a function.)
845
+ $(P The elements of an $(I AliasSeq) are automatically expanded
846
+ when it is referenced in a declaration or expression.
847
+ An $(I AliasSeq) can be used as arguments to instantiate a
848
+ template. A *ValueSeq* can be used as arguments to call a
849
+ function:)
837
850
838
851
$(SPEC_RUNNABLE_EXAMPLE_RUN
839
852
---
840
- import std.stdio;
853
+ import std.stdio : writeln ;
841
854
842
- template print(args...)
855
+ template print(args...) // args must be a ValueSeq
843
856
{
844
857
void f()
845
858
{
846
- writeln("args are ", args); // args is a ValueSeq
859
+ writeln("args are ", args);
847
860
}
848
861
}
849
862
850
- template write(Args...) // Args is a TypeSeq
863
+ void main()
864
+ {
865
+ print!(1,'a',6.8).f(); // prints: args are 1a6.8
866
+ }
867
+ ---
868
+ )
869
+
870
+ $(P A *TypeSeq* can be used to declare parameters for a function:)
871
+
872
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
873
+ ---
874
+ import std.stdio : writeln;
875
+
876
+ template print(Types...) // Types must be a TypeSeq
851
877
{
852
- void f(Args args) // args is a ValueSeq
878
+ void f(Types args) // args is a ValueSeq
853
879
{
854
880
writeln("args are ", args);
855
881
}
856
882
}
857
883
858
884
void main()
859
885
{
860
- print!(1,'a',6.8).f(); // prints: args are 1a6.8
861
- write!(int, char, double).f(1, 'a', 6.8); // prints: args are 1a6.8
886
+ print!(int, char, double).f(1, 'a', 6.8); // prints: args are 1a6.8
862
887
}
863
888
---
864
889
)
865
890
866
- $(P The number of elements in an $(I AliasSeq) can be retrieved with
867
- the $(D .length) property. The $(I n)th element can be retrieved
868
- by indexing the $(I AliasSeq) with [$(I n)],
869
- and sub-sequences are denoted by the slicing syntax.
891
+ $(P A *TypeSeq* can similarly be used to
892
+ $(DDSUBLINK articles/ctarguments, type-seq-instantiation, declare variables).
893
+ Parameters or variables declared with a *TypeSeq* are called an
894
+ *lvalue sequence*.)
895
+
896
+ $(H4 $(LNAME2 seq-ops, Sequence Operations))
897
+
898
+ $(UL
899
+ $(LI The number of elements in an $(I AliasSeq) can be retrieved with
900
+ the $(D .length) property.)
901
+ $(LI The $(I n)th element can be retrieved by
902
+ $(DDSUBLINK spec/expression, index_expressions, indexing) an
903
+ $(I AliasSeq) with `Seq[n]`. Indexes must be known at compile-time.
904
+ The result is an lvalue when the element is a variable.)
905
+ $(LI Sub-sequences can be obtained using
906
+ $(DDSUBLINK spec/expression, slice_expressions, slicing) syntax.)
907
+ )
908
+
909
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
910
+ ---
911
+ import std.meta : AliasSeq;
912
+
913
+ int v = 4;
914
+ alias nums = AliasSeq!(1, 2, 3, v);
915
+ static assert(nums.length == 4);
916
+ static assert(nums[1] == 2);
917
+
918
+ // nums[3] is bound to v, an lvalue
919
+ nums[3]++;
920
+ assert(v == 5);
921
+
922
+ // slice first 3 elements
923
+ alias trio = nums[0 .. $-1];
924
+ // expand into an array literal
925
+ static assert([trio] == [1, 2, 3]);
926
+ ---
870
927
)
871
928
872
- $(P $(I AliasSeq)- s are static compile-time entities, there is no way
929
+ $(P $(I AliasSeq)s are static compile-time entities, there is no way
873
930
to dynamically change, add, or remove elements either at compile-time or run-time.
931
+ Instead, either:)
932
+ $(UL
933
+ $(LI Construct a new sequence using the original sequence (or a slice of it) and additional elements before or after it.)
934
+ $(LI Use $(DDSUBLINK spec/declaration, AliasAssign, Alias Assignment)
935
+ to build a new sequence iteratively.)
874
936
)
937
+ $(P Sequences can 'unroll' code for each element using a
938
+ $(DDSUBLINK spec/statement, foreach_over_tuples, `foreach` statement).)
875
939
876
940
$(H4 $(LNAME2 typeseq_deduction, Type Sequence Deduction))
877
941
0 commit comments