Re: Creating a "fixed-range int" with opDispatch and/or alias this?
On Wednesday, 1 June 2016 at 19:59:51 UTC, Mark Isaacson wrote: I'm trying to create a type that for all intents and purposes behaves exactly like an int except that it limits its values to be within a certain range [a,b]. Theoretically, I would think this looks something like: ... It looks like opDispatch doesn't participate in resolution of operator overloads. Is there any way I can achieve my desired result? I know alias this forwards operations like +=, but with alias this I cannot wrap the operation to do the bounds checking. I think you would need to implement all of: * this(...) * opAssign(...) * opOpAssign(...) * opBinary(...) * opBinaryRight(...) * opUnary(...) FWIW, the fixed range int part of this question is just an example, I'm mostly just interested in whether this idea is possible without a lot of bloat/duplication. For a single type, I think the bloat is required. If you want to generate a lot of similar types, though, you could probably write a mixin template to generate the methods for you.
Re: Creating a "fixed-range int" with opDispatch and/or alias this?
On 06/02/2016 07:59 AM, Ali Çehreli wrote: > On 06/01/2016 12:59 PM, Mark Isaacson wrote: >> I'm trying to create a type that for all intents and purposes behaves >> exactly like an int except that it limits its values to be within a >> certain range [a,b]. > > 'alias this' with property functions work at least for your example: I can't believe I wrote that. :) No, it doesn't work. > struct FixedRangeInt { > int min; > int max; > int i_; > > int value() const { > return i_; > } > > void value(int i) { > assert(i >= min); > assert(i < max); And those better be moved to an invariant block. However, 'alias value this' does not work and 'alias i_ this' has no effect because there is no member-function called, so the invariant block is not executed. > i_ = i; > } > > alias i_ this; Silly mistake up there. :-/ > } > > void main() { > auto f = FixedRangeInt(0, 100); > f += 2; > assert(f == 2); > } > > Ali > Sorry for the noise. Ali
Re: Creating a "fixed-range int" with opDispatch and/or alias this?
On 06/02/2016 04:59 PM, Ali Çehreli wrote: 'alias this' with property functions work at least for your example: struct FixedRangeInt { int min; int max; int i_; int value() const { return i_; } void value(int i) { assert(i >= min); assert(i < max); i_ = i; } alias i_ this; } void main() { auto f = FixedRangeInt(0, 100); f += 2; assert(f == 2); } Ali The `value` methods are never called here. The checks are not performed.
Re: Creating a "fixed-range int" with opDispatch and/or alias this?
On 06/01/2016 12:59 PM, Mark Isaacson wrote: I'm trying to create a type that for all intents and purposes behaves exactly like an int except that it limits its values to be within a certain range [a,b]. 'alias this' with property functions work at least for your example: struct FixedRangeInt { int min; int max; int i_; int value() const { return i_; } void value(int i) { assert(i >= min); assert(i < max); i_ = i; } alias i_ this; } void main() { auto f = FixedRangeInt(0, 100); f += 2; assert(f == 2); } Ali
Re: Creating a "fixed-range int" with opDispatch and/or alias this?
On Wednesday, 1 June 2016 at 19:59:51 UTC, Mark Isaacson wrote: FWIW, the fixed range int part of this question is just an example, I'm mostly just interested in whether this idea is possible without a lot of bloat/duplication. I suspect not.. Here's how std.typecons.Proxy is doing it: https://github.com/dlang/phobos/blob/master/std/typecons.d#L5109
Creating a "fixed-range int" with opDispatch and/or alias this?
I'm trying to create a type that for all intents and purposes behaves exactly like an int except that it limits its values to be within a certain range [a,b]. Theoretically, I would think this looks something like: struct FixedRangeInt { this(int min, int max, int value=0) { this.min = min; this.max = max; this.value = value; } auto opDispatch(string name, T...)(T args) { auto backup = value; scope (failure) value = backup; auto result = mixin(`value.` ~ name ~ `(args)`); if (value < min || value > max) { throw new Exception("Operation put value out of range"); } return result; } int min; int max; int value; } But that code doesn't work for simple cases, like: FixedRangeInt(0, 100) x; x += 5; It looks like opDispatch doesn't participate in resolution of operator overloads. Is there any way I can achieve my desired result? I know alias this forwards operations like +=, but with alias this I cannot wrap the operation to do the bounds checking. FWIW, the fixed range int part of this question is just an example, I'm mostly just interested in whether this idea is possible without a lot of bloat/duplication.