hasDataMember and mixin inconsistency
Olivier Grant
olivier.grant at gmail.com
Sun Jan 27 07:22:26 PST 2013
On Sunday, 27 January 2013 at 12:58:39 UTC, Philippe Sigaud wrote:
>>> 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
> })";
> }
What is the purpose of "auto _ = t.D;" ?
> 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"))); // (1) - Fails
> assert(!mixin(hasDataMember!(int)("init"))); // (2) - Fails
>
> 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?
Using dmd 2.060 and command line "rdmd test.d", I get an
assertion fail on both calls that check for a member "init"
whether for int or Test.
More information about the Digitalmars-d-learn
mailing list