www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Retain struct when using alias this and passing using the alias..?

reply simendsjo <simendsjo gmail.com> writes:
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()?
Jun 24 2012
next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
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.
Jun 24 2012
prev sibling parent "Kenji Hara" <k.hara.pg gmail.com> writes:
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
Jun 25 2012