1 module dcompute.driver.ocl.util; 2 3 import std.range; 4 import std.meta; 5 import std.traits; 6 7 //deal with arrays seperately, in part to avoid any 8 //narrow-string idiocy 9 @property auto memSize(R)(R r) 10 if (is(R : T[], T)) 11 { 12 static if (is(R : T[], T)) 13 return r.length * T.sizeof; 14 else 15 static assert(false); 16 } 17 18 @property auto memSize(R)(R r) 19 if(isInputRange!R && hasLength!R && !is(R : T[], T)) 20 { 21 return r.length * (ElementType!R).sizeof; 22 } 23 24 T[Args.length + 1] propertyList(T,Args...)(Args args) 25 { 26 T[Args.length + 1] props; 27 foreach(i, arg; args) 28 props[i] = *cast(T*)(&arg); 29 props[$-1] = cast(T)0; 30 return props; 31 } 32 33 struct ArrayAccesssor(alias ptr, alias len) {} 34 35 struct StringzAccessor(alias ptr) {} 36 37 struct ZeroTerminatedArrayAccessor(alias ptr) {} 38 39 struct ArrayAccesssor2D(alias ptr, alias lens, alias len) {} 40 41 // Returned by ArrayAccesssor2D 42 struct RangeOfArray(T) 43 { 44 T** ptr; 45 size_t* lengths; 46 size_t length; 47 size_t index; 48 49 bool empty() 50 { 51 return index == length; 52 } 53 54 @property T[] front() 55 { 56 return ptr[index][0 .. lengths[index]]; 57 } 58 59 T[] opIndex(size_t i) 60 { 61 return ptr[i][0 .. lengths[i]]; 62 } 63 void popFront() 64 { 65 ++index; 66 } 67 68 @property size_t opDollar() { return length; } 69 } 70 71 string generateGetInfo(Info,alias func,string args = "raw")() 72 { 73 import std..string; 74 return helper!(Info.tupleof).format(func.stringof,args); 75 } 76 77 // A substitute for fullyQualifiedName to speed up compile time 78 private template isModule(alias a) { 79 static if (is(a) || is(typeof(a)) || a.stringof.length < 7) { 80 enum isModule = false; 81 } else { 82 enum isModule = a.stringof[0..7] == "module "; 83 } 84 } 85 86 private template partiallyQualifiedName(alias a) { 87 static if (isModule!a) { 88 enum partiallyQualifiedName = ""; 89 } else { 90 static if (!isModule!(__traits(parent, a))) { 91 enum prefix = partiallyQualifiedName!(__traits(parent, a)) ~ "."; 92 } else { 93 enum prefix = ""; 94 } 95 enum partiallyQualifiedName = prefix ~ __traits(identifier, a); 96 } 97 } 98 99 private template helper(Fields...) 100 { 101 static if (Fields.length == 0) 102 enum helper = ""; 103 104 else static if (is(typeof(Fields[0]) : ArrayAccesssor!(ptr,len),alias ptr,alias len)) 105 { 106 enum helper = "@property " ~ typeof(*ptr).stringof ~ "[] " ~ Fields[0].stringof ~ "()\n" ~ 107 "{\n" ~ 108 " return " ~ ptr.stringof ~ "[0 .. " ~ len.stringof ~"];"~ 109 "}\n" ~ helper!(Fields[1 .. $]); 110 } 111 else static if (is(typeof(Fields[0]) : StringzAccessor!ptr,alias ptr)) 112 { 113 enum helper = "@property char[] " ~ Fields[0].stringof ~ "()\n" ~ 114 "{\n" ~ 115 " import std.typecons; char[] ret;" ~ 116 " size_t len;" ~ 117 " %1$s(%2$s," ~ __traits(getAttributes, ptr).stringof ~ "[0], 0, null, &len);" ~ 118 " ret.length = len;" ~ 119 " %1$s(%2$s," ~ __traits(getAttributes, ptr).stringof ~ "[0], memSize(ret), ret.ptr, null);" ~ 120 " return ret;" ~ 121 "}\n" ~ helper!(Fields[1 .. $]); 122 } 123 else static if (is(typeof(Fields[0]) : ArrayAccesssor2D!(ptr,lens,len) , alias ptr, alias lens, alias len)) 124 { 125 enum helper = "@property RangeOfArray!(" ~ typeof(**ptr).stringof ~ ") " ~ Fields[0].stringof ~ "()\n" ~ 126 "{\n" ~ 127 " import std.typecons; size_t length; size_t* lengths; " ~ typeof(ptr).stringof ~ " ptr;" ~ 128 " %1$s(%2$s," ~ __traits(getAttributes, len).stringof ~ "[0],length.sizeof, &length,null);" ~ 129 " lengths = (new size_t[length]).ptr; ptr = (new " ~ typeof(*ptr).stringof ~ "[length]).ptr;" ~ 130 " %1$s(%2$s," ~ __traits(getAttributes, lens).stringof ~ "[0],lengths.sizeof, lengths,null);" ~ 131 " if (lengths[length - 1] == 0) length--;" ~ 132 " foreach(i; 0 .. length) \n{" ~ 133 " ptr[i] = (new " ~ typeof(**ptr).stringof ~ "[lengths[i]]).ptr;" ~ 134 " }\n" ~ 135 " %1$s(%2$s," ~ __traits(getAttributes, ptr).stringof ~ "[0], ptr.sizeof, ptr, null);" ~ 136 " return typeof(return)(ptr,lengths,length,0);" ~ 137 "}\n" ~ helper!(Fields[1 .. $]); 138 } 139 else 140 { 141 static if (is(typeof(Fields[0]) == enum)) 142 { 143 enum helper = "@property " ~ partiallyQualifiedName!(typeof(Fields[0])) ~ " " ~ Fields[0].stringof ~ "()\n" ~ 144 "{\n" ~ 145 " import std.typecons; typeof(return) ret;" ~ 146 "%1$s(%2$s,"~ __traits(getAttributes, Fields[0]).stringof ~ "[0], ret.sizeof, &ret, null);" ~ 147 "return ret; " ~ 148 "}\n" ~ helper!(Fields[1 .. $]); 149 150 } 151 else 152 { 153 enum helper = "@property " ~ typeof(Fields[0]).stringof ~ " " ~ Fields[0].stringof ~ "()\n" ~ 154 "{\n" ~ 155 " import std.typecons; typeof(return) ret;" ~ 156 "%1$s(%2$s,"~ __traits(getAttributes, Fields[0]).stringof ~ "[0], ret.sizeof, &ret, null);" ~ 157 "return ret; " ~ 158 "}\n" ~ helper!(Fields[1 .. $]); 159 } 160 } 161 }