1 module mocked.meta; 2 3 import std.algorithm; 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 Tuple!Types arguments_ = void; 14 15 private bool isNull_ = true; 16 17 /// Tuple length. 18 public enum size_t length = Arguments.length; 19 20 /// Tuple types. 21 public alias Types = Arguments; 22 23 /** 24 * Params: 25 * arguments = Values to be assigned. 26 */ 27 public void opAssign(Arguments arguments) 28 { 29 this.isNull_ = false; 30 31 auto payload = tuple!Arguments(arguments); 32 moveEmplace(payload, this.arguments_); 33 } 34 35 /** 36 * Returns: $(D_KEYWORD true) if the tuple is set, $(D_KEYWORD false) 37 * otherwise. 38 */ 39 public @property bool isNull() 40 { 41 return this.isNull_; 42 } 43 44 /** 45 * Params: 46 * n = Value position in the tuple. 47 * 48 * Returns: nth value in the tuple. 49 */ 50 public @property ref Arguments[n] get(size_t n)() 51 if (n < Arguments.length) 52 { 53 import std.exception : enforce; 54 enforce(!isNull()); 55 return this.arguments_[n]; 56 } 57 58 public @property ref Tuple!Arguments get() 59 in (!isNull()) 60 { 61 return this.arguments_; 62 } 63 } 64 65 /** 66 * Holds a typed sequence of template parameters. 67 * 68 * Params: 69 * Args = Elements of this $(D_PSYMBOL Pack). 70 */ 71 struct Pack(Args...) 72 { 73 /// Elements in this tuple as $(D_PSYMBOL AliasSeq). 74 alias Seq = Args; 75 76 /// The length of the tuple. 77 enum size_t length = Args.length; 78 79 alias Seq this; 80 } 81 82 /** 83 * Params: 84 * T = Some type. 85 * 86 * Returns: $(D_KEYWORD true) if $(D_PARAM T) is a class or interface, 87 * $(D_KEYWORD false) otherwise. 88 */ 89 enum bool isPolymorphicType(T) = is(T == class) || is(T == interface);