Jump to page: 1 2 3
Thread overview
Re: Challenge
Oct 03, 2016
Manu
Oct 03, 2016
John Colvin
Oct 03, 2016
Dicebot
Oct 03, 2016
Manu
Oct 03, 2016
Dicebot
Oct 03, 2016
Kagamin
Oct 03, 2016
Manu
Oct 03, 2016
Manu
Oct 03, 2016
Jonathan M Davis
Oct 03, 2016
Jonathan M Davis
Oct 03, 2016
Jonathan M Davis
Oct 03, 2016
Jonathan M Davis
Oct 04, 2016
Manu
Oct 04, 2016
Jonathan M Davis
Oct 04, 2016
Manu
Oct 04, 2016
Jonathan M Davis
Oct 04, 2016
Manu
Oct 04, 2016
Manu
Oct 05, 2016
Manu
Oct 05, 2016
Jonathan M Davis
Oct 05, 2016
Daniel N
Oct 05, 2016
John Colvin
Oct 05, 2016
Jonathan M Davis
Oct 05, 2016
Manu
Oct 05, 2016
Jonathan M Davis
Oct 05, 2016
Manu
October 03, 2016
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
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
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
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
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
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
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
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
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
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

« First   ‹ Prev
1 2 3