digitalmars.D.learn - Template mixins and selective imports
- jmh530 (44/44) Aug 03 2017 I am trying to create a vectorize function that mixes in a new
I am trying to create a vectorize function that mixes in a new version of function with the same name that applies the function (to an ndslice). The code below compiles without error and has the behavior I would expect. However, when I change the function import to a selective import (e.g. from import std.math; to import std.math : sin;), then I get errors implying that the overload is not actually created. Ideally, I would like to get this working with any kind of import. One thing I noticed is that the fullyQualifiedName of sin changes quite a bit depending on whether you use one or the other. This may be related to either of the following: https://issues.dlang.org/show_bug.cgi?id=16287 https://issues.dlang.org/show_bug.cgi?id=16023 ----------------------------------- import std.traits : isFunction; private enum _vectorize(string f) = " import mir.ndslice.slice : SliceKind, Slice; auto " ~ f ~ "(SliceKind kind, size_t[] packs, Iterator) (Slice!(kind, packs, Iterator) slice) { import mir.ndslice.topology : map; return slice.map!(f); } "; mixin template vectorize(alias f) if (isFunction!f) { mixin(_vectorize!(__traits(identifier, f))); } unittest { import std.stdio : writeln; import mir.ndslice.slice : sliced; import mir.ndslice.topology : map; import std.math; //import std.math : sin; auto x = [0.0, 1.0, 2.0, 3.0].sliced; auto y = x.map!(sin); writeln(y); mixin vectorize!(sin); auto z = sin(x); writeln(z); }
Aug 03 2017
On Thursday, 3 August 2017 at 15:29:47 UTC, jmh530 wrote:I am trying to create a vectorize function that mixes in a new version of function with the same name that applies the function (to an ndslice). The code below compiles without error and has the behavior I would expect. However, when I change the function import to a selective import (e.g. from import std.math; to import std.math : sin;), then I get errors implying that the overload is not actually created. Ideally, I would like to get this working with any kind of import. One thing I noticed is that the fullyQualifiedName of sin changes quite a bit depending on whether you use one or the other. This may be related to either of the following: https://issues.dlang.org/show_bug.cgi?id=16287 https://issues.dlang.org/show_bug.cgi?id=16023 ----------------------------------- import std.traits : isFunction; private enum _vectorize(string f) = " import mir.ndslice.slice : SliceKind, Slice; auto " ~ f ~ "(SliceKind kind, size_t[] packs, Iterator) (Slice!(kind, packs, Iterator) slice) { import mir.ndslice.topology : map; return slice.map!(f); } "; mixin template vectorize(alias f) if (isFunction!f) { mixin(_vectorize!(__traits(identifier, f))); } unittest { import std.stdio : writeln; import mir.ndslice.slice : sliced; import mir.ndslice.topology : map; import std.math; //import std.math : sin; auto x = [0.0, 1.0, 2.0, 3.0].sliced; auto y = x.map!(sin); writeln(y); mixin vectorize!(sin); auto z = sin(x); writeln(z); }I'm not 100% certain, but I believe you have to bring the vectorized overload of sin into the overload set, so first try `mixin vectorize!sin vsin; alias sin = vsin;` and see if it works. https://dlang.org/spec/function.html#overload-sets
Aug 03 2017
On Thursday, 3 August 2017 at 19:03:55 UTC, Meta wrote:`mixin vectorize!sin vsin; alias sin = vsin;` and see if itShould be `alias sin = vsin.sin;`
Aug 03 2017
On Thursday, 3 August 2017 at 19:05:47 UTC, Meta wrote:On Thursday, 3 August 2017 at 19:03:55 UTC, Meta wrote:Thanks, this pointed me in the right direction. I got the line below working. mixin vectorize!sin temp; alias vsin = temp.sin; auto z = vsin(x); I couldn't give it the name of sin or the name of the identifier. This is a little ugly and would require the user to make the adjustment themselves. Below seems to work if the user doesn't import the relevant function, though it will still result in errors if they selectively import that function. I think the combination of the two will be sufficient. private enum _vectorizeAlt(string mod, string func) = " auto " ~ func ~ "(SliceKind kind, size_t[] packs, Iterator) (Slice!(kind, packs, Iterator) slice) { import mir.ndslice.topology : map; return slice.map!(" ~ mod ~ "." ~ func ~ "); } "; mixin template vectorizeAlt(string mod, string func) { mixin("static import " ~ mod ~ ";"); import mir.ndslice.slice : SliceKind, Slice; mixin(_vectorizeAlt!(mod, func)); } unittest { import std.stdio : writeln; import mir.ndslice.slice : sliced; import mir.ndslice.topology : map; auto x = [0.0, 1.0, 2.0, 3.0].sliced; mixin vectorizeAlt!("std.math", "sin"); auto y = sin(x); }`mixin vectorize!sin vsin; alias sin = vsin;` and see if itShould be `alias sin = vsin.sin;`
Aug 03 2017