1 module meta_ex; 2 3 import std.range : isInputRange; 4 import std.meta : NoDuplicates, AliasSeq; 5 6 static if (__VERSION__ >= 2070) 7 { 8 import std.meta : aliasSeqOf; 9 } 10 else 11 { 12 /** Create $(D AliasSeq) from Static Array. 13 See also: http://forum.dlang.org/thread/cxahuyvnygtpsaseieeh@forum.dlang.org 14 See also: https://github.com/D-Programming-Language/phobos/pull/3785 15 */ 16 template aliasSeqOf(TL...) 17 if (TL.length == 1 && 18 isInputRange!(typeof(TL[0]))) 19 { 20 import std.range: front, empty, popFront; 21 alias TT = AliasSeq; 22 enum r = TL[0]; 23 static if (r.empty) 24 { 25 alias aliasSeqOf = TT!(); 26 } 27 else 28 { 29 enum f = r.front; 30 alias aliasSeqOf = TT!( 31 f, 32 aliasSeqOf!( 33 { auto tmp = r; tmp.popFront(); return tmp; }() 34 ) 35 ); 36 } 37 } 38 } 39 40 alias toAliasSeq = aliasSeqOf; 41 42 @safe pure nothrow @nogc unittest 43 { 44 import std.range : iota; 45 foreach(i; aliasSeqOf!(iota(10))) 46 { 47 // pragma(msg, i); 48 } 49 } 50 51 alias Deduplicate = NoDuplicates; 52 alias Uniq = NoDuplicates; 53 54 /** 55 See also: http://forum.dlang.org/post/sulxqtfprmkeekjatqup@forum.dlang.org 56 */ 57 template Merge1(A...) 58 if (!(A.length & 1)) 59 { 60 static if (A.length == 0) 61 { 62 alias Merge1 = AliasSeq!(); 63 } 64 else 65 { 66 alias Left = A[0 .. $ / 2]; 67 alias Right = A[$ / 2 .. $]; 68 alias Merge1 = AliasSeq!(Left[0], Right[0], Merge1!(Left[1 .. $], Right[1 .. $])); 69 } 70 } 71 72 @safe pure nothrow @nogc unittest 73 { 74 struct S(A...) {} // needed to reliably compare AliasSeq's for equality 75 76 alias first = AliasSeq!(int, string, bool); 77 alias second = AliasSeq!("abc", "def", "ghi"); 78 alias third = Merge1!(first, second); 79 80 static assert(is(S!third == S!(int, "abc", 81 string, "def", 82 bool, "ghi"))); 83 } 84 85 /** 86 See also: http://forum.dlang.org/post/sulxqtfprmkeekjatqup@forum.dlang.org 87 */ 88 template Merge(A...) 89 { 90 template With(B...) 91 { 92 static if (A.length == 0 || 93 B.length == 0) 94 alias With = AliasSeq!(A, B); // or static assert(0) if you require equal lengths 95 else 96 alias With = AliasSeq!(A[0], B[0], Merge!(A[1 .. $]).With!(B[1 .. $])); 97 } 98 } 99 100 @safe pure nothrow @nogc unittest 101 { 102 struct S(A...) {} // needed to reliably compare AliasSeq's for equality 103 104 alias first = AliasSeq!(int, string, bool); 105 alias second = AliasSeq!("abc", "def", "ghi"); 106 alias third = Merge!first.With!second; 107 108 static assert(is(S!third == S!(int, "abc", 109 string, "def", 110 bool, "ghi"))); 111 112 alias fourth = Merge!(first[0 .. 2]).With!second; 113 114 static assert(is(S!fourth == S!(int, "abc", 115 string, "def", 116 "ghi"))); 117 }