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 fieldsToParamListStr(uint count) 66 { 67 string result = ""; 68 for (uint i = 0; i < count; i++) 69 { 70 result ~= "this.field" ~ to!string(i); 71 if (i < count - 1) 72 result ~= ", "; 73 } 74 return result; 75 } 76 77 template isFunctionPointerType(T: FT*, FT) 78 { 79 enum isFunctionPointerType = is(FT == function); 80 } 81 82 unittest 83 { 84 auto p = (){}; 85 static assert(isFunctionPointerType!(typeof(p))); 86 } 87 88 template ReturnType(FuncType: FT*, FT) 89 { 90 static if (is(FT RT == return)) 91 alias ReturnType = RT; 92 else 93 static assert(0, "FuncType must be function pointer type"); 94 } 95 96 template ParamTypes(FuncType: FT*, FT) 97 { 98 static if (is(FT Params == function)) 99 alias ParamTypes = Params; 100 else 101 static assert(0, "FuncType must be function pointer type"); 102 } 103 104 unittest 105 { 106 auto p = (int x){ return x; }; 107 static assert(is(ReturnType!(typeof(p)) == int)); 108 static assert(is(ParamTypes!(typeof(p)) == AliasSeq!int)); 109 } 110 111 template Take(int count, T...) 112 { 113 alias Take = T[0 .. count]; 114 } 115 116 unittest 117 { 118 alias res = Take!(2, int, int, int, float); 119 static assert(is(res == AliasSeq!(int, int))); 120 static assert(!is(res == AliasSeq!(int, float))); 121 } 122 123 template Skip(int count, T...) 124 { 125 alias Skip = T[count .. $]; 126 } 127 128 unittest 129 { 130 alias res = Skip!(1, int, int, int, float); 131 static assert(is(res == AliasSeq!(int, int, float))); 132 } 133 134 template isClassOrIface(T) 135 { 136 enum isClassOrIface = is(T == class) || is(T == interface); 137 }