1 module poison.core.vector; 2 3 /** 4 * Vector mixin template to create vector types. 5 * Params: 6 * T = The type of the vector. 7 * names = The names of all members of the vector. 8 */ 9 private mixin template Vector(T, string[] names) { 10 /// Format for members. 11 enum memberFormat = q{ 12 private %s _%s; 13 }; 14 15 /// Format for properties. 16 enum propertyFormat = q{ 17 @property { 18 public auto %s() { return _%s; } 19 20 public void %s(%s newValue) { _%s = newValue; } 21 } 22 }; 23 24 /// Format for parameters. 25 enum paramFormat = "%s %s,"; 26 27 /// Format for member sets. 28 enum memberSetFormat = "_%s = %s;"; 29 30 /// Generates the constructor. 31 static string generateConstructor() { 32 import std.string : format; 33 34 auto paramsString = ""; 35 auto memberSetString = ""; 36 37 foreach (name; names) { 38 paramsString ~= paramFormat.format(T.stringof, name); 39 40 memberSetString ~= memberSetFormat.format(name, name); 41 } 42 43 if (paramsString) { 44 paramsString.length -= 1; 45 } 46 47 return "this(" ~ paramsString ~ ") { " ~ memberSetString ~ " }"; 48 } 49 50 mixin(generateConstructor); 51 52 /// Generates the members. 53 static string generateMembers() { 54 import std.string : format; 55 56 auto membersString = ""; 57 58 foreach (name; names) { 59 membersString ~= memberFormat.format(T.stringof, name); 60 } 61 62 return membersString; 63 } 64 65 mixin(generateMembers); 66 67 /// Generates the properties. 68 static string generateProperties() { 69 import std.string : format; 70 71 auto propertiesString = ""; 72 73 foreach (name; names) { 74 propertiesString ~= propertyFormat.format(name, name, name, T.stringof, name); 75 } 76 77 return propertiesString; 78 } 79 80 mixin(generateProperties); 81 } 82 83 /// A 2d point vector. 84 private class Point2dVector(T) { 85 mixin Vector!(T, ["x", "y"]); 86 } 87 88 /// Alias to create a 2d point vector of ptrdiff_t. 89 public alias Point = Point2dVector!ptrdiff_t; 90 91 /// Alias to create a 2d point vector of float. 92 public alias PointF = Point2dVector!float; 93 94 /// A 3d point vector. 95 private class Point3dVector(T) { 96 mixin Vector!(T, ["x", "y", "z"]); 97 } 98 99 /// Alias to create a 3d point vector of ptrdiff_t. 100 public alias Point3d = Point3dVector!ptrdiff_t; 101 102 /// Alias to create a 3d point vector of float. 103 public alias Point3dF = Point3dVector!float; 104 105 /// A 2d size vector. 106 private class Size2dVector(T) { 107 mixin Vector!(T, ["width", "height"]); 108 } 109 110 /// Alias to create a 2d size vector of size_t. 111 public alias Size = Size2dVector!size_t; 112 113 /// Alias to create a 2d size vector of float. 114 public alias SizeF = Size2dVector!float; 115 116 /// A 3d size vector. 117 private class Size3dVector(T) { 118 mixin Vector!(T, ["width", "height", "depth"]); 119 } 120 121 /// Alias to create a 3d size vector of size_t. 122 public alias Size3d = Size3dVector!size_t; 123 124 /// Alias to create a 3d size vector of float. 125 public alias Size3dF = Size3dVector!float; 126 127 /// An edge vector. 128 private class EdgeVector(T) { 129 mixin Vector!(T, ["top", "right", "bottom", "left"]); 130 } 131 132 /// Alias to create an edge vector of ptrdiff_t. 133 public alias Edge = EdgeVector!ptrdiff_t; 134 135 /// Alias to create an edge vector of float. 136 public alias EdgeF = EdgeVector!float;