digitalmars.D.learn - how do I tell if something is lvalue?
- Steven Schveighoffer (11/11) Jan 31 2016 struct S
- Meta (42/54) Jan 31 2016 This seems to do the trick, although I haven't extensively tested
- Steven Schveighoffer (3/6) Jan 31 2016 Thanks! I was surprised this is not straightforward.
- Meta (3/14) Jan 31 2016 It seems to me like it would be a useful addition to __traits.
- Steven Schveighoffer (4/17) Feb 01 2016 Yeah, the compiler probably has this handy.
- Artur Skawina via Digitalmars-d-learn (3/4) Feb 01 2016 enum isLvalue(alias A) = is(typeof((ref _){}(A)));
- Meta (9/14) Feb 01 2016 That looks much nicer. It still needs work to properly handle
- Steven Schveighoffer (5/20) Feb 01 2016 Nice for the general case, but in my case, I don't need to worry about
- Artur Skawina via Digitalmars-d-learn (8/23) Feb 01 2016 Then it gets a bit long for a one-liner ;)
- Artur Skawina via Digitalmars-d-learn (5/11) Feb 01 2016 And it's of course wrong in case there is a zero-args ref-returning
- Meta (12/26) Feb 01 2016 Hmm, I think it can be simplified by replacing `A[0](A[1..$])`
- tsbockman (21/23) Feb 01 2016 For function return values, at least, you can do this:
- Steven Schveighoffer (6/29) Feb 01 2016 Thanks. In my case, I need to treat fields and properties that return by...
- tsbockman (39/42) Feb 01 2016 Like this?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/6) Jan 31 2016 There is hasLvalueElements() as well. Its implementation my be similar
- Meta (3/11) Jan 31 2016 Unfortunately it's almost exactly the same as what I did, except
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
Jan 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. -SteveThis 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))); }
Jan 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
Jan 31 2016
On Sunday, 31 January 2016 at 22:11:45 UTC, Steven Schveighoffer wrote:On 1/31/16 4:48 PM, Meta wrote:It seems to me like it would be a useful addition to __traits.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
Jan 31 2016
On 1/31/16 5:12 PM, Meta wrote:On Sunday, 31 January 2016 at 22:11:45 UTC, Steven Schveighoffer wrote:Yeah, the compiler probably has this handy. https://issues.dlang.org/show_bug.cgi?id=15634 -SteveOn 1/31/16 4:48 PM, Meta wrote:It seems to me like it would be a useful addition to __traits.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.
Feb 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
Feb 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: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));Thanks! I was surprised this is not straightforward.enum isLvalue(alias A) = is(typeof((ref _){}(A))); artur
Feb 01 2016
On 2/1/16 2:47 PM, Meta wrote:On Monday, 1 February 2016 at 18:28:05 UTC, Artur Skawina wrote:Nice for the general case, but in my case, I don't need to worry about parameters. Thanks! -SteveOn 01/31/16 23:11, Steven Schveighoffer via Digitalmars-d-learn wrote: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));Thanks! I was surprised this is not straightforward.enum isLvalue(alias A) = is(typeof((ref _){}(A))); artur
Feb 01 2016
On 02/01/16 20:47, Meta via Digitalmars-d-learn wrote:On Monday, 1 February 2016 at 18:28:05 UTC, Artur Skawina wrote:Then it gets a bit long for a one-liner ;) enum isLvalue(A...) = is(typeof((ref _){}(A[0](A[1..$])))) || is(typeof((ref _){}(A[0])));On 01/31/16 23:11, Steven Schveighoffer via Digitalmars-d-learn wrote:That looks much nicer. It still needs work to properly handle functions with non-empty argument lists.Thanks! I was surprised this is not straightforward.enum isLvalue(alias A) = is(typeof((ref _){}(A)));Also, can alias parameters take runtime variables? I can't remember.Yes.struct S { int w(int n) { return 1; }ref int wl(int n) { return x; }} static assert(isLvalue!(S.w));static assert(!isLvalue!(S.w, 1)); static assert(isLvalue!(S.wl, 1)); artur
Feb 01 2016
On 02/01/16 21:42, Artur Skawina wrote:On 02/01/16 20:47, Meta via Digitalmars-d-learn wrote:And it's of course wrong in case there is a zero-args ref-returning overload present. So... enum isLvalue(A...) = A.length>1?is(typeof((ref _){}(A[0](A[1..$])))):is(typeof((ref _){}(A[0]))); arturThat looks much nicer. It still needs work to properly handle functions with non-empty argument lists.Then it gets a bit long for a one-liner ;) enum isLvalue(A...) = is(typeof((ref _){}(A[0](A[1..$])))) || is(typeof((ref _){}(A[0])));
Feb 01 2016
On Monday, 1 February 2016 at 20:53:35 UTC, Artur Skawina wrote:On 02/01/16 21:42, Artur Skawina wrote:Hmm, I think it can be simplified by replacing `A[0](A[1..$])` with `A(Parameters!A.init)`. Then the whole thing becomes: enum isLvalue(alias A) = is(typeof((ref _) {} (A(Parameters!A.init)))); *However*, we then run into this problem: int n; ref int returnN(int, float, bool) { return n; } ref int returnN() { return n; } static assert(isLvalue!returnN); If I remember correctly this will just check the first returnN declaration.On 02/01/16 20:47, Meta via Digitalmars-d-learn wrote:And it's of course wrong in case there is a zero-args ref-returning overload present. So... enum isLvalue(A...) = A.length>1?is(typeof((ref _){}(A[0](A[1..$])))):is(typeof((ref _){}(A[0]))); arturThat looks much nicer. It still needs work to properly handle functions with non-empty argument lists.Then it gets a bit long for a one-liner ;) enum isLvalue(A...) = is(typeof((ref _){}(A[0](A[1..$])))) || is(typeof((ref _){}(A[0])));
Feb 01 2016
On Sunday, 31 January 2016 at 22:11:45 UTC, Steven Schveighoffer wrote:Thanks! I was surprised this is not straightforward. -SteveFor function return values, at least, you can do this: import std.traits, std.stdio; int foo() { return 0; } ref int bar() { static int x = 0; return x; } enum isRetByRef(alias func) = (functionAttributes!func & FunctionAttribute.ref_) != 0; void main() { writeln("foo: ", isRetByRef!foo); writeln("bar: ", isRetByRef!bar); } (DPaste: http://dpaste.dzfl.pl/2aa8d3553a12)
Feb 01 2016
On 2/1/16 5:20 PM, tsbockman wrote:On Sunday, 31 January 2016 at 22:11:45 UTC, Steven Schveighoffer wrote:Thanks. In my case, I need to treat fields and properties that return by ref the same way. What I wanted essentially was a template constraint that says "this type has a member named foo, and t.foo is an lvalue" -SteveThanks! I was surprised this is not straightforward. -SteveFor function return values, at least, you can do this: import std.traits, std.stdio; int foo() { return 0; } ref int bar() { static int x = 0; return x; } enum isRetByRef(alias func) = (functionAttributes!func & FunctionAttribute.ref_) != 0; void main() { writeln("foo: ", isRetByRef!foo); writeln("bar: ", isRetByRef!bar); } (DPaste: http://dpaste.dzfl.pl/2aa8d3553a12)
Feb 01 2016
On Monday, 1 February 2016 at 22:32:26 UTC, Steven Schveighoffer wrote:What I wanted essentially was a template constraint that says "this type has a member named foo, and t.foo is an lvalue" -SteveLike this? template hasLValProperty(T, string property) { enum hasLValProperty = __traits(compiles, function(ref T x) { void requireLVal(V)(ref V y) { } requireLVal(mixin("x." ~ property)); }); } struct Foo { int a; } struct Bar { int b() { return 0; } } struct Baz { ref int c() { static int _c; return _c; } } void test(T, string property)() { import std.stdio; write(T.stringof, ".", property, " is "); if(!hasLValProperty!(T, property)) write("NOT "); writeln("an lvalue"); } void main() { import std.stdio; test!(Foo, "a")(); test!(Foo, "b")(); test!(Bar, "a")(); test!(Bar, "b")(); test!(Baz, "c")(); } (DPaste: http://dpaste.dzfl.pl/5877cc17ffd2)
Feb 01 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
Jan 31 2016
On Monday, 1 February 2016 at 00:20:00 UTC, Ali Çehreli wrote:On 01/31/2016 01:48 PM, Meta wrote:Unfortunately it's almost exactly the same as what I did, except for front, back, etc. Looks like there is currently no easier way.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
Jan 31 2016