Iterating over mixin template members
So, I've came to a situation where I must use mixin template for defining members overloads, like: ```d mixin template OverloadGen() { static if(hasMethod!(typeof(this), "add", int, int)) { float add(float x, float y){return x+y;} } static if(hasMethod!(typeof(this), "mul", int, int)) { float mul(float x, float y){return x*y;} } } ``` I know this example is obvious, but I'm using this for a far more complex, so I need that to work. The current way I tried to solve that was using string mixins such as: ```d enum mixOverloadGen() { return q{ mixin OverloadGen __ogen__; static foreach(mem; __traits(allMembers, __ogen__)) { mixin("alias ",mem," = __ogen__.",mem,";"); } }; } class Tester { int add(int, int){return 0;} mixin(mixOverloadGen); } ``` The problem doing that is that I can have access to `__ogen__`, which makes code like that valid: `tester.__ogen__.add`. I can't make `private mixin OverloadGen __ogen__`, because I won't be able to publicly access my overloads. And doing `static foreach(mem; mixin OverloadGen)` is also invalid, tried with allMembers, so, this is my current solution, the other thing I could do is instead of aliasing to the mixin members, I could make them private and declare a public function inside my string mixin which calls those, which is just wasteful: increase compile time, runtime usage and code complexity.
Re: mixin template bug with opBinary?
On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote: I get: ``` foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure nothrow @nogc @safe => a])` does not match template declaration `opBi(A, A function(A, A)[string] f0)` ``` Is this a bug or am I doing something wrong? Looks like this bug: https://issues.dlang.org/show_bug.cgi?id=22540
Re: mixin template bug with opBinary?
On Friday, 22 July 2022 at 12:56:44 UTC, Adam D Ruppe wrote: ``` mixin template opBi( alias f0 ) { static foreach (k, f; f0) { typeof(this) opBinary(string op: k)(typeof(this) r) { return f(this, r); } } } ``` Thanks, this seems to do the trick.
Re: mixin template bug with opBinary?
On 7/22/22 8:33 AM, Anthony Quizon wrote: Hello, I'm trying to create a mixin for quick binary operator overloads by passing in types with a corresponding associative array of strings to functions. However, the code I currently have: ``` module foo; mixin template opBi( A, A function(A, A)[string] f0, ) { static foreach (k, f; f0) { A opBinary(string op: k)(A r) { return f(this, r); } } } struct A { mixin opBi!( A, [ "+": (A a, A b) => a], ); } struct B { mixin opBi!( B, [ "+": (B a, B b) => a], ); } ``` Will not let me override operators on both struct A and B. I get: ``` foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure nothrow @nogc @safe => a])` does not match template declaration `opBi(A, A function(A, A)[string] f0)` ``` Is this a bug or am I doing something wrong? It's typing the AA differently, and therefore it doesn't fit. The type of the AA you are passing in is `T1[string]`, where it's expecting `T2[string]`, where: `T1` is `B function(B, B) pure nothrow @nogc @safe` `T2` is `B function(B, B)` I don't know if there's a better way to do this, other than use a further template parameter to match the function type passed in. -Steve
Re: mixin template bug with opBinary?
On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote: Is this a bug or am I doing something wrong? I think this is a bug. The compiler must not take well to this pattern, maybe the assoc array template argument, but idk. It looks like the first type used gets cached and reused even if it is supposed to change. I vaguely recall seeing this before but yeah smells buggy anyway. An alternative you might consider is dropping some of the type and using typeof(this): ``` module foo; mixin template opBi( alias f0 ) { static foreach (k, f; f0) { typeof(this) opBinary(string op: k)(typeof(this) r) { return f(this, r); } } } struct A { mixin opBi!( [ "+": (A a, A b) => a], ); } struct B { mixin opBi!( [ "+": (B a, B b) => a], ); } ``` That sidesteps the bug though it just trusts you pass the right type to `f0`.
mixin template bug with opBinary?
Hello, I'm trying to create a mixin for quick binary operator overloads by passing in types with a corresponding associative array of strings to functions. However, the code I currently have: ``` module foo; mixin template opBi( A, A function(A, A)[string] f0, ) { static foreach (k, f; f0) { A opBinary(string op: k)(A r) { return f(this, r); } } } struct A { mixin opBi!( A, [ "+": (A a, A b) => a], ); } struct B { mixin opBi!( B, [ "+": (B a, B b) => a], ); } ``` Will not let me override operators on both struct A and B. I get: ``` foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure nothrow @nogc @safe => a])` does not match template declaration `opBi(A, A function(A, A)[string] f0)` ``` Is this a bug or am I doing something wrong?
Re: mixin template
On 5/23/22 08:14, Vindex wrote: > Why? Why can't I have two constructors when I use mixin? And there is an example in Phobos: https://dlang.org/library/std/exception/basic_exception_ctors.html The documentation there mentions the following bug: https://issues.dlang.org/show_bug.cgi?id=11500 Ali
Re: mixin template
On Monday, 23 May 2022 at 15:14:53 UTC, Vindex wrote: I have this code: ``` import std.array, std.exception, std.stdio; mixin template RealizeException() { this(string msg, string file = __FILE__, size_t line = __LINE__) { super(msg, file, line); } } class WrongUsage : Exception { mixin RealizeException; this(string[] messages, string file = __FILE__, size_t line = __LINE__) { auto msg = std.array.join(messages, "\n"); super(msg, file, line); } } void main() { throw new WrongUsage("Error message."); } ``` ... and this error: ``` mixin_exception.d(19): Error: constructor `mixin_exception.WrongUsage.this(string[] messages, string file = __FILE__, ulong line = cast(ulong)__LINE__)` is not callable using argument types `(string)` mixin_exception.d(19):cannot pass argument `"Error message."` of type `string` to parameter `string[] messages` Failed: ["/usr/bin/dmd", "-v", "-o-", "mixin_exception.d", "-I."] ``` Why? Why can't I have two constructors when I use mixin? If I replace mixin to real code, I have no problem: ``` class WrongUsage : Exception { this(string msg, string file = __FILE__, size_t line = __LINE__) { super(msg, file, line); } this(string[] messages, string file = __FILE__, size_t line = __LINE__) { auto msg = std.array.join(messages, "\n"); super(msg, file, line); } } ``` mixin template create scope, for example if it was normal function (no ctor), you can do this: ```d mixin template RealizeException() { static void foo(string){} } class WrongUsage{ mixin RealizeException x; alias foo = x.foo; static void foo(string[]){} } void main() { WrongUsage.foo("Error message."); } ``` But for ctor this doesn't work...
mixin template
I have this code: ``` import std.array, std.exception, std.stdio; mixin template RealizeException() { this(string msg, string file = __FILE__, size_t line = __LINE__) { super(msg, file, line); } } class WrongUsage : Exception { mixin RealizeException; this(string[] messages, string file = __FILE__, size_t line = __LINE__) { auto msg = std.array.join(messages, "\n"); super(msg, file, line); } } void main() { throw new WrongUsage("Error message."); } ``` ... and this error: ``` mixin_exception.d(19): Error: constructor `mixin_exception.WrongUsage.this(string[] messages, string file = __FILE__, ulong line = cast(ulong)__LINE__)` is not callable using argument types `(string)` mixin_exception.d(19):cannot pass argument `"Error message."` of type `string` to parameter `string[] messages` Failed: ["/usr/bin/dmd", "-v", "-o-", "mixin_exception.d", "-I."] ``` Why? Why can't I have two constructors when I use mixin? If I replace mixin to real code, I have no problem: ``` class WrongUsage : Exception { this(string msg, string file = __FILE__, size_t line = __LINE__) { super(msg, file, line); } this(string[] messages, string file = __FILE__, size_t line = __LINE__) { auto msg = std.array.join(messages, "\n"); super(msg, file, line); } } ```
Re: template? mixin? template mixins? for modifying a struct setup
On Friday, 20 May 2022 at 14:54:31 UTC, Christopher Katko wrote: If the declarations are at module scope, `static` has no effect, and CTFE will be used for initialization. It won't use CTFE? Why is there a local module requirement? "module scope" just means at the top level in a module. so not inside a function.
Re: template? mixin? template mixins? for modifying a struct setup
On Friday, 20 May 2022 at 14:54:31 UTC, Christopher Katko wrote: So wait, that means if I have a module with extra stuff like D colors.d auto red = // grey and then in my other file D auto white = grey(1.0); It won't use CTFE? Why is there a local module requirement? I'm not sure what you mean by "local module requirement". The static storage class means that a variable will be around for the lifetime of the program (or more specifically in D's case, the lifetime of the thread). Module-scope variables are static by default.
Re: template? mixin? template mixins? for modifying a struct setup
On Friday, 20 May 2022 at 02:30:10 UTC, Mike Parker wrote: On Friday, 20 May 2022 at 00:12:44 UTC, Chris Katko wrote: Yeah that occurred to me as I was falling asleep. Though, do I have to a specify ```D static auto myColor = grey(0.5); ``` to ensure it's done at compile time? It's not the end of the world, but ideally, these are static / hardcoded values that can be used thousands of times a second. If the declarations are at module scope, `static` has no effect, and CTFE will be used for initialization. So wait, that means if I have a module with extra stuff like D colors.d auto red = // grey and then in my other file D auto white = grey(1.0); It won't use CTFE? Why is there a local module requirement?
Re: template? mixin? template mixins? for modifying a struct setup
On Friday, 20 May 2022 at 00:12:44 UTC, Chris Katko wrote: Yeah that occurred to me as I was falling asleep. Though, do I have to a specify ```D static auto myColor = grey(0.5); ``` to ensure it's done at compile time? It's not the end of the world, but ideally, these are static / hardcoded values that can be used thousands of times a second. If the declarations are at module scope, `static` has no effect, and CTFE will be used for initialization.
Re: template? mixin? template mixins? for modifying a struct setup
On 5/19/22 8:29 PM, Steven Schveighoffer wrote: Given a CTFE function it's very easy to wrap for ensuring compile-time usage: ```d enum ctGrey(float f) = grey(f); auto myColor = ctGrey!(0.5); ``` That being said, if it's calculatable at compile time, chances are the compiler is already going to do it, even for a standard constructor call, especially if there's no custom constructor. -Steve
Re: template? mixin? template mixins? for modifying a struct setup
On 5/19/22 8:12 PM, Chris Katko wrote: On Thursday, 19 May 2022 at 10:35:30 UTC, ag0aep6g wrote: On 19.05.22 12:15, Chris Katko wrote: given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ``` What's wrong with a simple plain function? COLOR grey(float rgb) { return COLOR(rgb, rgb, rgb, 1); } auto myColor = grey(0.5); Yeah that occurred to me as I was falling asleep. Though, do I have to a specify ```D static auto myColor = grey(0.5); ``` to ensure it's done at compile time? It's not the end of the world, but ideally, these are static / hardcoded values that can be used thousands of times a second. Given a CTFE function it's very easy to wrap for ensuring compile-time usage: ```d enum ctGrey(float f) = grey(f); auto myColor = ctGrey!(0.5); ``` -Steve
Re: template? mixin? template mixins? for modifying a struct setup
On Thursday, 19 May 2022 at 10:35:30 UTC, ag0aep6g wrote: On 19.05.22 12:15, Chris Katko wrote: given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ``` What's wrong with a simple plain function? COLOR grey(float rgb) { return COLOR(rgb, rgb, rgb, 1); } auto myColor = grey(0.5); Yeah that occurred to me as I was falling asleep. Though, do I have to a specify ```D static auto myColor = grey(0.5); ``` to ensure it's done at compile time? It's not the end of the world, but ideally, these are static / hardcoded values that can be used thousands of times a second.
Re: template? mixin? template mixins? for modifying a struct setup
On 19.05.22 12:15, Chris Katko wrote: given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ``` What's wrong with a simple plain function? COLOR grey(float rgb) { return COLOR(rgb, rgb, rgb, 1); } auto myColor = grey(0.5);
Re: template? mixin? template mixins? for modifying a struct setup
On Thursday, 19 May 2022 at 10:18:38 UTC, user1234 wrote: On Thursday, 19 May 2022 at 10:15:32 UTC, Chris Katko wrote: given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ``` average is a bad way to grayscale FYI ;) This is correct, you actually have to do something like this: ```d uint g = (uint)((0.3f * r) + (0.59f * g) + (0.11f * b)); ``` Where g is the new value for the current pixel's rgb value. However, OP doesn't seem to be grayscaling images, but rather just wanting to specify gray colors. In which case something like this could work: ```d COLOR GREY(float amount)() { return COLOR(amount, amount, amount, 1.0); } ... auto myColor = GREY!(0.5); myColor is COLOR(0.5, 0.5, 0.5, 1.0) ```
Re: template? mixin? template mixins? for modifying a struct setup
On Thursday, 19 May 2022 at 10:15:32 UTC, Chris Katko wrote: given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ``` average is a bad way to grayscale FYI ;)
template? mixin? template mixins? for modifying a struct setup
given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ```
Re: Mixin template overloads not working
On 12/7/21 1:03 PM, Q. Schroll wrote: On Tuesday, 7 December 2021 at 12:43:40 UTC, Rumbu wrote: Bug or feature? Feature. It even has a name: "overload set". It keeps you from accidentally calling a function you had no idea existed, for example because of a name clash. Not in this case. See this demonstration (I removed irrelevant pieces): ```d class S {} class A:S {} class Visitor { void visit(S s) {} void visit(A a) {} } class Derived : Visitor { } void main() { auto v = new Derived; v.visit(A.init); // calls visit(A) v.visit(S.init); // calls visit(S) } ``` Now, let's add a supposed "hiding" function: ```d class Derived : Visitor { override void visit(A a) {} } ``` Now, we have these 2 lines: ```d v.visit(A.init); // works, calls visit(A), just like before v.visit(S.init); // fails to compile, no overload for S. ``` Where is the hidden function? If you are thinking that just because it's not brought forth in the overload set, that's not important. Change the two visit parameters to string and int, and it compiles just fine: ```d class Visitor { void visit(string s) {} void visit(int a) {} } class Derived : Visitor { override void visit(int a) {} // no problem, even though we don't cover the string case } ``` NOW, if you did instead: ```d class Derived : Visitor { override void visit(S s) {} } ``` Now there is a hidden function, because visit(A.init) is going to call the derivative visit(S), whereas before it would call Visitor.visit(A). But that isn't this case. The spec says: "It is illegal if, through implicit conversions to the base class, those other functions do get called." The spec does not seem to cover this case, and the rules it states are not exactly what the compiler currently implements. I'm not sure where the bug is -- spec or implementation -- but there is a disagreement for sure. It's telling that making the S-accepting function final will fix the problem. -Steve
Re: Mixin template overloads not working
On Tuesday, 7 December 2021 at 12:43:40 UTC, Rumbu wrote: Bug or feature? Feature. It even has a name: "overload set". It keeps you from accidentally calling a function you had no idea existed, for example because of a name clash. Is there any workaround? Yes, the error message is very clear.
Re: Mixin template overloads not working
On 12/7/21 7:43 AM, Rumbu wrote: On Friday, 3 December 2021 at 10:57:34 UTC, Stanislav Blinov wrote: On Friday, 3 December 2021 at 10:42:37 UTC, Rumbu wrote: Bug or feature? Is there any workaround? The error message explains what to do :) Error: class `mixinover.AnotherVisitor` use of `mixinover.Visitor.visit(S s)` is hidden by `AnotherVisitor`; use `alias visit = Visitor.visit;` to introduce base class overload set Yes, I know, but in fact the compiler wrongly assumes that visit(A) is hiding visit(S). visit(A) is just an overload, it has a different signature than visit(S), theoretically the compiler must mangle it using a different name. It doesn't have to do with mangling. It has to do with implicit conversions. A more classic example would be: ```d class A { void foo(long i) {} void foo(int i) {} } class B : A { override void foo(long i) {} } ``` This hides A.foo(int), because B.foo(int) will call the long overload instead, when you might expect it to call the base class int overload. But I agree with you that this seems like a bug -- the anti-hidden overload error is supposed to complain when you have an implicitly convertible parameter. In this case, you aren't hiding visit(S) because visit(A) would not accept an S. The spec's explanation is pretty poor (and has invalid demo code to boot). -Steve
Re: Mixin template overloads not working
On Friday, 3 December 2021 at 10:57:34 UTC, Stanislav Blinov wrote: On Friday, 3 December 2021 at 10:42:37 UTC, Rumbu wrote: Bug or feature? Is there any workaround? The error message explains what to do :) Error: class `mixinover.AnotherVisitor` use of `mixinover.Visitor.visit(S s)` is hidden by `AnotherVisitor`; use `alias visit = Visitor.visit;` to introduce base class overload set Yes, I know, but in fact the compiler wrongly assumes that visit(A) is hiding visit(S). visit(A) is just an overload, it has a different signature than visit(S), theoretically the compiler must mangle it using a different name. Finally I solved it by "finalizing" visit(S), so it's not taken into overrides set. ```d class Visitor { final void visit(S s) {} //... }
Re: Mixin template overloads not working
On Friday, 3 December 2021 at 10:42:37 UTC, Rumbu wrote: Bug or feature? Is there any workaround? The error message explains what to do :) Error: class `mixinover.AnotherVisitor` use of `mixinover.Visitor.visit(S s)` is hidden by `AnotherVisitor`; use `alias visit = Visitor.visit;` to introduce base class overload set
Mixin template overloads not working
```d class S {} class A:S {} class B:S {} mixin template vmix(T) { void visit(T t) {} } class Visitor { void visit(S s) {} mixin vmix!A; mixin vmix!B; } class AnotherVisitor: Visitor { override void visit(A a) {} } ``` This will result in error when I try to override mixin generated visit(A) in AnotherVisitor. If A doesn't inherit S, the override in AnotherVisitor works like a charm. Bug or feature? Is there any workaround?
Re: How to translate this C macro to D mixin/template mixin?
On Wednesday, 16 June 2021 at 05:48:21 UTC, VitaliiY wrote: On Tuesday, 15 June 2021 at 12:39:40 UTC, Dennis wrote: On Tuesday, 15 June 2021 at 12:18:26 UTC, VitaliiY wrote: [...] ```D enum string ADDBITS(string a, string b) = ` { bitbuffer = (bitbuffer<<(`~a~`))|((`~b~`)&((1<<`~a~`)-1)); numbits += (`~a~`); mixin(STOREBITS); }`; // on use: ADDBITS(varA, varB) becomes mixin(ADDBITS!("varA", "varB")); ` [...] Thank you, Dennis. I tried with this kind of mixin, but a, b - are type of 'int so it's confusing to use them as mixin arguments. Use the [.stringof](https://dlang.org/spec/property.html#stringofhttps://dlang.org/spec/property.html#stringof) property. That should do it.
Re: How to translate this C macro to D mixin/template mixin?
On Tuesday, 15 June 2021 at 12:39:40 UTC, Dennis wrote: On Tuesday, 15 June 2021 at 12:18:26 UTC, VitaliiY wrote: [...] ```D enum string ADDBITS(string a, string b) = ` { bitbuffer = (bitbuffer<<(`~a~`))|((`~b~`)&((1<<`~a~`)-1)); numbits += (`~a~`); mixin(STOREBITS); }`; // on use: ADDBITS(varA, varB) becomes mixin(ADDBITS!("varA", "varB")); ` [...] Thank you, Dennis. I tried with this kind of mixin, but a, b - are type of 'int so it's confusing to use them as mixin arguments.
Re: How to translate this C macro to D mixin/template mixin?
On Tuesday, 15 June 2021 at 12:38:15 UTC, Ali Çehreli wrote: On 6/15/21 5:18 AM, VitaliiY wrote: > STOREBITS and ADDBITS use variables defined in STARTDATA If possible in your use case, I would put those variables in a struct type and make add() a member function. However, a similar type already exists as std.bitmanip.BitArray. Ali Thank you, Ali! Idea with member function seems interesting.
Re: How to translate this C macro to D mixin/template mixin?
On Tuesday, 15 June 2021 at 12:18:26 UTC, VitaliiY wrote: It's simple with STARTDATA as mixin, but STOREBITS and ADDBITS use variables defined in STARTDATA scope, so I can't understand how to do mixin template with it. If the code duplication isn't too bad, consider just expanding the C macros and translating that. I've noticed that some C programmers like to use complex macros just to save 10 lines. Otherwise, to make STOREBITS and ADDBITS access variables from STARTDATA, you can define them as inner functions. ```D void f() { size_t ressize=0; char* blockstart; int numbits; ulong bitbuffer=0; size_t size; void storeBits() { while(numbits >= 8) { if(!size) return 0; *(buffer++) = bitbuffer>>(numbits-8); numbits -= 8; ++ressize; --size; } } } ``` For the most literal translation, you can use a string mixin. You can't use a template mixin here since those can't insert code, only declarations. ```D enum string ADDBITS(string a, string b) = ` { bitbuffer = (bitbuffer<<(`~a~`))|((`~b~`)&((1<<`~a~`)-1)); numbits += (`~a~`); mixin(STOREBITS); }`; // on use: ADDBITS(varA, varB) becomes mixin(ADDBITS!("varA", "varB")); ```
Re: How to translate this C macro to D mixin/template mixin?
On 6/15/21 5:18 AM, VitaliiY wrote: > STOREBITS and ADDBITS use variables defined in STARTDATA If possible in your use case, I would put those variables in a struct type and make add() a member function. However, a similar type already exists as std.bitmanip.BitArray. Ali
How to translate this C macro to D mixin/template mixin?
Could anybody help with translation of this C macro to D mixin/mixin template? Here a - unsigned char, b - int. It's simple with STARTDATA as mixin, but STOREBITS and ADDBITS use variables defined in STARTDATA scope, so I can't understand how to do mixin template with it. #define STARTDATA \ size_t ressize=0; \ char *blockstart; \ int numbits; \ uint64_t bitbuffer=0; #define STOREBITS \ while(numbits >= 8) \ { \ if(!size) return 0; \ *(buffer++) = bitbuffer>>(numbits-8); \ numbits -= 8; \ ++ressize; \ --size; \ } #define ADDBITS(a, b) \ { \ bitbuffer = (bitbuffer<<(a))|((b)&((1<
Re: mixin template compile-time compute declared name
On Saturday, 27 June 2020 at 21:23:10 UTC, Adam D. Ruppe wrote: On Saturday, 27 June 2020 at 21:10:59 UTC, NonNull wrote: Is it possible to use a template to declare something whose name is computed at compile time? You'd have to string mixin the contents inside the mixin template. Worked! Thank you!!
Re: mixin template compile-time compute declared name
On Saturday, 27 June 2020 at 21:10:59 UTC, NonNull wrote: Is it possible to use a template to declare something whose name is computed at compile time? You'd have to string mixin the contents inside the mixin template.
mixin template compile-time compute declared name
Want mixin mytemplate!("foo", .); to be able to declare names dependent upon the text foo in the context it is used. For example declaring enum x_foo = ; blah foo_value = ; . . . . Is it possible to use a template to declare something whose name is computed at compile time?
Re: Difference between template and mixin template
On Thursday, 10 October 2019 at 15:56:36 UTC, Just Dave wrote: I'm trying to get my head around mixing templates. I'm using it as kind of a replacement for class inheritance as it seems to fit better composition over inheritance. So I do something like: mixin template NumberTemplate() { private: int number = 0; public: int getNumber(int number) { return number; } } interface INumber { getNumber(int number); } class Number : INumber { template NumberTemplate; }; So two questions: a) Is this correct usage? b) It compiles if I just do: template NumberTemplate() { private: int number = 0; public: int getNumber(int number) { return number; } } what is the difference between template and mixin template? Sorry I messed up the above code example the following should look like: class Number : INumber { mixin NumberTemplate; };
Difference between template and mixin template
I'm trying to get my head around mixing templates. I'm using it as kind of a replacement for class inheritance as it seems to fit better composition over inheritance. So I do something like: mixin template NumberTemplate() { private: int number = 0; public: int getNumber(int number) { return number; } } interface INumber { getNumber(int number); } class Number : INumber { template NumberTemplate; }; So two questions: a) Is this correct usage? b) It compiles if I just do: template NumberTemplate() { private: int number = 0; public: int getNumber(int number) { return number; } } what is the difference between template and mixin template?
Re: Inconsistent behavior of __FILE__ within mixin template
On Wednesday, 29 May 2019 at 16:08:11 UTC, Exil wrote: On Wednesday, 29 May 2019 at 08:45:45 UTC, Andre Pany wrote: [...] I imagine __FILE__ is used where the code is defined, since it is defined in "a.d" that is what is used. If you want to know the file name of where it is used then you can add it as part of the template. mixin template UnitTest(string filename = __FILE__) { private static this() { testClasses ~= TestClass(this.classinfo.name, filename ); } } Thanks a lot. That looks great. Kind regards Andre
Re: Inconsistent behavior of __FILE__ within mixin template
On Wednesday, 29 May 2019 at 08:45:45 UTC, Andre Pany wrote: Hi, I have a module a.d --- struct TestClass { string name; string fileName; } TestClass[] testClasses; mixin template UnitTest() { private static string getFileName(string fileName = __FILE__) { return fileName; } private static this() { testClasses ~= TestClass(this.classinfo.name, getFileName()); } } and a module b.d --- import std.stdio; import a; class MyTest { mixin UnitTest; this() { writeln(getFileName()); } } void main() { new MyTest(); writeln(testClasses); } What I want is to have in the struct array testClasses the file name of module b to generate an xml report. But the output of this application is b.d [TestClass("b.MyTest", "a.d")] I would have thought __FILE evaluates in both cases to "b.d" as the code is mixed into module b. Is this the intended behavior? Kind regards André I imagine __FILE__ is used where the code is defined, since it is defined in "a.d" that is what is used. If you want to know the file name of where it is used then you can add it as part of the template. mixin template UnitTest(string filename = __FILE__) { private static this() { testClasses ~= TestClass(this.classinfo.name, filename ); } }
Inconsistent behavior of __FILE__ within mixin template
Hi, I have a module a.d --- struct TestClass { string name; string fileName; } TestClass[] testClasses; mixin template UnitTest() { private static string getFileName(string fileName = __FILE__) { return fileName; } private static this() { testClasses ~= TestClass(this.classinfo.name, getFileName()); } } and a module b.d --- import std.stdio; import a; class MyTest { mixin UnitTest; this() { writeln(getFileName()); } } void main() { new MyTest(); writeln(testClasses); } What I want is to have in the struct array testClasses the file name of module b to generate an xml report. But the output of this application is b.d [TestClass("b.MyTest", "a.d")] I would have thought __FILE evaluates in both cases to "b.d" as the code is mixed into module b. Is this the intended behavior? Kind regards André
Re: Calling function explicitly from mixin template results in recursive call instead
On Monday, 10 December 2018 at 21:16:23 UTC, aliak wrote: Does this fix your issue? struct S { mixin operators ops; S opBinary(string op, T)(T a) { alias opBinary = ops.opBinary; // explicitly alias opBinary in this scope return opBinary!op(a); } } It does, thanks. Though I now have problems of the mixin scope not being able to access overloads of the instantiation scope... I'll just stick everything in the template since this is just an uphill battle.
Re: Calling function explicitly from mixin template results in recursive call instead
On Sunday, 9 December 2018 at 18:36:50 UTC, Dennis wrote: I'm using Adam's workaround from https://issues.dlang.org/show_bug.cgi?id=19365, but now I have endless recursion. Reduced code: ``` mixin template operators() { S opBinary(string op: "+")(S rhs) { return rhs; } // (A) auto opBinary(string op, T)(T rhs) if (false) { return rhs; } } struct S { mixin operators ops; S opBinary(string op, T)(T a) { return ops.opBinary!op(a); } } void main() { S.init.opBinary!"+"(S.init); } ``` Believe it or not, `ops.opBinary!op(a);` doesn't call anything from the mixin template ops, but it calls itself and it results in a stack overflow. I think this is a bug, but last time I was wrong, so maybe someone can explain what's going on here. I think the docs [0] are not as specific as they can be, but there's this part: "If the name of a declaration in a mixin is the same as a declaration in the surrounding scope, the surrounding declaration overrides the mixin one". Later on there's a section on disambiguating between conflicting symbols, but that sections feels wanting. Furthremore, this seems to work as expected: mixin template Foo() { void f() { writeln("Foo.f"); } } mixin Foo foo; void f() { writeln("f"); foo.f; } void main() { f; } I think I'd file this and see if someone complains. Does anyone know how to get this working? Does this fix your issue? struct S { mixin operators ops; S opBinary(string op, T)(T a) { alias opBinary = ops.opBinary; // explicitly alias opBinary in this scope return opBinary!op(a); } } Cheers, - Ali [0] https://dlang.org/spec/template-mixin.html#mixin_scope
Re: Calling function explicitly from mixin template results in recursive call instead
On Sunday, 9 December 2018 at 18:36:50 UTC, Dennis wrote: Does anyone know how to get this working? I added this to the mixin template: ``` alias mixinOpBinary = opBinary; ``` And called mixinOpBinary instead in the forwarded function. I think that solved it. I think I'll just file an issue for this.
Calling function explicitly from mixin template results in recursive call instead
I'm using Adam's workaround from https://issues.dlang.org/show_bug.cgi?id=19365, but now I have endless recursion. Reduced code: ``` mixin template operators() { S opBinary(string op: "+")(S rhs) { return rhs; } // (A) auto opBinary(string op, T)(T rhs) if (false) { return rhs; } } struct S { mixin operators ops; S opBinary(string op, T)(T a) { return ops.opBinary!op(a); } } void main() { S.init.opBinary!"+"(S.init); } ``` Believe it or not, `ops.opBinary!op(a);` doesn't call anything from the mixin template ops, but it calls itself and it results in a stack overflow. I think this is a bug, but last time I was wrong, so maybe someone can explain what's going on here. Note that after removing the opBinary at (A), it works. The idea behind it is that it converts the rhs to an S that opBinary!"+" takes. A less reduced version would be: ``` auto opBinary(string op, T)(T rhs) if (!is(T==S)) { return this.opBinary!op(S(rhs)); } ``` Does anyone know how to get this working?
Re: Can you get typeof(this) in a mixin template - trying to mimic a Kotlin feature here.
On Tuesday, 28 August 2018 at 20:58:23 UTC, Alex wrote: Isn't the problem, that inside a template a declaration is expected, and not a foreach? Boh, you're right. I guess I misunderstood mixin templates. Found a way with a normap function though :p void mapSelf(alias self, alias aa)() { ... } this(map) { mapSelf!(this, map); } https://run.dlang.io/is/EhDpOM
Re: Can you get typeof(this) in a mixin template - trying to mimic a Kotlin feature here.
On Tuesday, 28 August 2018 at 20:39:16 UTC, aliak wrote: Hi, I'm trying to do something similar to what Kotlin allows with assigning to member variables from a map. The syntax is very readable and looks like: class User(val map: Map) { val name: String by map val age: Int by map } So I'm trying to do something similar in D: mixin template MapMembers(alias aa) { foreach (name; typeof(this).tupleof) { // if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish } } struct User { this(Variant[string] aa) { mixin MapMembers!aa; } } Seems I can't do typeof(this) inside the mixin. One workaround is to explicitly pass the type "User" to the template mixin, but it feels like this is something that should work and I'm just unfamiliar with template mixins and their usage. Cheers, - Ali [0] https://kotlinlang.org/docs/reference/delegated-properties.html#storing-properties-in-a-map Isn't the problem, that inside a template a declaration is expected, and not a foreach? This works as expected: ´´´ import std.experimental.all; void main() { writeln("Edit source/app.d to start your project."); } mixin template MapMembers(alias aa) { typeof(this) var; /* foreach (name; typeof(this).tupleof) { // if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish } */ } struct User { this(Variant[string] aa) { mixin MapMembers!aa; } } //mixin MapMembers!(Variant[string].init); ´´´
Can you get typeof(this) in a mixin template - trying to mimic a Kotlin feature here.
Hi, I'm trying to do something similar to what Kotlin allows with assigning to member variables from a map. The syntax is very readable and looks like: class User(val map: Map) { val name: String by map val age: Int by map } So I'm trying to do something similar in D: mixin template MapMembers(alias aa) { foreach (name; typeof(this).tupleof) { // if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish } } struct User { this(Variant[string] aa) { mixin MapMembers!aa; } } Seems I can't do typeof(this) inside the mixin. One workaround is to explicitly pass the type "User" to the template mixin, but it feels like this is something that should work and I'm just unfamiliar with template mixins and their usage. Cheers, - Ali [0] https://kotlinlang.org/docs/reference/delegated-properties.html#storing-properties-in-a-map
Re: why mixin template can not inclulde statement;
try this: mixin template test(A...){ __gshared int a = A[0]; int dummy = (){ a++; return 0; }(); } import core.stdc.stdio; int main(){ mixin test!1; printf("a=%d\n", a); return 0; }
Re: why mixin template can not inclulde statement;
On Friday, 10 August 2018 at 13:17:13 UTC, learnfirst1 wrote: this work, it report no error but give a link problem. (this could be a bug ?) mixin template test(A...){ __gshared int a = A[0]; pragma(inline, true) // remove this will work static extern(C) int test(){ a++; return 0; } int dummy = test(); } import core.stdc.stdio; extern(C) void main(){ mixin test!1; printf("a=%d\n", a); } --- Undefined symbols for architecture x86_64: "__D4test4mainUZ8__mixin1QvUNbNiZi", referenced from: _main in test.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1
Re: why mixin template can not inclulde statement;
On Friday, 10 August 2018 at 13:10:57 UTC, Kagamin wrote: On Friday, 10 August 2018 at 13:01:21 UTC, learnfirst1 wrote: Looks like some problem with tuple, try __gshared a = A[0]; this work, it report no error but give a link problem. (this could be a bug ?)
Re: why mixin template can not inclulde statement;
On Friday, 10 August 2018 at 13:05:24 UTC, Kagamin wrote: Mixim template can only introduce declarations, not statements, a workaround is a lambda called in place. mixin template test(A...){ __gshared a = A; int dummy = (){ a++; return 0; }(); } extern(C) void main(){ mixin test!123; } Thanks, this work for me. my second example should be a dmd bug ? (ldc work)
Re: why mixin template can not inclulde statement;
On Friday, 10 August 2018 at 13:05:24 UTC, Kagamin wrote: Mixim template can only introduce declarations, not statements, a workaround is a lambda called in place. mixin template test(A...){ __gshared a = A; int dummy = (){ a++; return 0; }(); } extern(C) void main(){ mixin test!123; } Except that you can't use tuples for that, a working sample: mixin template test(alias A){ __gshared a = A; int dummy = (){ a++; return 0; }(); } extern(C) void main(){ mixin test!123; import core.stdc.stdio; printf("%d", a); }
Re: why mixin template can not inclulde statement;
On Friday, 10 August 2018 at 13:01:21 UTC, learnfirst1 wrote: duplicate symbol __D4test4mainUZ8__mixin111__a_field_0i in: test.o ld: 1 duplicate symbol for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1 this really make no sense, what is wrong with it?(same code build with ldc2) Looks like some problem with tuple, try __gshared a = A[0];
Re: why mixin template can not inclulde statement;
Mixim template can only introduce declarations, not statements, a workaround is a lambda called in place. mixin template test(A...){ __gshared a = A; int dummy = (){ a++; return 0; }(); } extern(C) void main(){ mixin test!123; }
Re: why mixin template can not inclulde statement;
On Friday, 10 August 2018 at 12:38:55 UTC, learnfirst1 wrote: mixin template test(A...){ mixin template test(A...){ __gshared a = A; } extern(C) void main(){ mixin test!123; } --- duplicate symbol __D4test4mainUZ8__mixin111__a_field_0i in: test.o ld: 1 duplicate symbol for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1 this really make no sense, what is wrong with it?(same code build with ldc2)
why mixin template can not inclulde statement;
mixin template test(A...){ __gshared a = A; a++; } extern(C) void main(){ mixin test!123; } - I dont want to use string mixin to intro a lot un want symbol, try with mixin template find this not work. I know if mixin test on global it should not working, but why not make the limit for function scope ? I try use D for a WASM project then find so much limitation with no good reason. or I missing some thing here ?
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 12:05:52 UTC, Simen Kjærås wrote: On Friday, 10 August 2018 at 11:17:10 UTC, learnfirst1 wrote: If you try the same without the mixin template, you'll see that it doesn't work: struct Test { extern(C) pragma(crt_constructor) static void init(){ // work int i = 3; } } void main(){ extern(C) pragma(crt_constructor) static void init(){ // not work int i = 3; } } -- It not work make no sense, since it can work on struct. I am not be able to search the related spec docs, only this link: https://dlang.org/blog/2018/01/04/dmd-2-078-0-has-been-released/ Based on my understand, nested static extern(C) function is all about visibility. It just like put private before it, there is really no reason to treat them in diff way.
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 11:17:10 UTC, learnfirst1 wrote: I think the static extern(C) nested function should just work like global extern(C) function. DMD still report missing symbols. Or I am wrong about this ? template G(){ static extern(C) pragma(crt_constructor) void init(){} } void main(){ mixin G!(); // Line 5 init(); } If you try the same without the mixin template, you'll see that it doesn't work: void main() { static extern(C) pragma(crt_constructor) void init(); init(); } Depending on the order of static, extern(C) and pragma(crt_constructor), you can get at least two different error messages, but either way - it doesn't work. It would be possible to make this work by changing the compiler, but according to spec, it shouldn't. -- Simen
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 10:24:55 UTC, Simen Kjærås wrote: On Friday, 10 August 2018 at 08:31:21 UTC, learnfirst1 wrote: Filed a bug: https://issues.dlang.org/show_bug.cgi?id=19153 template G(){ pragma(crt_constructor) static extern(C) void init(){} } void main(){ mixin G!(); // Line 5 init(); } same missing symbols.
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 10:24:55 UTC, Simen Kjærås wrote: On Friday, 10 August 2018 at 08:31:21 UTC, learnfirst1 wrote: The correct behavior would be for the compiler to show the latter error message for a mixin'd function as well. Filed a bug: https://issues.dlang.org/show_bug.cgi?id=19153 -- Simen I think the static extern(C) nested function should just work like global extern(C) function. DMD still report missing symbols. Or I am wrong about this ? template G(){ static extern(C) pragma(crt_constructor) void init(){} } void main(){ mixin G!(); // Line 5 init(); }
Re: is this a bug ? mixin template static function missing!
On Friday, 10 August 2018 at 08:31:21 UTC, learnfirst1 wrote: #!/usr/bin/env rdmd import core.stdc.stdio; template G(size_t line = __LINE__, A...){ int i = 3; static extern(C) pragma(crt_constructor) void init2(){ printf("init: %d\n", line); } } pragma(crt_constructor) extern(C) void init1(){ printf("init from global\n"); } struct A { mixin G!(); } extern(C) void main(){ mixin G!() g; printf("g.i=%d\n", g.i); g.init2(); // remove this can build, but g.init2 not get called! } - build error: Undefined symbols for architecture x86_64: "__D4test4mainUZ1g5init2UNbNiZv", referenced from: It is indeed. Reduced example: template G(){ extern(C) pragma(crt_constructor) void init(){} } void main(){ mixin G!(); init(); } For nested functions, extern(C) is simply ignored[0]. Since pragma(crt_constructor) requires that the symbol it's applied to uses C linkage (and an error message to that effect is shown if you write pragma(crt_constructor) void fun() {} in module scope: Error: function `fun` must be extern(C) for pragma(crt_constructor) In addition, if you try to apply pragma(crt_constructor) to a nested function, you get this error message, showing further that nested functions can't be crt_constructors: Error: unrecognized pragma(crt_constructor) The correct behavior would be for the compiler to show the latter error message for a mixin'd function as well. Filed a bug: https://issues.dlang.org/show_bug.cgi?id=19153 -- Simen [0]: from https://dlang.org/spec/attribute.html#linkage: Note that extern(C) can be provided for all types of declarations, including struct or class, even though there is no corresponding match on the C side. In that case, the attribute is ignored. This behavior applies for nested functions and nested variables as well.
is this a bug ? mixin template static function missing!
#!/usr/bin/env rdmd import core.stdc.stdio; template G(size_t line = __LINE__, A...){ int i = 3; static extern(C) pragma(crt_constructor) void init2(){ printf("init: %d\n", line); } } pragma(crt_constructor) extern(C) void init1(){ printf("init from global\n"); } struct A { mixin G!(); } extern(C) void main(){ mixin G!() g; printf("g.i=%d\n", g.i); g.init2(); // remove this can build, but g.init2 not get called! } - build error: Undefined symbols for architecture x86_64: "__D4test4mainUZ1g5init2UNbNiZv", referenced from:
Re: is this even possible? newbie + mixin template + foreach (allMembers)
On Tuesday, 3 April 2018 at 18:49:00 UTC, Carlos Navarro wrote: QUESTION: Obviously I'm no geting mixins/templates nor traits and I'm failing miserably to find/identify the right examples or documentation to help me tackle this thing. What is wrong in this code? is this pattern sintactically possible? what I'm getting wrong? [...] ICEs (compiler segfault) should _always_ be reported on Bugzilla. The compiler should never ever segfault - even on invalid code. I just did so for you: https://issues.dlang.org/show_bug.cgi?id=18718
Re: is this even possible? newbie + mixin template + foreach (allMembers)
On Tuesday, 3 April 2018 at 18:57:29 UTC, WebFreak001 wrote: you need to use a static foreach for this. You can insert a static foreach basically where you can insert a function definition like void foo() {} foreach is more like a function call like foo(), so you can't put it in the mixin template. A mixin template is basically expected to be mixin-able in global scope or in a class/struct so it can't have any things like function calls because that would be the same as writing `foo();` at global level instead of in the main function. static foreach on the other hand allows exactly that because it literally unrolls the contents and inserts it multiple times, so you can also put it in mixin templates if the content of the loop is valid in mixin templates. If you need to support older compilers you can use normal foreach with ctfe by generating a code string or do recursive templates, but I would really encourage you to use static foreach instead, it is cleaner and faster. I think, the OP has something other in mind. Look at this: ´´´ void main(){} struct World { floatrotation; bool active; //mixin BuildStuff!(); } mixin BuildStuff!(); mixin template BuildStuff() { static foreach(elem; __traits(allMembers, World)) { pragma(msg, elem); } } ´´´ While the outer mixin works as expected, the inner one results in a seg fault. No idea why, however, too...
Re: is this even possible? newbie + mixin template + foreach (allMembers)
On Tuesday, 3 April 2018 at 18:49:00 UTC, Carlos Navarro wrote: QUESTION: Obviously I'm no geting mixins/templates nor traits and I'm failing miserably to find/identify the right examples or documentation to help me tackle this thing. What is wrong in this code? is this pattern sintactically possible? what I'm getting wrong? CONTEXT: I'm a newbie trying to extend a struct using a mixin template like this one: struct World { floatrotation; bool active; mixin BuildStuff; } mixin template BuildStuff() { foreach(elem; __traits(allMembers, typeof(this))) { //pragma(msg, elem); } } //full example here: https://run.dlang.io/is/OeXS4j COMPILER OUTPUT: 2.067.1 to 2.071.2: Failure with output: - onlineapp.d(18): Error: declaration expected, not 'foreach' onlineapp.d(18): Error: declaration expected, not '__traits' onlineapp.d(22): Error: template member expected - 2.072.2 to 2.075.1: Failure with output: - onlineapp.d(18): Error: declaration expected, not 'foreach' onlineapp.d(18): Error: declaration expected, not '__traits' onlineapp.d(22): Error: matching '}' expected, not EOF - Since 2.076.1: Segfault and no output you need to use a static foreach for this. You can insert a static foreach basically where you can insert a function definition like void foo() {} foreach is more like a function call like foo(), so you can't put it in the mixin template. A mixin template is basically expected to be mixin-able in global scope or in a class/struct so it can't have any things like function calls because that would be the same as writing `foo();` at global level instead of in the main function. static foreach on the other hand allows exactly that because it literally unrolls the contents and inserts it multiple times, so you can also put it in mixin templates if the content of the loop is valid in mixin templates. If you need to support older compilers you can use normal foreach with ctfe by generating a code string or do recursive templates, but I would really encourage you to use static foreach instead, it is cleaner and faster.
is this even possible? newbie + mixin template + foreach (allMembers)
QUESTION: Obviously I'm no geting mixins/templates nor traits and I'm failing miserably to find/identify the right examples or documentation to help me tackle this thing. What is wrong in this code? is this pattern sintactically possible? what I'm getting wrong? CONTEXT: I'm a newbie trying to extend a struct using a mixin template like this one: struct World { floatrotation; bool active; mixin BuildStuff; } mixin template BuildStuff() { foreach(elem; __traits(allMembers, typeof(this))) { //pragma(msg, elem); } } //full example here: https://run.dlang.io/is/OeXS4j COMPILER OUTPUT: 2.067.1 to 2.071.2: Failure with output: - onlineapp.d(18): Error: declaration expected, not 'foreach' onlineapp.d(18): Error: declaration expected, not '__traits' onlineapp.d(22): Error: template member expected - 2.072.2 to 2.075.1: Failure with output: - onlineapp.d(18): Error: declaration expected, not 'foreach' onlineapp.d(18): Error: declaration expected, not '__traits' onlineapp.d(22): Error: matching '}' expected, not EOF - Since 2.076.1: Segfault and no output
Re: Voldemort type for mixin template.
On Thursday, 11 January 2018 at 21:30:43 UTC, aliak wrote: On Thursday, 11 January 2018 at 08:56:11 UTC, ChangLong wrote: When I try add some sub type for struct with mixin template, seems there is no way to hidden the private type. Is there a way to hidden type from mix template like Voldemort type ? fake code: mix template TypeX () { alias This = typeof(this); static struct Unique { This* _ptr ; } static struct Helper { private Unique data; } alias TypeX = { alias PublicName = Helper ; } } struct Node { mixin TypeX!(); PublicName helper; } Hi, can you explain a bit more? The question is not entirely clear to me. Can you mixin a struct of type PublicName and just hide everything in there? mixin template TypeX() { struct PublicName { private alias This = typeof(this); private struct Unique { This* _ptr; } private Unique _data; alias _data this; } } void main(string[] args) { mixin TypeX; PublicName helper; helper._ptr.writeln; } Cheers If PublicName is complex type, require has some private type information. there is noway to hidden the private type from the scope of mixin. the purpose is hidden helper._ptr from main function to avoid name conflict. I try use mixin fo modify struct to allow it has some kind zero cost abstract, or memory manage function.since the system is complex it will import a lot symbol into the class. I has to put the mix template into struct, since I has to add member with type from mix template. and I also want to avoid access ref_count from the struct body(and a lot other name conflict)
Re: Voldemort type for mixin template.
On Thursday, 11 January 2018 at 08:56:11 UTC, ChangLong wrote: When I try add some sub type for struct with mixin template, seems there is no way to hidden the private type. Is there a way to hidden type from mix template like Voldemort type ? fake code: mix template TypeX () { alias This = typeof(this); static struct Unique { This* _ptr ; } static struct Helper { private Unique data; } alias TypeX = { alias PublicName = Helper ; } } struct Node { mixin TypeX!(); PublicName helper; } Hi, can you explain a bit more? The question is not entirely clear to me. Can you mixin a struct of type PublicName and just hide everything in there? mixin template TypeX() { struct PublicName { private alias This = typeof(this); private struct Unique { This* _ptr; } private Unique _data; alias _data this; } } void main(string[] args) { mixin TypeX; PublicName helper; helper._ptr.writeln; } Cheers
Voldemort type for mixin template.
When I try add some sub type for struct with mixin template, seems there is no way to hidden the private type. Is there a way to hidden type from mix template like Voldemort type ? fake code: mix template TypeX () { alias This = typeof(this); static struct Unique { This* _ptr ; } static struct Helper { private Unique data; } alias TypeX = { alias PublicName = Helper ; } } struct Node { mixin TypeX!(); PublicName helper; }
Re: Variadic Mixin/Template classes?
On Saturday, 25 November 2017 at 10:08:36 UTC, vit wrote: On Saturday, 25 November 2017 at 09:52:01 UTC, Chirs Forest wrote: [...] import std.meta : staticMap; class Bar(T) { T bar; } class Foo(Ts...){ staticMap!(Bar, Ts) bars; this(){ static foreach(i, alias T; Ts) bars[i] = new Bar!T; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo2.bars[0].bar = 9; foo2.bars[1].bar = "world"; } thankyou!
Re: Variadic Mixin/Template classes?
On Saturday, 25 November 2017 at 09:52:01 UTC, Chirs Forest wrote: I'd like to make a class that takes multiple template types (1 - several) which can hold an array/tuple of a second class that are instantiated with those types. class Bar(T) { T bar; } class Foo(T[]){ // not sure how to take variadic types here? Bar!(?)[] bars; //not sure how I'd define an array/tuple of multiple types this(){ foreach(int i, b; bars) b = new Bar!T[i]; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo.bars[0].bar = 9; foo.bars[1].bar = "world"; } import std.meta : staticMap; class Bar(T) { T bar; } class Foo(Ts...){ staticMap!(Bar, Ts) bars; this(){ static foreach(i, alias T; Ts) bars[i] = new Bar!T; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo2.bars[0].bar = 9; foo2.bars[1].bar = "world"; }
Variadic Mixin/Template classes?
I'd like to make a class that takes multiple template types (1 - several) which can hold an array/tuple of a second class that are instantiated with those types. class Bar(T) { T bar; } class Foo(T[]){ // not sure how to take variadic types here? Bar!(?)[] bars; //not sure how I'd define an array/tuple of multiple types this(){ foreach(int i, b; bars) b = new Bar!T[i]; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo.bars[0].bar = 9; foo.bars[1].bar = "world"; }
Re: passing member.member alias to mixin template
Clear explanation, thanks! I think it would avoid a lot of confusion to disallow the alias f = c1.field notation and only allow the alias f = C.field notation. If necessary one could use alias f = typeof(c1).field
Re: passing member.member alias to mixin template
On 09/03/2017 08:54 PM, Eric_DD wrote: *** This works: struct Array { void foo() { writeln("foo"); } } mixin template arrayOperations(arrays...) { void foo() { foreach(ref a; arrays) a.foo(); } } class Thing { Array data1; Array data2; mixin arrayOperations!(data1, data2); } [...] *** But if I wrap Array in a S, then I get a "need this for data of type Array" Is there a way (without an alias this in S) to get the following working? *** Non working code: [...] struct S { Array data; } [...] class Thing { S s1; S s2; mixin arrayOperations!(s1.data, s2.data); } As far as I understand, the problem is that an alias of a member does not carry a `this` reference. It's added only when you use the alias in a method of the aggregate. That means, s1.data is not an alias of s1's `data` field, but an alias of `S.data`. And so is `s2.data`. They're effectively the same alias. It's the same with `data1` and `data2`. But in that case the aliases work because `foo` provides the correct `this` reference. An example of what I mean: import std.stdio; class C { int field; void method() { writeln(f); } } C c1; C c2; alias f = c1.field; void main() { c1 = new C; c2 = new C; c1.field = 1; c2.field = 2; c1.method(); /* prints "1" */ c2.method(); /* prints "2" */ version (none) writeln(f); /* Error: need 'this' */ } Note that `c2.method()` prints "2", even though the alias f has been made from c1. The alias doesn't refer to c1's specific field, but to the generic field of the C class. The alias can only be used in methods of C, because they provide the needed `this`.
passing member.member alias to mixin template
I am running into something that seems a bit inconsistent. When I pass an alias of a member to a mixin it works, but a member to member doesn't. It seems like the alias is evaluated to the last symbol before passing it to the mixin. If that's true, is there a way to defer the evaluation? Anyway, better look at this code: *** This works: struct Array { void foo() { writeln("foo"); } } mixin template arrayOperations(arrays...) { void foo() { foreach(ref a; arrays) a.foo(); } } class Thing { Array data1; Array data2; mixin arrayOperations!(data1, data2); } int main(string[] argv) { new Thing().foo(); return 0; } *** But if I wrap Array in a S, then I get a "need this for data of type Array" Is there a way (without an alias this in S) to get the following working? *** Non working code: struct Array { void foo() { writeln("foo"); } } struct S { Array data; } mixin template arrayOperations(arrays...) { void foo() { foreach(ref a; arrays) a.foo();// error: "need this for data of type Array" } } class Thing { S s1; S s2; mixin arrayOperations!(s1.data, s2.data); } int main(string[] argv) { new Thing().foo(); return 0; }
Re: mixin template, extern(C/Windows) and mangled name
On Tuesday, 1 August 2017 at 03:30:08 UTC, Adam D. Ruppe wrote: On Tuesday, 1 August 2017 at 03:08:30 UTC, Domain wrote: And I can see SimpleDllMain in core.sys.windows.dll, the mangled name is correct: DllMain main, DllMain, and WinMain are special cased... for yours, I think you'll have to hack it with pragma(mangle) mixin template GetMetaData() { pragma(mangle, "GetMetaData") // or whatever maybe @0 ? extern(Windows) MetaData GetMetaData() { return MetaData(); } } mixin GetMetaData; I think. Thanks. Anyone known any plan for issue 12575? It has been 3 years, it looks like not that hard to fix.
Re: mixin template, extern(C/Windows) and mangled name
On Tuesday, 1 August 2017 at 03:08:30 UTC, Domain wrote: And I can see SimpleDllMain in core.sys.windows.dll, the mangled name is correct: DllMain main, DllMain, and WinMain are special cased... for yours, I think you'll have to hack it with pragma(mangle) mixin template GetMetaData() { pragma(mangle, "GetMetaData") // or whatever maybe @0 ? extern(Windows) MetaData GetMetaData() { return MetaData(); } } mixin GetMetaData; I think.
mixin template, extern(C/Windows) and mangled name
I known there is a bug with extern(C) in mixin template: https://issues.dlang.org/show_bug.cgi?id=12575 And I can see SimpleDllMain in core.sys.windows.dll, the mangled name is correct: DllMain But my mixin template has wrong mangled name: mixin template GetMetaData() { extern(Windows) MetaData GetMetaData() { return MetaData(); } } mixin GetMetaData; I can see the mangled name is: _D3app8__mixin911GetMetaDataWZS4zero7plugins8metadata8MetaData
Re: function overload with mixin template bug?
On Wednesday, 17 May 2017 at 13:26:36 UTC, Adam D. Ruppe wrote: On Wednesday, 17 May 2017 at 13:13:06 UTC, Patric Dexheimer wrote: Function overloads coming from mixin templates are not being detected ? A name being present in the struct means that name is NOT pulled from the mixin template. This is a feature, not a bug. It allows overriding of mixin template individual behavior. see: http://arsdnet.net/this-week-in-d/sep-27.html To bring in the mixin overloads in addition to your current ones instead of overriding, use alias: mixin Foo some_name; alias foo = some_name.foo; void foo() {} // now they are all combined Oh, thank you, didn´t know about it. didn´t know about this syntax also "mixin Foo some_name;"
Re: function overload with mixin template bug?
On Wednesday, 17 May 2017 at 13:13:06 UTC, Patric Dexheimer wrote: Function overloads coming from mixin templates are not being detected ? A name being present in the struct means that name is NOT pulled from the mixin template. This is a feature, not a bug. It allows overriding of mixin template individual behavior. see: http://arsdnet.net/this-week-in-d/sep-27.html To bring in the mixin overloads in addition to your current ones instead of overriding, use alias: mixin Foo some_name; alias foo = some_name.foo; void foo() {} // now they are all combined
function overload with mixin template bug?
1) struct T{ void f1(){writeln("default f1");} void f1(int x){writeln("overload f1");} } //main T().f1(); T().f1(1); //compiles and output as expected. 2) mixin template add_function(){ void f1(){writeln("default f1");} } struct T{ mixin add_function; void f1(int x){writeln("overload f1");} } //main T().f1(); T().f1(1); //Error: function f355.T.f1 (int x) is not callable using argument types () /* What? i´m missing something here? */ 3) mixin template add_function(){ void f1(){writeln("default f1");} } struct T{ mixin add_function; } //main T().f1(); //compiles and output as expected. Function overloads coming from mixin templates are not being detected ?
Re: Mixin template confusion / compiler error.
On 01/19/2017 01:06 AM, Ali Çehreli wrote: > In other words, D's string > mixins are the same as C's macros. I was testing you! :p I meant "NOT the same as". :p Ali
Re: Mixin template confusion / compiler error.
On 01/19/2017 12:41 AM, Chris Katko wrote: > 1 - Is there any way TO get the output 64,64? You can mixin the entire statement. I used the ~ operator but you can use format() or the return value of a function as well: mixin("array_t!(" ~ sizer2D!() ~ ") case2;"); // ... mixin("array3_t!(" ~ sizer2D!() ~ ") case6;"); With function call: mixin(makeDeclaration(/* ... */)); > 2 - Is this very non-standard / unrecommended practice and there's a > much better way to do this? There are other options like using literals like 64. Perhaps an AliasSeq!(64, 64) could be useful. > enum MAP_SIZE > { > PLANET = 2048, > SHIP = 256, > SHUTTLE = 64, > (etc) > } //this could also be translated to an array lookup. ala SHIP = 0, > SHUTTLE = 1, etc. with an array holding the sizes. > > and then I pass MAP_SIZE, into a map class, which then builds layers > into that map based on the MAP_SIZE. The layers are statically sized at > compile-time by translating a given MAP_SIZE down to the actual required > dimensions. > > So in plain English: Based on a MAP_SIZE, the inner structures are all > sized appropriately at compile-time. I think the best way of doing this is by producing the entire code as string but look at the implementation of std.bitmanip.bitfields to see how it's actually a mixin template than contains an enum, I think to prevent name-polluting the scope that it's mixed in. > "no commas" seem so arbitrary from an abstract, novice > perspective. I think AliasSeq is your best bet in that case. > What if I was pre-processing English statements which include > commas? Of course you can do that as strings but mixed-in code must obey the spec and it must be "a valid StatementList". In other words, D's string mixins are the same as C's macros. Ali
Re: Mixin template confusion / compiler error.
On Thursday, 19 January 2017 at 08:41:53 UTC, Chris Katko wrote: Thank you! So: 1 - Is there any way TO get the output 64,64? Would this work for you? import std.meta; alias sizer1D = AliasSeq!(64); alias sizer2D = AliasSeq!(64,64); array_t!sizer2D caseX; array2_t!sizer1D caseY;
Re: Mixin template confusion / compiler error.
Thank you! So: 1 - Is there any way TO get the output 64,64? It seems like being able to get a comma out of a mixin is a useful feature. 2 - Is this very non-standard / unrecommended practice and there's a much better way to do this? For example, in my actual code, I have an enumerator: enum MAP_SIZE { PLANET = 2048, SHIP = 256, SHUTTLE = 64, (etc) } //this could also be translated to an array lookup. ala SHIP = 0, SHUTTLE = 1, etc. with an array holding the sizes. and then I pass MAP_SIZE, into a map class, which then builds layers into that map based on the MAP_SIZE. The layers are statically sized at compile-time by translating a given MAP_SIZE down to the actual required dimensions. So in plain English: Based on a MAP_SIZE, the inner structures are all sized appropriately at compile-time. So, for example: map_t!(MAP_SIZE.SHIP) x; goes into map_t(MAP_SIZE s) { layer_t!(mixin(sizer2D!(s))) layer; } which becomes map_t(MAP_SIZE s) { layer_t!(64,64) layer; } and in layer_t: layer_t(int width, int height) { int [width][height] data; } Is there a different way to go about this? Should I be building some sort of function inside a template that "decides" / "translates" a passed template parameter MAP_SIZE to width and height values? I guess I could try putting the mixin inside layer_t and put the values into the square brackets, instead of commas. But again, "no commas" seem so arbitrary from an abstract, novice perspective. What if I was pre-processing English statements which include commas? Thank you for your assistance. I appreciate it.
Re: Mixin template confusion / compiler error.
On 01/19/2017 12:03 AM, Chris Katko wrote: > template sizer2D() // no params here for simplicity > { > const char [] sizer2D = "64,64"; > } > array_t!(mixin(sizer2D!())) case2; // FAILS (error below) > Error: template instance array_t!64 does not match template declaration > array_t(int width, int height) The comma operator strikes back but this time it's caught. :) The clue was exposed because my compilation has the following dmd flag: -de show use of deprecated features as errors (halt compilation) According to spec, "The text contents of the string must be compilable as a valid StatementList, and is compiled as such.": https://dlang.org/spec/statement.html#mixin-statement So, "64,64" is mixed in as two expressions around a comma operator and it gets the value 64. Ali
Re: Mixin template confusion / compiler error.
Addendum: Writing the following: writeln(mixin(sizer2D!())); simply dumps 64 to stdout. What's going on here? Have I run into a compiler bug?
Mixin template confusion / compiler error.
I've tried to narrow this down to the minimum code that exhibits the problem. When I use a mixin, to supply the parameters for a template, it works with ONE argument, but NOT TWO. template sizer2D() // no params here for simplicity { const char [] sizer2D = "64,64"; } template sizer1D() { const char [] sizer1D = "64"; } class why_t () { array_t!(64,64) case1; // works array_t!(mixin(sizer2D!())) case2; // FAILS (error below) array2_t!(64) case3; // works array2_t!(mixin(sizer1D!())) case4; // works array3_t!(64) case5; // works array3_t!(mixin(sizer2D!())) case6; // WORKS using ONE ARGUMENT method using default parameter for height (see class) } class array_t (int width, int height) { int [width][height] data; } class array2_t (int width) { int [width][width] data; } class array3_t (int width, int height=width) //note default param { int [width][height] data; } The error I get is: Error: template instance array_t!64 does not match template declaration array_t(int width, int height) Error: template instance a5test.why_t!() error instantiating And the strange thing is, it's like it's only outputting ONE of the two numbers. If it were outputting any other gibberish, it shouldn't compile at all. And I'm not misplacing the 1D vs 2D function names because originally there was NO 1D version at all. It was just the 2D and it wouldn't compile. Is there any way to get a PRINTOUT of the mixin code upon failure to see what it's actually trying to compile? - I'm using LDC2: LDC - the LLVM D compiler (e9b2b4): based on DMD v2.068.2 and LLVM 3.5.0
Re: mixin template hide
On Sunday, 24 July 2016 at 18:38:53 UTC, Eppason wrote: The obvious solution is to refactor Bar, but in the real world, it is much harder and life would be much easier if I could remove foo from exists inside S. At worse, if Bar did depend on foo, I would simply get errors about missing foo. I doubt it is possible, but maybe some tricks? you could define a flag for foo, like: mixin template BAR(bool addFoo = true) { mixin FOO; static if(addFoo) { void foo(){} } }
mixin template hide
I use self-introspection and have the case for having to "remove" things from the mixin. Typically the mixin will mixin stuff that it does not exist in the scope it is trying to mix in, a great feature. But what I would like to do is tell the mixin not to mix in foo(), this allows me to take a step back in the abstraction that I have created, rather than having to only move forward. mixin FOO(); @disable FOO.foo(); // prevents foo from mixing in from FOO and does not add foo to the method table with functions, I can create dummy functions, but they then still exist. For fields, I cannot remove. mixin template FOO() { void test() { // Self introspection static if (__traits(compiles, foo())) ... } } mixin template BAR() { mixin FOO(); void foo() { } } struct S { mixin BAR(); // We now have foo(); But I don't want!!! } You might gander that I could just mixin FOO and void this problem. Well, there are things in BAR I do want. I do know, because of design, that removing foo won't "break" bar, so there is no risk. It is more risk to create a dummy foo that doesn't do what FOO expects of it(which, is to foo). For example, if foo is actually allocate_memory, then Foo works with allocate_memory or without(because of self-introspection). Bar adds the ability to allocate_memory, and print "Hello". For S, I want FOO & the ability to print "Hello" but not the ability to allocate. The obvious solution is to refactor Bar, but in the real world, it is much harder and life would be much easier if I could remove foo from exists inside S. At worse, if Bar did depend on foo, I would simply get errors about missing foo. I doubt it is possible, but maybe some tricks?
Re: Behavior of __FILE__ in mixin template
On Wednesday, 22 June 2016 at 17:52:26 UTC, Ali Çehreli wrote: On 06/22/2016 10:07 AM, Andre Pany wrote: > Hi, > > I thought a mixin template is copied into the place where the mixin > statement > exists and then the coding is evaluated. > This seems not to be true for __FILE__ Apparently its the whole template that supports that. Is moving the 'file' parameter to the entire template acceptable? mixin template formTemplate(string file = __FILE__) { // ... } Ali Perfekt, thanks a lot. Kind regards André
Re: Behavior of __FILE__ in mixin template
On 06/22/2016 10:07 AM, Andre Pany wrote: > Hi, > > I thought a mixin template is copied into the place where the mixin > statement > exists and then the coding is evaluated. > This seems not to be true for __FILE__ Apparently its the whole template that supports that. Is moving the 'file' parameter to the entire template acceptable? mixin template formTemplate(string file = __FILE__) { // ... } Ali
Behavior of __FILE__ in mixin template
Hi, I thought a mixin template is copied into the place where the mixin statement exists and then the coding is evaluated. This seems not to be true for __FILE__ I have a module form, which has a class Form. This module also contains following mixin template mixin template formTemplate() { void generateForm() { string getFormName(string file = __FILE__)() { import std.string: indexOf; return file[0..file.indexOf(".")]~".frm"; } enum fileContent = import(getFormName()); } } In another module myform I have a class MyForm in which I call the mixin statement: mixin formTemplate. The purpose of the template coding is: The enum fileContent should contain the text of a file, which has the same name as the module but the file ending .frm. I tried different things, but either it doesn't compile or __FILE__ returns "form" instead of "myform". Is this behavior correct? Do you have any tip? Kind regards André
Re: import in mixin template
On Thursday, 26 May 2016 at 05:47:36 UTC, Era Scarecrow wrote: On Thursday, 26 May 2016 at 05:20:25 UTC, vitus wrote: Why 'alias wln1 = writeln;' doesnt't work but 'alias wln2 = std.stdio.writeln;' work when import is not static? Why 'wln2("test");' work but 'std.stdio.writeln("test");' doesn't? (changing import to static import doesn't change anything) The import seems to be localized to just the mixin & the template. Makes sense since you don't want to be cluttering the namespace with other imports. The only thing you haven't shown is that the 'alias m' is identified and accessible. Adding it in the compiler doesn't complain; Only line 11 (alias wln1) complains for me DMD w32 v2.071.0. But why is 'std.stdio.writeln' accessible from CLASS but writeln no? Both are imported in MIXIN. and: mixin template MIXIN(){ import std.stdio; } class CLASS{ mixin MIXIN; void test(){ alias wln = std.stdio.writeln; //OK wln("test"); //OK std.stdio.writeln("test"); //Error: Deprecation: module std.stdio is not accessible here, perhaps add 'static import std.stdio;' } } Why is possible create alias to function 'std.stdio.writeln' but cannot by called as a function directly?
Re: import in mixin template
On Thursday, 26 May 2016 at 05:20:25 UTC, vitus wrote: Why 'alias wln1 = writeln;' doesnt't work but 'alias wln2 = std.stdio.writeln;' work when import is not static? Why 'wln2("test");' work but 'std.stdio.writeln("test");' doesn't? (changing import to static import doesn't change anything) The import seems to be localized to just the mixin & the template. Makes sense since you don't want to be cluttering the namespace with other imports. The only thing you haven't shown is that the 'alias m' is identified and accessible. Adding it in the compiler doesn't complain; Only line 11 (alias wln1) complains for me DMD w32 v2.071.0.
import in mixin template
Code: mixin template MIXIN(){ import std.stdio; alias m = writeln; //OK } class CLASS{ mixin MIXIN; alias wln1 = writeln; //Error: 'writeln' is not defined, perhaps you need to import std.stdio; ? alias wln2 = std.stdio.writeln; //OK void test(){ wln2("test"); //OK std.stdio.writeln("test"); //Error: Deprecation: module std.stdio is not accessible here, perhaps add 'static import std.stdio;' } } Why 'alias wln1 = writeln;' doesnt't work but 'alias wln2 = std.stdio.writeln;' work when import is not static? Why 'wln2("test");' work but 'std.stdio.writeln("test");' doesn't? (changing import to static import doesn't change anything)
Re: Mixin Template Function Attributes
On Wednesday, 20 January 2016 at 19:48:04 UTC, jmh530 wrote: On Wednesday, 20 January 2016 at 19:19:04 UTC, Marc Schütz wrote: On Wednesday, 20 January 2016 at 16:37:31 UTC, jmh530 wrote: I'm not sure if this is how the behavior is supposed to be or if it is a bug. I believe, however, that it _is_ a bug that the imported symbols are visible outside the template. Most likely related to the infamous https://issues.dlang.org/show_bug.cgi?id=314 Thanks. The fact that one worked and the other didn't was what I found weird. It looks like this issue covers it https://issues.dlang.org/show_bug.cgi?id=12735 It appears that there is a pull request in the works to fix the behavior.
Re: Mixin Template Function Attributes
On Wednesday, 20 January 2016 at 19:19:04 UTC, Marc Schütz wrote: On Wednesday, 20 January 2016 at 16:37:31 UTC, jmh530 wrote: I'm not sure if this is how the behavior is supposed to be or if it is a bug. I believe, however, that it _is_ a bug that the imported symbols are visible outside the template. Most likely related to the infamous https://issues.dlang.org/show_bug.cgi?id=314 Thanks. The fact that one worked and the other didn't was what I found weird.
Re: Mixin Template Function Attributes
On Wednesday, 20 January 2016 at 16:37:31 UTC, jmh530 wrote: I'm not sure if this is how the behavior is supposed to be or if it is a bug. It's not a bug. The `@attribute:` syntax applies to all following declarations _inside the current scope_, i.e. until your mixin templates closing `}`.
Re: Mixin Template Function Attributes
On Wednesday, 20 January 2016 at 16:37:31 UTC, jmh530 wrote: I'm not sure if this is how the behavior is supposed to be or if it is a bug. I believe, however, that it _is_ a bug that the imported symbols are visible outside the template. Most likely related to the infamous https://issues.dlang.org/show_bug.cgi?id=314