1 module mocked.meta;
2 
3 import std.format : format;
4 import std.meta;
5 import std.typecons;
6 
7 /**
8  * $(D_PSYMBOL Maybe) optionally saves a tuple of values. The values can't be
9  * set individually, but only at once.
10  */
11 struct Maybe(Arguments...)
12 {
13     private Nullable!(Tuple!Arguments) arguments_;
14 
15     /// Tuple length.
16     public enum size_t length = Arguments.length;
17 
18     /**
19      * Params:
20      *     arguments = Values to be assigned.
21      */
22     public void opAssign(Arguments arguments)
23     {
24         this.arguments_ = tuple!Arguments(arguments);
25     }
26 
27     /**
28      * Returns: $(D_KEYWORD true) if the tuple is set, $(D_KEYWORD false)
29      * otherwise.
30      */
31     public @property bool isNull()
32     {
33         return this.arguments_.isNull;
34     }
35 
36     /**
37      * Params:
38      *     n = Value position in the tuple.
39      *
40      * Returns: nth value in the tuple.
41      */
42     public @property ref Arguments[n] get(size_t n)()
43     if (n < Arguments.length)
44     in (!this.isNull())
45     {
46         return this.arguments_.get[n];
47     }
48 }
49 
50 /**
51  * Takes a sequence of strings and joins them with separating spaces.
52  *
53  * Params:
54  *     Args = Strings.
55  *
56  * Returns: Concatenated string.
57  */
58 template unwords(Args...)
59 {
60     static if (Args.length == 0)
61     {
62         enum string unwords = "";
63     }
64     else static if (Args.length == 1)
65     {
66         enum string unwords = Args[0];
67     }
68     else
69     {
70         enum string unwords = format!"%s %s"(Args[0], unwords!(Args[1..$]));
71     }
72 }
73 
74 /**
75  * Holds a typed sequence of template parameters.
76  *
77  * Params:
78  *     Args = Elements of this $(D_PSYMBOL Pack).
79  */
80 struct Pack(Args...)
81 {
82     /// Elements in this tuple as $(D_PSYMBOL AliasSeq).
83     alias Seq = Args;
84 
85     /// The length of the tuple.
86     enum size_t length = Args.length;
87 
88     alias Seq this;
89 }
90 
91 /**
92  * Params:
93  *     T = Some type.
94  *
95  * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a class or interface,
96  * $(D_KEYWORD false) otherwise.
97  */
98 enum bool isPolymorphicType(T) = is(T == class) || is(T == interface);
99 
100 enum bool canFind(alias T, Args...) = staticIndexOf!(T, Args) != -1;