Re: Cannot access template name from within template
On 2016-10-04 04:22, Michael Coulombe wrote: You can also just do something like this, to search the upper/global scope: alias A = SomethingCool!(.MyStruct); Doesn't work for nested templates. -- /Jacob Carlborg
Re: Challenge
On 4 October 2016 at 14:40, Jonathan M Davis via Digitalmars-d wrote: > [...] > For that matter, even testing whether something is a variable is > surprisingly difficult. True story! I've written that one before... I spent ages trying to get it right! When people say D is highly complex, these are the reasons. There are a lot of edges, and some arbitrary corners where things just don't work. *mutter mutter* storage class *mutter mutter*
Re: Challenge
On Tuesday, October 04, 2016 14:24:59 Manu via Digitalmars-d wrote: > On 4 October 2016 at 12:30, Jonathan M Davis via Digitalmars-d > > wrote: > > On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote: > >> I'm feeling John's solution is a little bit simpler. But nice work, > >> thanks! > > > > So, it is. LOL. I'd actually glanced over that post while I was in the > > middle of getting my version to work, and I read it too quickly, because I > > understood that it had just solved the property problem and that it didn't > > work for all cases. I'll have to update my PR. Though his code does make > > the mistake of doing > > > > mixin(`alias mem = T.` ~ member ~ `;`); > > > > rather than doing something like > > > > alias mem = AliasSeq!(__traits(getMember, T, member))[0]; > > > > which means that there are some cases where it won't work properly. The > > core logic is simpler though, which is definitely a plus. > > Make that change in your PR :) I already updated it and was actually able to make it slightly simpler than John's example (as far as I can tell, FunctionTypeOf is only needed in the case where the address is taken). > I think the PR is important. It's not obvious how to do this, and it's > very useful. I was astonished it's not already there. Yeah. I ran into a need for something similar recently, but my implementation at the time wasn't as thorough, since it just used offsetof to do the check (though in my case, I think that was enough). Getting it completely right is surprisingly difficult. I was also surprised that while we have quite a few __traits for functions, they're severely lacking for variables (e.g. I was looking for the variable equivalent of __traits(isStaticFunction, ...), and there is no such beast). For that matter, even testing whether something is a variable is surprisingly difficult. - Jonathan M Davis
Re: Challenge
On 4 October 2016 at 12:30, Jonathan M Davis via Digitalmars-d wrote: > On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote: >> I'm feeling John's solution is a little bit simpler. But nice work, thanks! > > So, it is. LOL. I'd actually glanced over that post while I was in the > middle of getting my version to work, and I read it too quickly, because I > understood that it had just solved the property problem and that it didn't > work for all cases. I'll have to update my PR. Though his code does make the > mistake of doing > > mixin(`alias mem = T.` ~ member ~ `;`); > > rather than doing something like > > alias mem = AliasSeq!(__traits(getMember, T, member))[0]; > > which means that there are some cases where it won't work properly. The core > logic is simpler though, which is definitely a plus. Make that change in your PR :) I think the PR is important. It's not obvious how to do this, and it's very useful. I was astonished it's not already there.
Re: Challenge
On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote: > I'm feeling John's solution is a little bit simpler. But nice work, thanks! So, it is. LOL. I'd actually glanced over that post while I was in the middle of getting my version to work, and I read it too quickly, because I understood that it had just solved the property problem and that it didn't work for all cases. I'll have to update my PR. Though his code does make the mistake of doing mixin(`alias mem = T.` ~ member ~ `;`); rather than doing something like alias mem = AliasSeq!(__traits(getMember, T, member))[0]; which means that there are some cases where it won't work properly. The core logic is simpler though, which is definitely a plus. - Jonathan M Davis
Re: Cannot access template name from within template
On Tuesday, 4 October 2016 at 00:40:08 UTC, Andrei Alexandrescu wrote: On 10/03/2016 06:32 PM, Stefan Koch wrote: On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu wrote: Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei try defining an alias to template name outside of the template and use that. No guarantees. Using std.traits.TemplateOf!MyStruct works like a charm. -- Andrei You can also just do something like this, to search the upper/global scope: alias A = SomethingCool!(.MyStruct);
Re: debugging mixins
On Tuesday, 4 October 2016 at 01:20:01 UTC, Manu wrote: On 4 October 2016 at 04:21, Stefan Koch via Digitalmars-d wrote: On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote: Yes, having the mixins expanded without the surrounding code would make it difficult to debug in some cases. Maybe generating the entire source with the expanded mixins is another option? mycode.d obj/mycode_processed.d That was my intention. Maybe this idea could also be expanded to template instantiation? Oh yes. it is not that more much work :) What case of template instantiation where there are no mixins involved would this make significantly simpler to debug? (I don't know this is a critical debugability problem as it is...) Do you mean just substituting 'T' with actual types? resolving static if's? Hard to know what it should do... Actually, one case that often bites me is static-foreach unrolling. That's borderline impossible to debug. foreach(m; __traits(allMembers,T)) is the classic impossible to debug case. static ifs are resolved when the compiler sees the template-instance in semantic3. And that makes a huge difference in some cases where a template is generated by a string-mixin for example. is not that big of a deal to print out unrolled static foreach. (as in I can implement in the compiler within 2 days)
Re: debugging mixins
On 4 October 2016 at 04:21, Stefan Koch via Digitalmars-d wrote: > On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote: > >> >> Yes, having the mixins expanded without the surrounding code would make it >> difficult to debug in some cases. Maybe generating the entire source with >> the expanded mixins is another option? >> >> mycode.d >> obj/mycode_processed.d > > That was my intention. >> >> Maybe this idea could also be expanded to template instantiation? > > Oh yes. it is not that more much work :) What case of template instantiation where there are no mixins involved would this make significantly simpler to debug? (I don't know this is a critical debugability problem as it is...) Do you mean just substituting 'T' with actual types? resolving static if's? Hard to know what it should do... Actually, one case that often bites me is static-foreach unrolling. That's borderline impossible to debug. foreach(m; __traits(allMembers,T)) is the classic impossible to debug case.
Re: inout delegate
On 4 October 2016 at 10:50, Timon Gehr via Digitalmars-d wrote: > On 03.10.2016 05:06, Manu via Digitalmars-d wrote: >> >> Okay, well my current project is blocked on this. I can't progress. >> https://issues.dlang.org/show_bug.cgi?id=16572 > > > Probably you can work around the issue using unsafe type casts. Mmm, I'll see how much work it is to detect the case to do such a cast...
Re: Challenge
On 4 October 2016 at 05:01, Jonathan M Davis via Digitalmars-d wrote: > On Monday, October 03, 2016 11:13:52 Jonathan M Davis via Digitalmars-d wrote: >> template isStaticMember(T, string member) >> { >> static if (!__traits(hasMember, T, member)) >> enum bool isStaticMember = false; >> else >> { >> import std.meta : AliasSeq; >> import std.traits : FunctionTypeOf; >> alias sym = AliasSeq!(__traits(getMember, T, member))[0]; >> >> static if (__traits(isStaticFunction, sym)) >> enum bool isStaticMember = true; >> else static if (is(FunctionTypeOf!sym == function) && >> is(FunctionTypeOf!(typeof(&sym)) == function)) >> { >> enum bool isStaticMember = false; >> } >> else >> { >> enum bool isStaticMember = !__traits(compiles, sym.offsetof) && >>__traits(compiles, &sym); >> } >> } >> } > > Well, since I took the time to write it, I created a PR for it: > > https://github.com/dlang/phobos/pull/4834 > > So, if anyone sees problems with my implementation, go poke holes in it. > > - Jonathan M Davis > I'm feeling John's solution is a little bit simpler. But nice work, thanks!
Re: Challenge
On 4 October 2016 at 00:25, John Colvin via Digitalmars-d wrote: > On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: >> >> Fill in the blank... >> I'm having a really hard time with this. I've made it work with a >> mountain of code, and I want to see what others come up with... > > > template isStaticMember(T, string member) > { > mixin(`alias mem = T.` ~ member ~ `;`); > import std.traits : FunctionTypeOf; > static if (is(FunctionTypeOf!mem == function) && > is(FunctionTypeOf!(typeof(&mem)) == function)) > enum bool isStaticMember = __traits(isStaticFunction, mem); > else > enum bool isStaticMember = is(typeof(&mem)); > } > > Basically, using FunctionTypeOf catches @property functions (which just > typeof wouldn't), but it also catches member variables with function types, > so we need the second FunctionTypeOf to see if it's still a function when > you take its address (true for member functions, including @property > functions, not true for member variables with function types). > > Everything else is just "can you take the address of this". Very nice. This is the quality of solution I was looking for! 3 Significant LOC. I knew a simple solution must exist. I didn't think of FunctionTypeOf.
Re: inout delegate
On 03.10.2016 05:06, Manu via Digitalmars-d wrote: Okay, well my current project is blocked on this. I can't progress. https://issues.dlang.org/show_bug.cgi?id=16572 Probably you can work around the issue using unsafe type casts.
Re: Cannot access template name from within template
On 10/03/2016 06:32 PM, Stefan Koch wrote: On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu wrote: Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei try defining an alias to template name outside of the template and use that. No guarantees. Using std.traits.TemplateOf!MyStruct works like a charm. -- Andrei
Re: Cannot access template name from within template
On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu wrote: Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei try defining an alias to template name outside of the template and use that. No guarantees.
Cannot access template name from within template
Consider: template SomethingCool(alias X) { alias Y = X!int; } struct MyStruct(T) { alias A = SomethingCool!MyStruct; } Inside MyStruct though, a mention of the symbol MyStruct alone is actually the current instantiation - i.e. a type, not a template. Any known workaround? Thanks, Andrei
Re: Challenge
On Monday, October 03, 2016 11:13:52 Jonathan M Davis via Digitalmars-d wrote: > template isStaticMember(T, string member) > { > static if (!__traits(hasMember, T, member)) > enum bool isStaticMember = false; > else > { > import std.meta : AliasSeq; > import std.traits : FunctionTypeOf; > alias sym = AliasSeq!(__traits(getMember, T, member))[0]; > > static if (__traits(isStaticFunction, sym)) > enum bool isStaticMember = true; > else static if (is(FunctionTypeOf!sym == function) && > is(FunctionTypeOf!(typeof(&sym)) == function)) > { > enum bool isStaticMember = false; > } > else > { > enum bool isStaticMember = !__traits(compiles, sym.offsetof) && >__traits(compiles, &sym); > } > } > } Well, since I took the time to write it, I created a PR for it: https://github.com/dlang/phobos/pull/4834 So, if anyone sees problems with my implementation, go poke holes in it. - Jonathan M Davis
Re: debugging mixins
On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote: Yes, having the mixins expanded without the surrounding code would make it difficult to debug in some cases. Maybe generating the entire source with the expanded mixins is another option? mycode.d obj/mycode_processed.d That was my intention. Maybe this idea could also be expanded to template instantiation? Oh yes. it is not that more much work :)
Re: Challenge
On 10/03/2016 07:41 AM, Seb wrote: On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Recommend, use latest DMD nightly. I find differences with latest nightly vs release. See also: http://stackoverflow.com/questions/39430684/check-if-class-member-is-static Appeared on dlang forum as well: :) http://forum.dlang.org/post/nni8lp$1ihk$1...@digitalmars.com Ali
Re: Challenge
On Monday, October 03, 2016 08:38:22 Jonathan M Davis via Digitalmars-d wrote: > On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote: > > Fill in the blank... > > I'm having a really hard time with this. I've made it work with a > > mountain of code, and I want to see what others come up with... > > It's certainly possible that this misses something, but it passes all of > your test cases: > > template isStaticMember(T, string member) > { > static if(!__traits(hasMember, T, member)) > enum bool isStaticMember = false; > else > { > import std.meta : AliasSeq; > import std.traits : FunctionTypeOf; > alias sym = AliasSeq!(__traits(getMember, T, member))[0]; > static if(__traits(isStaticFunction, sym)) > enum bool isStaticMember = true; > else static if(is(FunctionTypeOf!sym == function) && >is(FunctionTypeOf!(typeof(&sym)) == function)) > { > enum bool isStaticMember = false; > } > else > { > enum bool isStaticMember = !__traits(compiles, sym.offsetof) && >!is(sym == enum) && >!is(sym == class) && >!is(sym == struct) && >__traits(compiles, &sym); > } > } > } Actually, it can be reduced even further: template isStaticMember(T, string member) { static if (!__traits(hasMember, T, member)) enum bool isStaticMember = false; else { import std.meta : AliasSeq; import std.traits : FunctionTypeOf; alias sym = AliasSeq!(__traits(getMember, T, member))[0]; static if (__traits(isStaticFunction, sym)) enum bool isStaticMember = true; else static if (is(FunctionTypeOf!sym == function) && is(FunctionTypeOf!(typeof(&sym)) == function)) { enum bool isStaticMember = false; } else { enum bool isStaticMember = !__traits(compiles, sym.offsetof) && __traits(compiles, &sym); } } } Checking for the address makes it unnecessary to check for enums, classes, or structs. - Jonathan M Davis
Re: Pattern-matching qualifiers with is() expressions
On Monday, October 03, 2016 12:40:45 Andrei Alexandrescu via Digitalmars-d wrote: > Am I doing something wrong? This is a fairly basic match, I'm surprised > this hasn't surfaced yet: > > https://issues.dlang.org/show_bug.cgi?id=16581 My guess is that it hasn't been fined primarily because that version of an is expression probably isn't used all that often. And if the problem is qualifier-specific, then in order to hit the bug, someone would have to not only use that specific version of an is expression, but they'd have to be testing qualifiers with it as well. And I'd guess that that just isn't very common. Not to mention, even if some code did hit it, depending on what the it did, the bug might go unnoticed. - Jonathan M Davis
Pattern-matching qualifiers with is() expressions
Am I doing something wrong? This is a fairly basic match, I'm surprised this hasn't surfaced yet: https://issues.dlang.org/show_bug.cgi?id=16581 Andrei
Re: ndslice: feature deprecation voting / discussion
On Sunday, 2 October 2016 at 16:36:14 UTC, jmh530 wrote: Wouldn't it be more flexible to allow both ways? If D can handle the case without brackets without any issue, why force it? In Matlab, writing ones(2, 2) produces a 2x2 matrix of ones. In numpy, I would write np.ones((2, 2)) I find it annoying that in numpy I have to constantly remember to put in the second set of parentheses. This idea is basically forcing the same issue into ndslice. I think it's a bad idea. I feel the same way. +1 here
Re: Challenge
On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote: > Fill in the blank... > I'm having a really hard time with this. I've made it work with a > mountain of code, and I want to see what others come up with... It's certainly possible that this misses something, but it passes all of your test cases: template isStaticMember(T, string member) { static if(!__traits(hasMember, T, member)) enum bool isStaticMember = false; else { import std.meta : AliasSeq; import std.traits : FunctionTypeOf; alias sym = AliasSeq!(__traits(getMember, T, member))[0]; static if(__traits(isStaticFunction, sym)) enum bool isStaticMember = true; else static if(is(FunctionTypeOf!sym == function) && is(FunctionTypeOf!(typeof(&sym)) == function)) { enum bool isStaticMember = false; } else { enum bool isStaticMember = !__traits(compiles, sym.offsetof) && !is(sym == enum) && !is(sym == class) && !is(sym == struct) && __traits(compiles, &sym); } } } - Jonathan M Davis
Re: Challenge
On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote: > Fill in the blank... > I'm having a really hard time with this. I've made it work with a > mountain of code, and I want to see what others come up with... > > If you succeed, put it in std.traits! > > Recommend, use latest DMD nightly. I find differences with latest > nightly vs release. > > > --- template isStaticMember(T, string member) > { > enum bool isStaticMember = [code goes here]; > } > > > struct S > { > enum X = 10; > enum Y > { > i = 10 > } > struct S {} > class C {} > > static int x = 0; > __gshared int y = 0; > static void f() {} > static void f2() pure nothrow @nogc @safe {} > > shared void g() {} > > static void function() fp; > __gshared void function() gfp; > void function() fpm; > > void m() {} > final void m2() const pure nothrow @nogc @safe {} > > inout(int) iom() inout { return 10; } > static inout(int) iosf(inout int x) { return x; } > > @property int p() { return 10; } > static @property int sp() { return 10; } > } > > class C > { > enum X = 10; > enum Y > { > i = 10 > } > struct S {} > class C {} > > static int x = 0; > __gshared int y = 0; > static void f() {} > static void f2() pure nothrow @nogc @safe {} > > shared void g() {} > > static void function() fp; > __gshared void function() gfp; > void function() fpm; > > void m() {} > final void m2() const pure nothrow @nogc @safe {} > > inout(int) iom() inout { return 10; } > static inout(int) iosf(inout int x) { return x; } > > @property int p() { return 10; } > static @property int sp() { return 10; } > } > > static assert(!isStaticMember!(S, "X"), "!"); > static assert(!isStaticMember!(S, "Y"), "!"); > static assert(!isStaticMember!(S, "Y.i"), "!"); > static assert(!isStaticMember!(S, "S"), "!"); > static assert(!isStaticMember!(S, "C"), "!"); > static assert( isStaticMember!(S, "x"), "!"); > static assert( isStaticMember!(S, "y"), "!"); > static assert( isStaticMember!(S, "f"), "!"); > static assert( isStaticMember!(S, "f2"), "!"); > static assert(!isStaticMember!(S, "g"), "!"); > static assert( isStaticMember!(S, "fp"), "!"); > static assert( isStaticMember!(S, "gfp"), "!"); > static assert(!isStaticMember!(S, "fpm"), "!"); > static assert(!isStaticMember!(S, "m"), "!"); > static assert(!isStaticMember!(S, "m2"), "!"); > static assert(!isStaticMember!(S, "iom"), "!"); > static assert( isStaticMember!(S, "iosm"), "!"); > static assert(!isStaticMember!(S, "p"), "!"); > static assert( isStaticMember!(S, "sp"), "!"); > > static assert(!isStaticMember!(C, "X"), "!"); > static assert(!isStaticMember!(C, "Y"), "!"); > static assert(!isStaticMember!(C, "Y.i"), "!"); > static assert(!isStaticMember!(C, "S"), "!"); > static assert(!isStaticMember!(C, "C"), "!"); > static assert( isStaticMember!(C, "x"), "!"); > static assert( isStaticMember!(C, "y"), "!"); > static assert( isStaticMember!(C, "f"), "!"); > static assert( isStaticMember!(C, "f2"), "!"); > static assert(!isStaticMember!(C, "g"), "!"); > static assert( isStaticMember!(C, "fp"), "!"); > static assert( isStaticMember!(C, "gfp"), "!"); > static assert(!isStaticMember!(C, "fpm"), "!"); > static assert(!isStaticMember!(C, "m"), "!"); > static assert(!isStaticMember!(C, "m2"), "!"); > static assert(!isStaticMember!(C, "iom"), "!"); > static assert( isStaticMember!(C, "iosm"), "!"); > static assert(!isStaticMember!(C, "p"), "!"); > static assert( isStaticMember!(C, "sp"), "!"); I would point out that iosm is missing from both the struct and the class, so it can't be true for isStaticMember. I assume that you meant for it to be iosf, which _is_ declared? - Jonathan M Davis
Re: debugging mixins
On Sunday, 2 October 2016 at 03:36:31 UTC, Manu wrote: This comes up a lot. As far as I know, it's not solved. What shall we do? I feel like a simple solution would be to have the compiler emit a _mixin.d file populated with all the mixin expansions beside the .obj files, and have the debuginfo refer to that fabricated source file? It might look a little bit weird jumping into code where the surrounding scope is not visible (unless that were copied over too?), but it's better than what we have now. Are there any other commonly proposed solutions? Yes, having the mixins expanded without the surrounding code would make it difficult to debug in some cases. Maybe generating the entire source with the expanded mixins is another option? mycode.d obj/mycode_processed.d Maybe this idea could also be expanded to template instantiation?
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Recommend, use latest DMD nightly. I find differences with latest nightly vs release. See also: http://stackoverflow.com/questions/39430684/check-if-class-member-is-static
Re: Challenge
On 3 October 2016 at 23:48, Manu wrote: > On 3 October 2016 at 23:41, Manu wrote: >> I'm finding this rather annoying: >> >> struct S >> { >> static @property int p() { return 10; } >> } >> >> pragma(msg, typeof(&S.p)); // prints: int function() @property >> pragma(msg, is(typeof(&S.p) == function)); // prints: false >> >> It looks like a function... but I can't identify it as a function! > > I guess that should read: is(typeof(&S.p) == R function(A), R, A...)) ?? Here's a leg-up: template isStaticMember(T, string member) { mixin("alias M = T." ~ member ~ ";"); static if(__traits(compiles, &M)) { static if(!is(typeof(M) == function)) { static if(is(typeof(&M) == R function(A), R, A...)) { import std.traits : functionAttributes, FunctionAttribute; enum isStaticMember = (functionAttributes!M & FunctionAttribute.property) && /* distinguish static/non-static @property somehow */ */; } else enum isStaticMember = true; } else { enum isStaticMember = __traits(isStaticFunction, M); } } else enum isStaticMember = false; }
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... template isStaticMember(T, string member) { mixin(`alias mem = T.` ~ member ~ `;`); import std.traits : FunctionTypeOf; static if (is(FunctionTypeOf!mem == function) && is(FunctionTypeOf!(typeof(&mem)) == function)) enum bool isStaticMember = __traits(isStaticFunction, mem); else enum bool isStaticMember = is(typeof(&mem)); } Basically, using FunctionTypeOf catches @property functions (which just typeof wouldn't), but it also catches member variables with function types, so we need the second FunctionTypeOf to see if it's still a function when you take its address (true for member functions, including @property functions, not true for member variables with function types). Everything else is just "can you take the address of this".
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... [...] Dere's a typo static assert( isStaticMember!(S, "iosm"), "!"); Should be iosf Easy: template isStaticMember(T, string member) { static if(__traits(compiles, &__traits(getMember, T, member))) { static if(is(FunctionTypeOf!(__traits(getMember, T, member)) == function)) { enum isStaticMember = isFunctionPointer!(__traits(getMember, T, member)) || isDelegate!(__traits(getMember, T, member)) || __traits(isStaticFunction, __traits(getMember, T, member)); } else { enum isStaticMember = true;//!is(typeof(__traits(getMember, T, member).offsetof)); } } else { enum isStaticMember = false; } }
Re: Challenge
On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof(&S.p)); // prints: int function() @property pragma(msg, is(typeof(&S.p) == function)); // prints: false It looks like a function... but I can't identify it as a function! https://dlang.org/phobos/std_traits.html#isSomeFunction ?
Re: Challenge
On 3 October 2016 at 23:50, John Colvin via Digitalmars-d wrote: > On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: >> >> I'm finding this rather annoying: >> >> struct S >> { >> static @property int p() { return 10; } >> } >> >> pragma(msg, typeof(&S.p)); // prints: int function() @property >> pragma(msg, is(typeof(&S.p) == function)); // prints: false >> >> It looks like a function... but I can't identify it as a function! > > > The problem is that function pointers in "is" expressions don't match > "function" or "delegate". > > static assert (is(void delegate() == delegate)); //passes > static assert (is(void function() == function)); //fails > static assert (is(void function() == delegate)); //fails > > Bug report? Nar, I just forgot about this well-known edge. 'function' means something different in is(); it means a proper-function, *not* a function pointer. if(X == R function(A), R, A...) will test for function pointers. It's still hard though, @property's are hard to detect, and I am really struggling to distinguish between static and non-static properties without testing for assignments, which is terrible.
Re: Challenge
On Monday, 3 October 2016 at 13:50:26 UTC, John Colvin wrote: The problem is that function pointers in "is" expressions don't match "function" or "delegate". static assert (is(void delegate() == delegate)); //passes static assert (is(void function() == function)); //fails static assert (is(void function() == delegate)); //fails Bug report? Note that there is at least some code that relies on current behavior to distinguish delegate/function fields from method declarations in aggregates.
Re: Challenge
On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof(&S.p)); // prints: int function() @property pragma(msg, is(typeof(&S.p) == function)); // prints: false It looks like a function... but I can't identify it as a function! It works if both: a) you remove @property b) you don't convert it to function pointer struct S { static int p() { return 10; } } pragma(msg, is(typeof(S.p) == function); // true Sadly `is(X == function)` is very obscure and confusing because it doesn't do what one may expect it to do. In current form it can only be used if something is a function declaration, everything else is `false`. It is not even possible to manually express a type which will pass `is(T == function)`, you can only get `true` by applying `typeof` to existing function declaration. And @property screws it because the only current effect of property is exactly changing result of `typeof(propertyFoo)` from function type to result type.
Re: Challenge
On 3 October 2016 at 23:41, Manu wrote: > I'm finding this rather annoying: > > struct S > { > static @property int p() { return 10; } > } > > pragma(msg, typeof(&S.p)); // prints: int function() @property > pragma(msg, is(typeof(&S.p) == function)); // prints: false > > It looks like a function... but I can't identify it as a function! I guess that should read: is(typeof(&S.p) == R function(A), R, A...)) ??
Re: Challenge
On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote: I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof(&S.p)); // prints: int function() @property pragma(msg, is(typeof(&S.p) == function)); // prints: false It looks like a function... but I can't identify it as a function! The problem is that function pointers in "is" expressions don't match "function" or "delegate". static assert (is(void delegate() == delegate)); //passes static assert (is(void function() == function)); //fails static assert (is(void function() == delegate)); //fails Bug report?
Re: Challenge
On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote: Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Pretty easy: template isStaticMember(T, string member) { enum bool isStaticMember = !(member=="X" || member=="Y" || member=="Y.i" || member=="S" || member=="C" || member=="g" || member=="fpm" || member=="m" || member=="m2" || member=="iom" || member=="p"); } Ok, I'm joking.
Re: Challenge
I'm finding this rather annoying: struct S { static @property int p() { return 10; } } pragma(msg, typeof(&S.p)); // prints: int function() @property pragma(msg, is(typeof(&S.p) == function)); // prints: false It looks like a function... but I can't identify it as a function!
Challenge
Fill in the blank... I'm having a really hard time with this. I've made it work with a mountain of code, and I want to see what others come up with... If you succeed, put it in std.traits! Recommend, use latest DMD nightly. I find differences with latest nightly vs release. --- template isStaticMember(T, string member) { enum bool isStaticMember = [code goes here]; } struct S { enum X = 10; enum Y { i = 10 } struct S {} class C {} static int x = 0; __gshared int y = 0; static void f() {} static void f2() pure nothrow @nogc @safe {} shared void g() {} static void function() fp; __gshared void function() gfp; void function() fpm; void m() {} final void m2() const pure nothrow @nogc @safe {} inout(int) iom() inout { return 10; } static inout(int) iosf(inout int x) { return x; } @property int p() { return 10; } static @property int sp() { return 10; } } class C { enum X = 10; enum Y { i = 10 } struct S {} class C {} static int x = 0; __gshared int y = 0; static void f() {} static void f2() pure nothrow @nogc @safe {} shared void g() {} static void function() fp; __gshared void function() gfp; void function() fpm; void m() {} final void m2() const pure nothrow @nogc @safe {} inout(int) iom() inout { return 10; } static inout(int) iosf(inout int x) { return x; } @property int p() { return 10; } static @property int sp() { return 10; } } static assert(!isStaticMember!(S, "X"), "!"); static assert(!isStaticMember!(S, "Y"), "!"); static assert(!isStaticMember!(S, "Y.i"), "!"); static assert(!isStaticMember!(S, "S"), "!"); static assert(!isStaticMember!(S, "C"), "!"); static assert( isStaticMember!(S, "x"), "!"); static assert( isStaticMember!(S, "y"), "!"); static assert( isStaticMember!(S, "f"), "!"); static assert( isStaticMember!(S, "f2"), "!"); static assert(!isStaticMember!(S, "g"), "!"); static assert( isStaticMember!(S, "fp"), "!"); static assert( isStaticMember!(S, "gfp"), "!"); static assert(!isStaticMember!(S, "fpm"), "!"); static assert(!isStaticMember!(S, "m"), "!"); static assert(!isStaticMember!(S, "m2"), "!"); static assert(!isStaticMember!(S, "iom"), "!"); static assert( isStaticMember!(S, "iosm"), "!"); static assert(!isStaticMember!(S, "p"), "!"); static assert( isStaticMember!(S, "sp"), "!"); static assert(!isStaticMember!(C, "X"), "!"); static assert(!isStaticMember!(C, "Y"), "!"); static assert(!isStaticMember!(C, "Y.i"), "!"); static assert(!isStaticMember!(C, "S"), "!"); static assert(!isStaticMember!(C, "C"), "!"); static assert( isStaticMember!(C, "x"), "!"); static assert( isStaticMember!(C, "y"), "!"); static assert( isStaticMember!(C, "f"), "!"); static assert( isStaticMember!(C, "f2"), "!"); static assert(!isStaticMember!(C, "g"), "!"); static assert( isStaticMember!(C, "fp"), "!"); static assert( isStaticMember!(C, "gfp"), "!"); static assert(!isStaticMember!(C, "fpm"), "!"); static assert(!isStaticMember!(C, "m"), "!"); static assert(!isStaticMember!(C, "m2"), "!"); static assert(!isStaticMember!(C, "iom"), "!"); static assert( isStaticMember!(C, "iosm"), "!"); static assert(!isStaticMember!(C, "p"), "!"); static assert( isStaticMember!(C, "sp"), "!");
Re: debugging mixins
On 10/03/2016 07:42 AM, Stefan Koch wrote: On Sunday, 2 October 2016 at 12:27:23 UTC, Andrei Alexandrescu wrote: Yes, Stefan it would be terrific if you could keep an eye on it while working on the engine. A file with properly handed dependencies could serve as instantiation cache and save a ton of re-instantiation waste. Thanks! -- Andrei instantiation ? Do you mean mixin-expansion ? or are you talking about mixins created in templates ? Mixin expansions. Although Caching mixin expansions hits on the same problem as chaching template-instances, it is more difficult since a mixin can appear anywhere. and one has to worry about a much wider scope. I'll see what I can come up with, for now the debugging is priority. @Ethan can you share code illustrating your usecase. (My head is inside compiler internals and building test-code is a rather unpleasant context switch) Understood, then keep this on the back burner and forge ahead with the warm cache. Thanks! -- Andrei
Re: ndslice: feature deprecation voting / discussion
On 10/02/2016 11:01 PM, Manu via Digitalmars-d wrote: Ah, the 'sufficiently high-quality compiler' unicorn. It's been a legend in C++ for at least 20 years that I've been looking... For this particular matter it's somewhat of a solved problem in C++. Is it your perception as well that template bloat in C++ seems to have discussed a lot more in the past than in recent times? -- Andrei
Re: debugging mixins
On Monday, 3 October 2016 at 11:42:25 UTC, Stefan Koch wrote: @Ethan can you share code illustrating your usecase. (My head is inside compiler internals and building test-code is a rather unpleasant context switch) You should be able to do everything with the example code you have. My intention there is to compile everything in the acorelibrary module in to a library and statically link against that. As such, you'll want to do the .di generation on those files. The behaviour right now is that all the Binderoo mixins will not expand.
Re: debugging mixins
On Sunday, 2 October 2016 at 12:27:23 UTC, Andrei Alexandrescu wrote: Yes, Stefan it would be terrific if you could keep an eye on it while working on the engine. A file with properly handed dependencies could serve as instantiation cache and save a ton of re-instantiation waste. Thanks! -- Andrei instantiation ? Do you mean mixin-expansion ? or are you talking about mixins created in templates ? Although Caching mixin expansions hits on the same problem as chaching template-instances, it is more difficult since a mixin can appear anywhere. and one has to worry about a much wider scope. I'll see what I can come up with, for now the debugging is priority. @Ethan can you share code illustrating your usecase. (My head is inside compiler internals and building test-code is a rather unpleasant context switch)
Re: inout delegate
On Monday, 3 October 2016 at 02:47:09 UTC, Manu wrote: On 3 October 2016 at 02:37, Timon Gehr via Digitalmars-d This is a known issue: https://issues.dlang.org/show_bug.cgi?id=3720 (What I do is: typeof(&typeof(this).f) is int delegate(), but auto x = &f does not compile as the 'this' reference is missing.) It compiles for me... (using yesterday's nightly) I pasted it right from my code. It wouldn't compile using Timon's frontend, which was his point. — David
Re: inout delegate
On 3 October 2016 at 17:18, Jacob Carlborg via Digitalmars-d wrote: > On 2016-10-03 05:06, Manu via Digitalmars-d wrote: > >> Okay, well my current project is blocked on this. I can't progress. >> https://issues.dlang.org/show_bug.cgi?id=16572 > > > I You can remove "inout" ;) That just makes a different problem, ie, the one that requires it to be inout in the first place.
Re: inout delegate
On 2016-10-03 05:06, Manu via Digitalmars-d wrote: Okay, well my current project is blocked on this. I can't progress. https://issues.dlang.org/show_bug.cgi?id=16572 I You can remove "inout" ;) -- /Jacob Carlborg