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.