Re: Creating a "fixed-range int" with opDispatch and/or alias this?

2016-06-02 Thread tsbockman via Digitalmars-d-learn

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?

2016-06-02 Thread Ali Çehreli via Digitalmars-d-learn

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?

2016-06-02 Thread ag0aep6g via Digitalmars-d-learn

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?

2016-06-02 Thread Ali Çehreli via Digitalmars-d-learn

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?

2016-06-01 Thread Rene Zwanenburg via Digitalmars-d-learn

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?

2016-06-01 Thread Mark Isaacson via Digitalmars-d-learn
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.