1 /* 2 MIT License 3 Copyright (c) 2017 Boris Barboris 4 */ 5 6 module daii.utils; 7 8 import std.conv: to; 9 import std.experimental.allocator: make, dispose; 10 import std.traits: Unqual, isArray; 11 import std.meta: AliasSeq; 12 13 14 template isAllocator(T) 15 { 16 // Credits to atila. 17 // https://github.com/atilaneves/automem/blob/master/source/automem/traits.d 18 private template isAllocatorAlike(T) 19 { 20 enum isAllocatorAlike = is(typeof(() 21 { 22 T allocator; 23 int* i = allocator.make!int; 24 allocator.dispose(i); 25 void[] bytes = allocator.allocate(size_t.init); 26 bool res = allocator.deallocate(bytes); 27 })); 28 } 29 enum isAllocator = isAllocatorAlike!(Unqual!T) || 30 isAllocatorAlike!(shared Unqual!T); 31 } 32 33 template isStaticAllocator(T) 34 if (isAllocator!T) 35 { 36 static if (is(typeof(T.instance))) 37 enum isStaticAllocator = isAllocator!(typeof(T.instance)); 38 else 39 enum isStaticAllocator = false; 40 } 41 42 unittest 43 { 44 import std.experimental.allocator.showcase: StackFront; 45 import std.experimental.allocator.mallocator: Mallocator; 46 47 static assert(isAllocator!Mallocator); 48 static assert(isStaticAllocator!Mallocator); 49 static assert(!isAllocator!int); 50 static assert(isAllocator!(StackFront!4096)); 51 static assert(!isStaticAllocator!(StackFront!4096)); 52 } 53 54 package string fieldExpand(int count, string arrname)() 55 { 56 string result = ""; 57 for (int i = 0; i < count; i++) 58 { 59 string idx_str = to!string(i); 60 result ~= arrname ~ "[" ~ idx_str ~ "] field" ~ idx_str ~ ";"; 61 } 62 return result; 63 } 64 65 package string argsAndFields(uint count1, string G1, uint count2)() 66 { 67 string result = ""; 68 for (uint i = 0; i < count1; i++) 69 result ~= G1 ~ "[" ~ to!string(i) ~ "], "; 70 for (uint i = 0; i < count2; i++) 71 { 72 result ~= "this.field" ~ to!string(i); 73 if (i < count2 - 1) 74 result ~= ", "; 75 } 76 return result; 77 } 78 79 template isFunctionPointerType(T: FT*, FT) 80 { 81 enum isFunctionPointerType = is(FT == function); 82 } 83 84 unittest 85 { 86 auto p = (){}; 87 static assert(isFunctionPointerType!(typeof(p))); 88 } 89 90 template ReturnType(FuncType: FT*, FT) 91 { 92 static if (is(FT RT == return)) 93 alias ReturnType = RT; 94 else 95 static assert(0, "FuncType must be function pointer type"); 96 } 97 98 template ParamTypes(FuncType: FT*, FT) 99 { 100 static if (is(FT Params == function)) 101 alias ParamTypes = Params; 102 else 103 static assert(0, "FuncType must be function pointer type"); 104 } 105 106 unittest 107 { 108 auto p = (int x){ return x; }; 109 static assert(is(ReturnType!(typeof(p)) == int)); 110 static assert(is(ParamTypes!(typeof(p)) == AliasSeq!int)); 111 } 112 113 template Take(int count, T...) 114 { 115 alias Take = T[0 .. count]; 116 } 117 118 unittest 119 { 120 alias res = Take!(2, int, int, int, float); 121 static assert(is(res == AliasSeq!(int, int))); 122 static assert(!is(res == AliasSeq!(int, float))); 123 } 124 125 template Skip(int count, T...) 126 { 127 alias Skip = T[count .. $]; 128 } 129 130 unittest 131 { 132 alias res = Skip!(1, int, int, int, float); 133 static assert(is(res == AliasSeq!(int, int, float))); 134 } 135 136 template isClassOrIface(T) 137 { 138 enum isClassOrIface = is(T == class) || is(T == interface); 139 }