how do I tell if something is lvalue?
Meta via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Jan 31 13:48:40 PST 2016
On Sunday, 31 January 2016 at 20:49:43 UTC, Steven Schveighoffer
wrote:
> struct S
> {
> int x;
> ref int y() { return x; }
> int z() { return 1; }
> }
>
> What can I use, given S, to determine that x and y yield
> lvalues, while z yields an rvalue?
>
> I was expecting something like isLvalue somewhere, but cannot
> find it.
>
> __traits(isRef, ...) doesn't work.
>
> -Steve
This seems to do the trick, although I haven't extensively tested
it. There's probably a simpler way but this is the first thing I
could come up with that works.
template yieldsLval(Aggregate, alias member)
{
import std.traits: ReturnType;
import std.functional: FunctionTypeOf;
import std.typetuple: staticIndexOf;
static if (isSomeFunction!member)
{
enum yieldsLval = __traits(compiles,
{
alias Ftype = FunctionTypeOf!member;
void takesLval(ref ReturnType!Ftype) {}
takesLval(Ftype());
});
}
//It's a member variable
else static if (staticIndexOf!(member.stringof,
FieldNameTuple!Aggregate) > -1)
enum yieldsLval = true;
else
static assert(false, "Symbol " ~ member.stringof ~ " is not a
member function or variable of " ~ Aggregate.stringof);
}
struct S
{
int x;
ref int y() { return x; }
int z() { return 1; }
enum f = 0;
}
void main()
{
static assert(yieldsLval!(S, S.y));
static assert(yieldsLval!(S, S.x));
static assert(!yieldsLval!(S, S.z));
static assert(!__traits(compiles, yieldsLval!(S, S.f)));
}
More information about the Digitalmars-d-learn
mailing list