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