Re: Aliasing current function template instance

2020-05-01 Thread Jean-Louis Leroy via Digitalmars-d-learn

On Friday, 1 May 2020 at 21:05:17 UTC, Adam D. Ruppe wrote:

On Friday, 1 May 2020 at 20:28:58 UTC, Jean-Louis Leroy wrote:

Something I have overlooked? Any ideas?


There's an old rule, that I can't find in the spec anymore but 
I'm still pretty sure it is there, where taking the address of 
a template inside a template yields the current instantiation.


Then you can fetch the type of that and do some reflection off. 
So try this in your test rig:


   pragma(msg, Parameters!(typeof()));

This rule was in there to ease callbacks and recursive 
functions iirc but it can also work with you thanks to typeof 
turning the runtime address back into a compile time alias.


It looks like it does the trick. Thanks! Trying to add support 
for method templates to openmethods.




Re: Aliasing current function template instance

2020-05-01 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 1 May 2020 at 20:28:58 UTC, Jean-Louis Leroy wrote:

Something I have overlooked? Any ideas?


There's an old rule, that I can't find in the spec anymore but 
I'm still pretty sure it is there, where taking the address of a 
template inside a template yields the current instantiation.


Then you can fetch the type of that and do some reflection off. 
So try this in your test rig:


   pragma(msg, Parameters!(typeof()));

This rule was in there to ease callbacks and recursive functions 
iirc but it can also work with you thanks to typeof turning the 
runtime address back into a compile time alias.


Re: Aliasing current function template instance

2020-05-01 Thread Simen Kjærås via Digitalmars-d-learn

On Friday, 1 May 2020 at 20:28:58 UTC, Jean-Louis Leroy wrote:
Is it possible, inside a function template, to create an alias 
to the instantiated function? IOW the equivalent of 
__FUNCTION__, but yielding an alias?


The closest I came is:

  import std.string;
  import std.traits;

  void foo(T)(lazy T)
  {
mixin(
  "alias thisFunction = ",
  __FUNCTION__[0..__FUNCTION__.lastIndexOf('.')],
  ";");
pragma(msg, Parameters!thisFunction);
  }

  void main()
  {
foo(0);
foo("");
  }

  dmd -c aliasthisfunction.d
  (lazy int)
  (lazy string)

...but (unsurprisingly) this fails in presence of overloads. 
I.e. if I throw in:


  void foo(T)(int, T);

...then I get:

  aliasthisfunction.d(6): Error: template 
`aliasthisfunction.foo` matches more than one template 
declaration:

  aliasthisfunction.d(4): `foo(T)(lazy T)`
  and
  aliasthisfunction.d(20): `foo(T)(int, T)`
  ...

Something I have overlooked? Any ideas?


This should work:

alias context(alias a) = __traits(parent, a);

void fun() {
alias ctx = context!({})();
}

{} becomes a lambda inside fun(), so it's parent is fun(). The 
same could be done by introducing a symbol explicitly, but that 
pollutes the namespace. This template works inside functions, 
methods, lambdas, modules, structs, classes and interfaces.


--
  Simen


Re: Aliasing current function template instance

2020-05-01 Thread Jean-Louis Leroy via Digitalmars-d-learn

On Friday, 1 May 2020 at 20:43:05 UTC, Steven Schveighoffer wrote:

On 5/1/20 4:28 PM, Jean-Louis Leroy wrote:


Something I have overlooked? Any ideas?



This trick works. No idea who came up with it:

alias thisFunction = __traits(parent, {});

-Steve


I think I get the idea. Alas it doesn't work inside a function 
template, because it returns the template, not the instance:


 void foo(T)(lazy T)
 {
   alias thisFunction = __traits(parent, {});
   pragma(msg, thisFunction.stringof);
   //pragma(msg, Parameters!thisFunction); // later
 }

 void main()
 {
   foo(0);
   foo("");
 }

prints:

  foo(T)(lazy T)
  foo(T)(lazy T)

Uncommenting the line that is (more or less) my real goal:

aliasthisfunction.d(7): Error: template instance 
`std.traits.Parameters!(foo)` does not match template declaration 
`Parameters(func...)`

  with `func = (foo(T)(lazy T))`
  must satisfy the following constraint:
`   isCallable!func`



Re: Aliasing current function template instance

2020-05-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/1/20 4:28 PM, Jean-Louis Leroy wrote:


Something I have overlooked? Any ideas?



This trick works. No idea who came up with it:

alias thisFunction = __traits(parent, {});

-Steve


Aliasing current function template instance

2020-05-01 Thread Jean-Louis Leroy via Digitalmars-d-learn
Is it possible, inside a function template, to create an alias to 
the instantiated function? IOW the equivalent of __FUNCTION__, 
but yielding an alias?


The closest I came is:

  import std.string;
  import std.traits;

  void foo(T)(lazy T)
  {
mixin(
  "alias thisFunction = ",
  __FUNCTION__[0..__FUNCTION__.lastIndexOf('.')],
  ";");
pragma(msg, Parameters!thisFunction);
  }

  void main()
  {
foo(0);
foo("");
  }

  dmd -c aliasthisfunction.d
  (lazy int)
  (lazy string)

...but (unsurprisingly) this fails in presence of overloads. I.e. 
if I throw in:


  void foo(T)(int, T);

...then I get:

  aliasthisfunction.d(6): Error: template `aliasthisfunction.foo` 
matches more than one template declaration:

  aliasthisfunction.d(4): `foo(T)(lazy T)`
  and
  aliasthisfunction.d(20): `foo(T)(int, T)`
  ...

Something I have overlooked? Any ideas?