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.

Reply via email to