import std.exception, std.stdio;
struct CustomInteger(T, T minValue, T maxValue)
{
T value_;
alias value this;
@property T value() const
{
enforce((value_ >= minValue) &&
(value_ <= maxValue));
return value_;
}
@property void value(T v)
{
value_ = v;
}
ref CustomInteger opOpAssign(string op, T2)(T2 rhs)
{
static if (is (T2 == CustomInteger)) {
mixin("value_ " ~ op ~ "= rhs.value_;");
return this;
} else {
return opOpAssign!op(CustomInteger(rhs));
}
}
}
void main()
{
alias Balance = CustomInteger!(int, -32_000, 32_000);
auto b = Balance(42);
b += 5; // OK
writeln(b); // 47
}
aW1wb3J0IHN0ZC5leGNlcHRpb24sIHN0ZC5zdGRpbzsKCnN0cnVjdCBDdXN0b21JbnRlZ2VyKFQsIFQgbWluVmFsdWUsIFQgbWF4VmFsdWUpCnsKCVQgdmFsdWVfOwoJCglhbGlhcyB2YWx1ZSB0aGlzOwoJCglAcHJvcGVydHkgVCB2YWx1ZSgpIGNvbnN0Cgl7CgkJZW5mb3JjZSgodmFsdWVfID49IG1pblZhbHVlKSAmJgoJCQkJKHZhbHVlXyA8PSBtYXhWYWx1ZSkpOwoJCQoJCXJldHVybiB2YWx1ZV87Cgl9CgkKCUBwcm9wZXJ0eSB2b2lkIHZhbHVlKFQgdikKCXsKCQl2YWx1ZV8gPSB2OwoJfQoKCXJlZiBDdXN0b21JbnRlZ2VyIG9wT3BBc3NpZ24oc3RyaW5nIG9wLCBUMikoVDIgcmhzKQoJewoJCXN0YXRpYyBpZiAoaXMgKFQyID09IEN1c3RvbUludGVnZXIpKSB7CgkJCW1peGluKCJ2YWx1ZV8gIiB+IG9wIH4gIj0gcmhzLnZhbHVlXzsiKTsKCQkJcmV0dXJuIHRoaXM7CgkJCQoJCX0gZWxzZSB7CgkJCXJldHVybiBvcE9wQXNzaWduIW9wKEN1c3RvbUludGVnZXIocmhzKSk7CgkJfQoJfQoKfQoKdm9pZCBtYWluKCkKewoJYWxpYXMgQmFsYW5jZSA9IEN1c3RvbUludGVnZXIhKGludCwgLTMyXzAwMCwgMzJfMDAwKTsKCQoJYXV0byBiID0gQmFsYW5jZSg0Mik7CgkKCWIgKz0gNTsgLy8gT0sKCQoJd3JpdGVsbihiKTsgLy8gNDcKfQ==