Default struct constructors if a struct member is a union

cc cc at nevernet.com
Sun Jul 7 02:16:29 UTC 2024


On Saturday, 29 June 2024 at 23:33:41 UTC, solidstate1991 wrote:
> My question is can I initialize structs like these in one line 
> without relying on a second line?

```d
template ValueOfUDAType(alias T, alias UDA) {
	static foreach (uidx, U; __traits(getAttributes, T)) static if 
(is(typeof(U) == UDA)) enum UDA ValueOfUDAType = U;
}
struct S {
	enum TypeEnum {
		Integer32,
		Integer64,
		Float32,
		Float64,
	}
	union U {
		@(TypeEnum.Integer32) int i32;
		@(TypeEnum.Integer64) long i64;
		@(TypeEnum.Float32) float f32;
		@(TypeEnum.Float64) double f64;
	}
	TypeEnum type;
	U data;
	this(T)(T t) { opAssign(t); }
	void opAssign(S rhs) {
		static foreach (idx, field; S.tupleof) {
			this.tupleof[idx] = rhs.tupleof[idx];
		}
	}
	void opAssign(T)(T t) {
		static foreach (idx, field; data.tupleof) static if (is(T == 
typeof(field))) {
			type = ValueOfUDAType!(field, TypeEnum);
			data.tupleof[idx] = t;
			static assert(!is(typeof(FOUND)), "Assigning type 
"~fullyQualifiedName!T~" matches multiple candidates 
"~fullyQualifiedName!U);
			enum bool FOUND = true;
		}
		static assert(is(typeof(FOUND)), "Cannot assign type 
"~fullyQualifiedName!T~" to "~fullyQualifiedName!U);
	}
	T get(T)() {
		static foreach (idx, field; data.tupleof) static if (is(T == 
typeof(field))) {
			enforce(type == ValueOfUDAType!(field, TypeEnum), "Type 
mismatch requesting "~fullyQualifiedName!T);
			return data.tupleof[idx];
		}
	}
	bool is_a(T)() {
		static foreach (idx, field; data.tupleof) static if (is(T == 
typeof(field))) {
			return (type == ValueOfUDAType!(field, TypeEnum));
		}
	}
}

S s = 3.14f;
assert(s.type == S.TypeEnum.Float32);
s = 9.17;
assert(s.type == S.TypeEnum.Float64);

if (s.is_a!double) {
	writeln(s.get!double);
}
try {
	int n = s.get!int;
} catch (Exception e) {
	writeln("Not an int");
}

s = 20;
assert(s.type == S.TypeEnum.Integer32);
s = 40L;
assert(s.type == S.TypeEnum.Integer64);
```


Or just use SumType.



More information about the Digitalmars-d-learn mailing list