tail const
Simen kjaeraas
simen.kjaras at gmail.com
Fri Dec 3 04:03:32 PST 2010
Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> On 12/2/10 6:54 PM, Simen kjaeraas wrote:
>> Michel Fortin <michel.fortin at michelf.com> wrote:
>>
>>> I'm not sure I get the problem. Can you show me in code?
>>
>> const a = map!"a+a"( [1,2,3] );
>>
>> foreach ( e; a ) {
>> }
>>
>> The foreach fails because popFront is not const. What is needed is for
>> typeof(a) to be Map!("a+a", const(int)[]). IOW,
>> is( const(Map!("a+a", int[])) == Map!("a+a", const(int)[]) ).
>>
>> One possible way to do this is for all types T to have defined types
>> immutable_t and const_t, which by default alias to immutable(T) and
>> const(T), but can be defined to alias to other types. The compiler
>> would then automagically convert cast(const)T to cast(T.const_t)T.
>
> Well the code asks for a constant object, and I don't see it as
> reasonable for the type system to automagically infer the intent.
True. I believe I was thinking that T should be implicitly convertible
to T.const_t (or tailconst_t, as may be more appropriate).
What might be appropriate is a function tailconst( T )( T t ) that
returns a tail const version of the passed type. That is, given a
T[], const(T[]), const(T)[], immutable(T[]), or immutable(T)[], it
returns a const(T)[]. For a MyRange!R, const(MyRange!R), or
immutable(MyRange!R), it returns a MyRange!(R).tailconst_t. See bottom
of post for a (naïve) implementation.
> What should work is this:
>
> const(int)[] data = [1,2,3];
> auto a = map!"a+a"(data);
> foreach (e;a) {
> }
That does work.
import std.traits;
/**
* Return the tail-const type for a given type
**/
template TailConst( T ) {
static if ( is( T U : U[] ) ) {
alias const(Unqual!U)[] TailConst;
} else static if ( is( T U : U* ) ) {
alias const(Unqual!U)* TailConst;
} else static if ( is( T.tailconst_t ) ) {
alias T.tailconst_t TailConst;
} else static assert( false );
}
unittest {
struct test {
alias int tailconst_t;
}
assert( is( TailConst!( int[] ) == const(int)[] ) );
assert( is( TailConst!( immutable( int[] ) ) == const(int)[] ) );
assert( is( TailConst!( const(int)[] ) == const(int)[] ) );
assert( is( TailConst!test == int ) );
}
/**
* Converts the given parameter to tail const
**/
TailConst!T tailconst( T )( T t ) {
TailConst!T tmp = t;
return tmp;
}
unittest {
struct test( T ) {
alias test!(const T) tailconst_t;
this( const test!( Unqual!T ) t ) {}
}
assert( __traits( compiles, { tailconst( [1,2,3] ); } ) );
assert( __traits( compiles, { test!int t; tailconst( t ); } ) );
}
--
Simen
More information about the Digitalmars-d
mailing list