hasDataMember and mixin inconsistency
Philippe Sigaud
philippe.sigaud at gmail.com
Sun Jan 27 04:51:52 PST 2013
>> I'd put the mixin externally:
>>
>> template hasDataMember( T, string M )
>> {
>> mixin("
>>
>> enum hasDataMember = __traits(
>> compiles,
>> ( ref T x, ref T y ){ x." ~ M ~ " = y." ~ M ~ "; }
>> );");
>> }
>
>
> I've just tried that and it unfortunately does not work, the same
> test case still fails.
? I'll find the files again, for I tested before posting.
>> Also, I suppose the Test inner struct is not visible from the
>> hasDataMember template. The template is instantiated where it's
>> declared, not where it's called. You could use a mixin template, I
>> guess.
>
>
> I'm not sure at all what you mean by that. I thought all symbols
> within a source file were visible irrespective of their order or
> scope? Also, the test failure is on the Test structure directly,
> not its inner structure A.
Test is inside main() { ... }. I guess it's not visible from the
module inner scope.
>> I'd use a string mixin, but then I was converted to string mixins a
>> few years ago :)
>>
>> string hasDataMember( T )(string M )
>> {
>> return " __traits(compiles, {
>> Test t;
>> auto _ = t.D; // reading t.M
>> t." ~ M ~ " = t." ~ M ~ "; // assign to t.M
>> })";
>> }
>>
>> using is a bit more noisy than your solution:
>> mixin(hadDataMember!(Test)("M"))
>
>
> I've tried that as well and it still fails on the same test case
> again.
?
Here is what I used before posting:
string hasDataMember( T )(string M )
{
return " __traits(compiles, {
Test t;
auto _ = t.D; // reading t.M
t." ~ M ~ " = t." ~ M ~ "; // assign to t.M
})";
}
void main()
{
struct Test
{
struct A { }
void B( ) { }
@property A C( ) const { return F; }
@property long D( ) const { return E; }
@property void D( long e ) { E = e; }
long E;
A F;
}
assert(!mixin(hasDataMember!(Test)("init")));
assert(!mixin(hasDataMember!(int)("init")));
assert(!mixin(hasDataMember!(Test)("init"))); // Passes
assert(!mixin(hasDataMember!(Test)("A")));
assert(!mixin(hasDataMember!(Test)("B")));
assert(!mixin(hasDataMember!(Test)("C")));
assert(mixin(hasDataMember!(Test)("D")));
assert(mixin(hasDataMember!(Test)("E")));
assert(mixin(hasDataMember!(Test)("F")));
}
It seems the right behaviour. Am I mistaken?
More information about the Digitalmars-d-learn
mailing list