d的自动构造器模板
原文
通用,hashOf
函数:
override size_t toHash() const {
return hashOf(y, hashOf(x));
}
这里:
enum defaultClassConstructor = q{
this(typeof(this.tupleof) params) {
static foreach (i; 0..this.tupleof.length)
this.tupleof[i] = params[i];
}
};
struct Color {
ubyte r, g, b, a;
}
class Point {
Color c;
int x, y;
bool h;
mixin(defaultClassConstructor);
}
unittest
{
Color foo = { r : 0x30,
g : 0xd5,
b : 0xc8
};
auto bar = new Point(foo, 320, 240, true);
assert(bar.h);
assert(bar.x == 320);
assert(bar.y == 240);
assert(bar.c.a == 0);
assert(bar.c.r == 48);
assert(bar.c.g == 213);
assert(bar.c.b == 200);
}
//另一版本
void main()
{
auto colorWithAlpha = vec4i(100, 150, 200, 300);
colorWithAlpha.r = 120;
assert(colorWithAlpha.r == 120);
assert(colorWithAlpha.g == 150);
assert(colorWithAlpha.b == 200);
assert(colorWithAlpha.a == 300);
auto point3D = vec3i(100, 200, 300);
point3D.z /= 2;
assert(point3D.x == 100);
assert(point3D.y == 200);
assert(point3D.z == 150);
auto point2D = vec2i(100, 200);
point2D.y = point3D.z;
assert(point2D.x == 100);
assert(point2D.y == 150);
}
template vec2(T) { alias Vector!(T, 2) vec2; }
alias vec2!int vec2i;
alias vec2!float vec2f;
alias vec2!double vec2d;
template vec3(T) { alias Vector!(T, 3) vec3; }
alias vec3!int vec3i;
alias vec3!float vec3f;
alias vec3!double vec3d;
template vec4(T) { alias Vector!(T, 4) vec4; }
alias vec4!int vec4i;
alias vec4!float vec4f;
alias vec4!double vec4d;
enum isVector(T) = is(T : Vector!A, A...);
struct Vector(T, int N)
{
static assert(N >= 1);
import std.conv,
std.format,
std.traits;
union
{
T[N] v;
struct
{
static if(N >= 1)
{
T x; alias x r;
}
static if(N >= 2)
{
T y; alias y g;
}
static if(N >= 3)
{
T z; alias z b;
}
static if(N >= 4)
{
T w; alias w a;
}
}
}
this(Args...)(Args args)
{
static if (args.length == 1)
{// 从简单值构造向量
opAssign!(Args[0])(args[0]);
}
else
{ // 验证总参个数
template argCount(T...)
{
static if(T.length == 0)
enum argCount = 0; // 递归完成
else static if(isVector!(T[0]))
enum argCount = T[0]._N + argCount!(T[1..$]);
else
enum argCount = 1 + argCount!(T[1..$]);
}
static assert(argCount!Args <= N, "Too many arguments in vector constructor");
int index = 0;
foreach(arg; args)
{
static if(isAssignable!(T, typeof(arg)))
{
v[index] = arg;
index++; //
}
else static if (isVector!(typeof(arg)) && isAssignable!(T, arg._T))
{
mixin(generateLoopCode!("v[index + @] = arg[@];", arg._N)());
index += arg._N;
}
else static assert(false, "Unrecognized argument in Vector constructor");
}
assert(index == N, "Bad arguments in Vector constructor");
}
}
/// 用静态数组赋值
ref Vector opAssign(U)(U arr)
if ((isStaticArray!(U) && isAssignable!(T, typeof(arr[0])) && (arr.length == N)))
{
mixin(generateLoopCode!("v[@] = arr[@];", N)());
return this;
}
/// 用动态数组
ref Vector opAssign(U)(U arr)
if (isDynamicArray!(U) && isAssignable!(T, typeof(arr[0])))
{
assert(arr.length == N);
mixin(generateLoopCode!("v[@] = arr[@];", N)());
return this;
}
/// 相同向量
ref Vector opAssign(U)(U u)
if (is(U : Vector))
{
v[] = u.v[];
return this;
}
/// 其余向量类型
ref Vector opAssign(U)(U x)
if(isVector!U && isAssignable!(T, U._T)
&& (!is(U: Vector))
&& (U._N == _N)
) {
mixin(generateLoopCode!("v[@] = x.v[@];", N)());
return this;
}
/// 内容指针
inout(T)* ptr() inout @property
{
return v.ptr;
}
/// 良好打印
string toString() const nothrow
{
try
return format("%s", v);
catch (Exception e)
assert(false); // 不应该
}
private
{
enum _N = N;
alias T _T;
// 可转换类型
template isConvertible(T)
{
enum bool isConvertible =
(!is(T : Vector)) &&
is(typeof( { T x_Detect;
Vector v = x_Detect;
}()
)
);
}
static
string generateLoopCode(string str, int N)()
{
import std.string;
string result;
for(int i; i < N; ++i)
{
string index = ctIntToString(i);
// replace all @ by indices
result ~= str.replace("@", index);
}
return result;
}
// 加速ctfe.
static string ctIntToString(int n)
{
static
immutable string[16] table = ["0", "1", "2",
"3", "4", "5",
"6", "7", "8",
"9"];
if (n < 10) return table[n];
else return n.to!string;
}
} // 私
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现