www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Unqual fails with pointer?

reply "Namespace" <rswhite4 googlemail.com> writes:
----
import std.traits : Unqual;

void main() {
	static assert(is(Unqual!int == int));
	static assert(is(Unqual!(const int) == int));
	static assert(is(Unqual!(immutable int) == int));
	static assert(is(Unqual!(shared int) == int));
	static assert(is(Unqual!(shared(const int)) == int));
	static assert(is(Unqual!int* == int*));
	static assert(is(Unqual!(const int*) == int*)); /// Error: 
static assert  (is(const(int)* == int*)) is false
}
----

Is this expected?
Jun 13 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Thursday, 13 June 2013 at 21:32:19 UTC, Namespace wrote:
 ----
 import std.traits : Unqual;

 void main() {
 	static assert(is(Unqual!int == int));
 	static assert(is(Unqual!(const int) == int));
 	static assert(is(Unqual!(immutable int) == int));
 	static assert(is(Unqual!(shared int) == int));
 	static assert(is(Unqual!(shared(const int)) == int));
 	static assert(is(Unqual!int* == int*));
 	static assert(is(Unqual!(const int*) == int*)); /// Error: 
 static assert  (is(const(int)* == int*)) is false
 }
 ----

 Is this expected?
This works: ---- template UnqualPtr(T) { static if (is(T == shared(const U*), U)) alias UnqualPtr = U*; else static if (is(T == const U*, U)) alias UnqualPtr = U*; else static if (is(T == immutable U*, U)) alias UnqualPtr = U*; else static if (is(T == inout U*, U)) alias UnqualPtr = U*; else static if (is(T == shared U*, U)) alias UnqualPtr = U*; else static if (is(T == shared(const U), U)) alias UnqualPtr = U; else static if (is(T == const U, U)) alias UnqualPtr = U; else static if (is(T == immutable U, U)) alias UnqualPtr = U; else static if (is(T == inout U, U)) alias UnqualPtr = U; else static if (is(T == shared U, U)) alias UnqualPtr = U; else alias UnqualPtr = T; } ----
Jun 13 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Just out of interest: how safe is something like this:

----
UnqualPtr!From unqual_cast(From : U*, U)(From from) {
	union Cast {
		From from;
		UnqualPtr!From to;
	}
	
	Cast c;
	c.from = from;
	
	return c.to;
}

const B* cb = ...;
B* b = unqual_cast(cb);
----

compared to this:

----
const B* cb = ...;
B* b = cast(B*) cb;
----

I'm just playing around in favor of something like 'const_cast' 
from C++.
Jun 13 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Namespace:

 Just out of interest: how safe is something like this:

 ----
 UnqualPtr!From unqual_cast(From : U*, U)(From from) {
 	union Cast {
 		From from;
 		UnqualPtr!From to;
 	}
 	
 	Cast c;
 	c.from = from;
 	
 	return c.to;
 }

 const B* cb = ...;
 B* b = unqual_cast(cb);
 ----

 compared to this:

 ----
 const B* cb = ...;
 B* b = cast(B*) cb;
 ----
Both are quite unsafe. As you know modifying const data in D causes bugs. The second is more bug-prone because you have to state the type again, so it's not DRY. Bye, bearophile
Jun 13 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
Thank you.
Jun 14 2013