digitalmars.D.learn - Aliasing current function template instance
- Jean-Louis Leroy (33/33) May 01 2020 Is it possible, inside a function template, to create an alias to
- Steven Schveighoffer (4/6) May 01 2020 This trick works. No idea who came up with it:
- Jean-Louis Leroy (24/30) May 01 2020 I think I get the idea. Alas it doesn't work inside a function
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (12/46) May 01 2020 This should work:
- Adam D. Ruppe (10/11) May 01 2020 There's an old rule, that I can't find in the spec anymore but
- Jean-Louis Leroy (3/14) May 01 2020 It looks like it does the trick. Thanks! Trying to add support
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?
May 01 2020
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
May 01 2020
On Friday, 1 May 2020 at 20:43:05 UTC, Steven Schveighoffer wrote:On 5/1/20 4:28 PM, Jean-Louis Leroy wrote: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`Something I have overlooked? Any ideas?This trick works. No idea who came up with it: alias thisFunction = __traits(parent, {}); -Steve
May 01 2020
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
May 01 2020
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(&foo))); 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.
May 01 2020
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:It looks like it does the trick. Thanks! Trying to add support for method templates to openmethods.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(&foo))); 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.
May 01 2020