Jump to page: 1 2
Thread overview
how do I tell if something is lvalue?
Jan 31, 2016
Meta
Jan 31, 2016
Meta
Feb 01, 2016
Artur Skawina
Feb 01, 2016
Meta
Feb 01, 2016
Artur Skawina
Feb 01, 2016
Artur Skawina
Feb 01, 2016
Meta
Feb 01, 2016
tsbockman
Feb 02, 2016
tsbockman
Feb 01, 2016
Ali Çehreli
Feb 01, 2016
Meta
January 31, 2016
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
January 31, 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)));
}
January 31, 2016
On 1/31/16 4:48 PM, Meta wrote:

>
> 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.
>
>

Thanks! I was surprised this is not straightforward.

-Steve
January 31, 2016
On Sunday, 31 January 2016 at 22:11:45 UTC, Steven Schveighoffer wrote:
> On 1/31/16 4:48 PM, Meta wrote:
>
>>
>> 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.
>>
>>
>
> Thanks! I was surprised this is not straightforward.
>
> -Steve

It seems to me like it would be a useful addition to __traits.
January 31, 2016
On 01/31/2016 01:48 PM, Meta wrote:

> This seems to do the trick, although I haven't extensively tested it.


There is hasLvalueElements() as well. Its implementation my be similar or give other ideas:

  https://dlang.org/phobos/std_range_primitives.html#hasLvalueElements

Ali

February 01, 2016
On Monday, 1 February 2016 at 00:20:00 UTC, Ali Çehreli wrote:
> On 01/31/2016 01:48 PM, Meta wrote:
>
>> This seems to do the trick, although I haven't extensively tested it.
>
>
> There is hasLvalueElements() as well. Its implementation my be similar or give other ideas:
>
>   https://dlang.org/phobos/std_range_primitives.html#hasLvalueElements
>
> Ali

Unfortunately it's almost exactly the same as what I did, except for front, back, etc. Looks like there is currently no easier way.
February 01, 2016
On 1/31/16 5:12 PM, Meta wrote:
> On Sunday, 31 January 2016 at 22:11:45 UTC, Steven Schveighoffer wrote:
>> On 1/31/16 4:48 PM, Meta wrote:
>>
>>>
>>> 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.
>>>
>>>
>>
>> Thanks! I was surprised this is not straightforward.
>>
>
> It seems to me like it would be a useful addition to __traits.

Yeah, the compiler probably has this handy.

https://issues.dlang.org/show_bug.cgi?id=15634

-Steve
February 01, 2016
On 01/31/16 23:11, Steven Schveighoffer via Digitalmars-d-learn wrote:
> Thanks! I was surprised this is not straightforward.

   enum isLvalue(alias A) = is(typeof((ref _){}(A)));

artur
February 01, 2016
On Monday, 1 February 2016 at 18:28:05 UTC, Artur Skawina wrote:
> On 01/31/16 23:11, Steven Schveighoffer via Digitalmars-d-learn wrote:
>> Thanks! I was surprised this is not straightforward.
>
>    enum isLvalue(alias A) = is(typeof((ref _){}(A)));
>
> artur

That looks much nicer. It still needs work to properly handle functions with non-empty argument lists. Also, can alias parameters take runtime variables? I can't remember.

struct S
{
    int w(int n) { return 1; }
}

static assert(isLvalue!(S.w));
February 01, 2016
On 2/1/16 2:47 PM, Meta wrote:
> On Monday, 1 February 2016 at 18:28:05 UTC, Artur Skawina wrote:
>> On 01/31/16 23:11, Steven Schveighoffer via Digitalmars-d-learn wrote:
>>> Thanks! I was surprised this is not straightforward.
>>
>>    enum isLvalue(alias A) = is(typeof((ref _){}(A)));
>>
>> artur
>
> That looks much nicer. It still needs work to properly handle functions
> with non-empty argument lists. Also, can alias parameters take runtime
> variables? I can't remember.
>
> struct S
> {
>      int w(int n) { return 1; }
> }
>
> static assert(isLvalue!(S.w));

Nice for the general case, but in my case, I don't need to worry about parameters.

Thanks!

-Steve
« First   ‹ Prev
1 2