1 module des.math.util.flatdata; 2 3 import std.traits; 4 import std..string; 5 import std.meta; 6 7 import des.ts; 8 import des.stdx.traits; 9 import des.math.linear.vector; 10 public import des.stdx.range : flatData; 11 12 /// 13 template hasIterableData(T) 14 { enum hasIterableData = is( typeof( isIterable!(typeof(T.init.data)) ) ); } 15 16 /// 17 template hasStaticIterableData(T) 18 { 19 static if( hasIterableData!T ) 20 enum hasStaticIterableData = isStaticArray!(typeof(T.init.data)); 21 else 22 enum hasStaticIterableData = false; 23 } 24 25 bool canStaticFill(size_t N,T,E...)() pure @property 26 if( E.length > 0 ) 27 { return hasNoDynamic!E && N == getElemCount!E && isConvertable!(T,E); } 28 29 bool hasNoDynamic(E...)() pure @property 30 { 31 static if( E.length == 1 ) return !hasIndirections!(E[0]); 32 else return hasNoDynamic!(E[0]) && hasNoDynamic!(E[1..$]); 33 } 34 35 size_t getElemCount(E...)() pure @property 36 { 37 static if( E.length == 0 ) return 0; 38 else static if( E.length >= 1 ) 39 return getTypeElemCount!(E[0]) + getElemCount!(E[1..$]); 40 } 41 42 size_t getTypeElemCount(E)() pure @property 43 { 44 static if( isStaticArray!E ) return E.length; 45 else static if( hasStaticIterableData!E ) return E.data.length; 46 else return 1; 47 } 48 49 bool isConvertable(T,E...)() pure @property 50 { 51 static if( E.length == 1 ) 52 { 53 alias E[0] X; 54 static if( is( typeof( T(X.init) ) ) ) return true; 55 else static if( isComplex!T && ( isNumeric!X || isImaginary!X ) ) return true; 56 else static if( isNumeric!X && isNumeric!T ) return true; 57 else static if( isStaticArray!X ) return isConvertable!(T,typeof(X.init[0])); 58 else static if( isStaticVector!X ) 59 { 60 static if( isStaticVector!T ) 61 return T.length == X.length && isConvertable!(T.datatype,X.datatype); 62 else 63 return isConvertable!(T,X.datatype); 64 } 65 else return false; 66 } 67 else return isConvertable!(T,E[0]) && isConvertable!(T,E[1..$]); 68 } 69 70 string vectorStaticFill(string type, string data, string vals, T, E...)() pure @property 71 if( E.length > 0 ) 72 { 73 string[] ret; 74 static if( isStaticVector!T ) 75 { 76 ret ~= convertValues!(T.datatype,E)( type~".datatype", data, vals ); 77 foreach( i, ref r; ret ) 78 r = format( "%1$s[%2$s/%3$s][%2$s%%%3$s] = %4$s;", data, i, T.length, r ); 79 } 80 else 81 { 82 ret ~= convertValues!(T,E)( type, data, vals ); 83 foreach( i, ref r; ret ) 84 r = format( "%s[%s] = %s;", data, i, r ); 85 } 86 return ret.join("\n"); 87 } 88 89 string matrixStaticFill(string type, string data, string vals, size_t W, T, E...)() pure @property 90 if( E.length > 0 ) 91 { 92 string[] ret; 93 ret ~= convertValues!(T,E)( type, data, vals ); 94 foreach( i, ref r; ret ) 95 r = format( "%s[%s][%s] = %s;", data, i/W, i%W, r ); 96 return ret.join("\n"); 97 } 98 99 string[] convertValues(T,E...)( string type, string data, string vals, size_t valno=0 ) pure 100 { 101 static if( E.length == 1 ) 102 return convertValue!(T,E[0])(type,data,vals,valno); 103 else 104 return convertValue!(T,E[0])(type,data,vals,valno) ~ 105 convertValues!(T,E[1..$])(type,data,vals,valno+1); 106 } 107 108 string[] convertValue(T, E)( string type, string data, string vals, size_t valno ) pure 109 { 110 static if( isStaticArray!E || isStaticVector!E ) 111 { 112 string[] ret; 113 foreach( i; 0 .. E.length ) 114 ret ~= format( convertRule!(T,typeof(E.init[0])), type, format( "%s[%d][%d]", vals, valno, i ) ); 115 return ret; 116 } 117 else 118 return [ format( convertRule!(T,E), type, format( "%s[%d]", vals, valno ) ) ]; 119 } 120 121 string convertRule(T,E)() pure @property 122 { 123 static if( isNumeric!E && isNumeric!T ) 124 return "cast(%s)(%s)"; 125 else static if( isComplex!T && ( isNumeric!E || isImaginary!E ) ) 126 return "%s(0+0i+%s)"; 127 else static if( is( typeof( T(E.init) ) ) ) 128 return "%s(%s)"; 129 else static assert( 0, "uncompatible types [convertRule]" ); 130 }