View mode: basic / threaded / horizontal-split · Log in · Help
June 24, 2012
Retain struct when using alias this and passing using the alias..?
import std.exception;
import std.traits;

struct Ranged(T, T min, T max) {
    T _value = min;
    typeof(this) opAssign(V : T)(V value) {
        enforce(value >= min);
        enforce(value <= max);
        _value = value;
        return this;
    }
    alias _value this;
}

void f(int i) {
    i = 1000;
}

void g(T)(T i) if(isIntegral!T){
    i = 1000;
}

void main() {
    Ranged!(int, 10, 20) v;
    v = 10; // ok
    v = 20; // ok
    f(v); // auch
    g(v); // ok, exception
}

Is there a way to ensure the struct is used in f() without using templates  
as in g()?
June 24, 2012
Re: Retain struct when using alias this and passing using the alias..?
On Sunday, 24 June 2012 at 13:16:53 UTC, simendsjo wrote:
> import std.exception;
> import std.traits;
>
> struct Ranged(T, T min, T max) {
>     T _value = min;
>     typeof(this) opAssign(V : T)(V value) {
>         enforce(value >= min);
>         enforce(value <= max);
>         _value = value;
>         return this;
>     }
>     alias _value this;
> }
>
> void f(int i) {
>     i = 1000;
> }
>
> void g(T)(T i) if(isIntegral!T){
>     i = 1000;
> }
>
> void main() {
>     Ranged!(int, 10, 20) v;
>     v = 10; // ok
>     v = 20; // ok
>     f(v); // auch
>     g(v); // ok, exception
> }
>
> Is there a way to ensure the struct is used in f() without 
> using templates as in g()?

This should currently be impossible. The compiler would need to 
automatically promote f to a template function.
June 25, 2012
Re: Retain struct when using alias this and passing using the alias..?
On Sunday, 24 June 2012 at 13:16:53 UTC, simendsjo wrote:
> import std.exception;
> import std.traits;
>
> struct Ranged(T, T min, T max) {
>     T _value = min;
>     typeof(this) opAssign(V : T)(V value) {
>         enforce(value >= min);
>         enforce(value <= max);
>         _value = value;
>         return this;
>     }
>     alias _value this;
> }
>
> void f(int i) {
>     i = 1000;
> }
>
> void g(T)(T i) if(isIntegral!T){
>     i = 1000;
> }
>
> void main() {
>     Ranged!(int, 10, 20) v;
>     v = 10; // ok
>     v = 20; // ok
>     f(v); // auch
>     g(v); // ok, exception
> }
>
> Is there a way to ensure the struct is used in f() without 
> using templates as in g()?

The type of 'alias this' symbol works as like the super class of 
user defined class.
Therefore, Ranged!(...) is always implicitly convertible to int 
by 'alias _value this', and there is no way to disable such 
conversion.

Kenji Hara
Top | Discussion index | About this forum | D home