Thread overview | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 03, 2016 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! |
October 03, 2016 Re: Challenge | ||||
---|---|---|---|---|
| ||||
On 3 October 2016 at 23:41, Manu <turkeyman@gmail.com> 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...)) ??
|
October 03, 2016 Re: Challenge | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | 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?
|
October 03, 2016 Re: Challenge | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | 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.
|
October 03, 2016 Re: Challenge | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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.
|
October 04, 2016 Re: Challenge | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On 3 October 2016 at 23:50, John Colvin via Digitalmars-d <digitalmars-d@puremagic.com> 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.
|
October 03, 2016 Re: Challenge | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | 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 ? |
October 04, 2016 Re: Challenge | ||||
---|---|---|---|---|
| ||||
On 3 October 2016 at 23:48, Manu <turkeyman@gmail.com> wrote:
> On 3 October 2016 at 23:41, Manu <turkeyman@gmail.com> 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;
}
|
October 03, 2016 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
|
October 03, 2016 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 |
Copyright © 1999-2021 by the D Language Foundation