Why does BinaryHeap sometime cause compile-error in foeach?
https://dpaste.dzfl.pl/cd605899d050 why this code cannot convert to foreach (over Structs and Classes with Ranges). auto h = new BinaryHeap!(int[])(new int[0]); typeof(h).stringof.writeln; static assert(isInputRange!(typeof(h))); h.insert(3); h.insert(1); h.insert(2); // Error: invalid foreach aggregate `h` // foreach (e; h) e.writeln; for (; !h.empty; h.popFront()) { auto e = h.front(); e.writeln; } https://dlang.org/spec/statement.html#foreach-with-ranges
Re: Why does BinaryHeap sometime cause compile-error in foeach?
On Saturday, 30 September 2017 at 09:27:23 UTC, Shigeki Karita wrote: https://dpaste.dzfl.pl/cd605899d050 why this code cannot convert to foreach (over Structs and Classes with Ranges). auto h = new BinaryHeap!(int[])(new int[0]); typeof(h).stringof.writeln; static assert(isInputRange!(typeof(h))); h.insert(3); h.insert(1); h.insert(2); // Error: invalid foreach aggregate `h` // foreach (e; h) e.writeln; for (; !h.empty; h.popFront()) { auto e = h.front(); e.writeln; } https://dlang.org/spec/statement.html#foreach-with-ranges The reason why it doesn't work is much more simple than you think: h is not a BinaryHeap, it's a pointer to. Try "foreach (e; *h) e.writeln;" and it works.
Re: static this not run?
On Saturday, 30 September 2017 at 08:49:14 UTC, user1234 wrote: On Saturday, 30 September 2017 at 06:15:41 UTC, Nicholas Wilson wrote: No "initialising onError", the static this is not even being run! I'm using LDC master. See also https://github.com/libmir/dcompute/issues/32 LDC 1.4, DMD 2.076, DMD ~master and finally GDC all give the expected result here "initialising onErrorinitialising onError: funcptr = 0xaddress>" each time using: --- enum Status {success,} class StatusException : Exception { this(Status s) {this.s = s;super("");} Status s; } void delegate(Status) onError; static this() { import core.stdc.stdio; printf("initialising onError"); onError = (Status s) { throw new StatusException(s);}; printf("initialising onError: funcptr = 0x%x", onError.funcptr); } void main() { import std.stdio; writeln(onError.funcptr); } --- Hmm. Everything except for the main function was in a different module, I dont see why that would cause it to not be run, but then bugs have a tendency to do strange things like that. I'll have to dust mite DCompute and see what it gets as a minimal case.
Re: core.stdc.time
On 2017-09-30 08:56, Tony wrote: The documentation says: -- This module contains bindings to selected types and functions from the standard C header . Note that this is not automatically generated, and may omit some types/functions from the original C header. --- It says "this is not automatically generated". I am seeing it on my Ubuntu Linux system. What would cause it to not be generated and what would be the solution? It means that it's manually translated from C to D and not translated automatically using some tool. -- /Jacob Carlborg
Re: Creating a dynamic library
On 30-09-17 03:27, Tony wrote: One thing I picked up from SCons is creating dynamic object files with a .os extension and static object files with the standard .o extension. That way they can be compiled in the same directory in the same build step. But dmd rejects the files that are named *.os. Is there an extension besides .o that dmd would accept for the dynamic object files? I've been using .pic.o so it still ends with .o for dmd. -- Mike Wey
Re: AliasSeq of T.tupleof for class and all base classes
On 9/29/17 11:39 PM, bitwise wrote: As far as I can tell, this code should compile: class B { int a; } class D1 : B { int b; } class D2 : D1 { int c; } template TupleOf(Classes...) { static if(Classes.length > 1) alias TupleOf = AliasSeq!(Classes[0].tupleof, TupleOf!(Classes[1..$])); else static if(Classes.length == 1) alias TupleOf = AliasSeq!(Classes[0].tupleof); else alias TupleOf = AliasSeq!(); } int main(string[] argv) { alias allClasses = AliasSeq!(D2, BaseClassesTuple!D2); alias allFields = TupleOf!allClasses; return 0; } But I get this: Error: template instance AliasSeq!(b, a) AliasSeq!(b, a) is nested in both D1 and B Error: template instance main.TupleOf!(D1, B, Object) error instantiating instantiated from here: TupleOf!(D2, D1, B, Object) Any ideas? Thanks I think the problem may be that derived classes' tupleof has some of the same variables as the base class? I agree it should work, but I think if it did work, it may not be what you want. You would see a lot of repeats. BTW, AliasSeq!(x.tupleof) is redundant, x.tupleof is already an AliasSeq. -Steve
Re: static this not run?
On Saturday, 30 September 2017 at 12:07:21 UTC, Nicholas Wilson wrote: Hmm. Everything except for the main function was in a different module, I dont see why that would cause it to not be run, but then bugs have a tendency to do strange things like that. I'll have to dust mite DCompute and see what it gets as a minimal case. [The object needs to be pulled in during linking.]
Re: Region-based memory management and GC?
On Saturday, 30 September 2017 at 07:41:21 UTC, Igor wrote: On Friday, 29 September 2017 at 22:13:01 UTC, Jon Degenhardt wrote: Have there been any investigations into using region-based memory management (aka memory arenas) in D, possibly in conjunction with GC allocated memory? Sounds like just want to use https://dlang.org/phobos/std_experimental_allocator_building_blocks_region.html. Wow, thanks, I did not know about this. Will check it out.
splitter string/char different behavior
writeln( "a.b.c".splitter('.').dropBack(1) ); //compiles ok writeln( "a.b.c".splitter(".").dropBack(1) ); //error: Error: template std.range.dropBack cannot deduce function from argument types !()(Result, int), candidates are: (...) Hm.. can someone explain whats going on?
Sockets and the Promiscous Mode
Hello all only for learning purposes and my interest for deeper network programming. I wanted to write a program and filter the entire traffic in my network. I have a server and various computers in my network, but I dont know, as I in D the promiscous mode for sockets can switch on. Is this possible in D ? I dont want back to C and in Rust.. Rust :) I Love to write some Code in D, its a beautyful language. And so sorry for my english, i understand good, but to write english, i must more learn :) happy greetings fichtknick
Re: AliasSeq of T.tupleof for class and all base classes
On Saturday, 30 September 2017 at 12:42:17 UTC, Steven Schveighoffer wrote: I think the problem may be that derived classes' tupleof has some of the same variables as the base class? I agree it should work, but I think if it did work, it may not be what you want. You would see a lot of repeats. .tupleof doesn't return fields from base classes. assert(D2.tupleof.stringof == "tuple(c)");
Re: Creating a dynamic library
On Saturday, 30 September 2017 at 10:09:43 UTC, Mike Wey wrote: On 30-09-17 03:27, Tony wrote: One thing I picked up from SCons is creating dynamic object files with a .os extension and static object files with the standard .o extension. That way they can be compiled in the same directory in the same build step. But dmd rejects the files that are named *.os. Is there an extension besides .o that dmd would accept for the dynamic object files? I've been using .pic.o so it still ends with .o for dmd. Thanks for the suggestion! I was thinking that this might be a linker function only and tried to use g++ and gcc for the .so creation but, while they both create the same size file as each other, it is different than what dmd does when called with -shared.
Re: Region-based memory management and GC?
On Friday, 29 September 2017 at 22:13:01 UTC, Jon Degenhardt wrote: Have there been any investigations into using region-based memory management (aka memory arenas) in D, possibly in conjunction with GC allocated memory? This would be a very speculative idea, but it'd be interesting to know if there have been looks at this area. My own interest is request-response applications, where memory allocated as part of a specific request can be discarded as a single block when the processing of that request completes, without running destructors. I've also seen some papers describing GC systems targeting big data platforms that incorporate this idea. eg. http://www.ics.uci.edu/~khanhtn1/papers/osdi16.pdf --Jon Sounds like just want to use https://dlang.org/phobos/std_experimental_allocator_building_blocks_region.html.
generating @property from structs
struct MyType { void* ptr; static struct Info { @(42) int foo; } // Should be generated by the mixin below @property int foo() { int ret; getMyTypeInfo(ptr,42,int.sizeof,); return ret; } mixin generateInfo!getMyTypeInfo; } extern(C) void getMyTypeInfo(void*,int, size_t,void*); How do I write generateInfo info? mixin template generateInfo(alias func) { foreach(field; typeof(this).Info.tupleof) { //??? } } I know I'll probably have to resort to string mixins, but how do I get the attribute so that I call func(ptr,attibute, T.sizeof, )? There will be a couple of values that dont have an attribute but they are all of known types and I want to handle them separately. Thanks Nic
Re: Is it possible to specify the address returned by the address of operator?
On Friday, 29 September 2017 at 22:15:44 UTC, Mengu wrote: On Friday, 29 September 2017 at 02:34:08 UTC, DreadKyller wrote: [...] +1 for forum issue. +1 please...
static this not run?
I want a module level initialised delegate. if I try module foo; enum Status { success, } class StatusException : Exception { Status s; // usual exception constructors } void delegate(Status) onError = (Status s) { throw new StatusException(s);}; I get a error like cannot initialise something that needs a context at compile time. Ignoring the fact the the initialiser does not need a context, if I do void delegate(Status) onError; static this() { onError = (Status s) { throw new StatusException(s);}; } void main() { import std.stdio; writeln(onError.funcptr); // null } WAT? void delegate(Status) onError; static this() { import core.stdc.stdio; printf("initialising onError"); onError = (Status s) { throw new StatusException(s);}; printf("initialising onError: funcptr = 0x%x", onError.funcptr); } void main() { import std.stdio; writeln(onError.funcptr); } output: null No "initialising onError", the static this is not even being run! I'm using LDC master. See also https://github.com/libmir/dcompute/issues/32
Re: core.stdc.time
On Saturday, 30 September 2017 at 07:45:27 UTC, Jacob Carlborg wrote: On 2017-09-30 08:56, Tony wrote: The documentation says: -- This module contains bindings to selected types and functions from the standard C header . Note that this is not automatically generated, and may omit some types/functions from the original C header. --- It says "this is not automatically generated". I am seeing it on my Ubuntu Linux system. What would cause it to not be generated and what would be the solution? It means that it's manually translated from C to D and not translated automatically using some tool. Thanks!
Re: generating @property from structs
On Saturday, 30 September 2017 at 08:20:44 UTC, Nicholas Wilson wrote: struct MyType { void* ptr; static struct Info { @(42) int foo; } // Should be generated by the mixin below @property int foo() { int ret; getMyTypeInfo(ptr,42,int.sizeof,); return ret; } mixin generateInfo!getMyTypeInfo; } extern(C) void getMyTypeInfo(void*,int, size_t,void*); How do I write generateInfo info? mixin template generateInfo(alias func) { foreach(field; typeof(this).Info.tupleof) { //??? } } I know I'll probably have to resort to string mixins, but how do I get the attribute so that I call func(ptr,attibute, T.sizeof, )? There will be a couple of values that dont have an attribute but they are all of known types and I want to handle them separately. Thanks Nic You can use a struct that contains the value because apparently without you can only retrieve a specific value: --- struct ValueHolder{int value;} struct Foo { @ValueHolder(42) int foo; int getTheValueDuringTheCall(string member)() { import std.traits; alias uda = getUDAs!(__traits(getMember, Foo, member), ValueHolder); static if (uda.length == 1) return uda[0].value; else return 0; } void test() { import std.stdio; writeln(getTheValueDuringTheCall!"foo"); } } void main() { Foo foo; foo.test(); } --- I mean that `getUDAs!(__traits(getMember, Foo, member), int);` wouldn't work.
Re: static this not run?
On Saturday, 30 September 2017 at 06:15:41 UTC, Nicholas Wilson wrote: No "initialising onError", the static this is not even being run! I'm using LDC master. See also https://github.com/libmir/dcompute/issues/32 LDC 1.4, DMD 2.076, DMD ~master and finally GDC all give the expected result here "initialising onErrorinitialising onError: funcptr = 0xaddress>" each time using: --- enum Status {success,} class StatusException : Exception { this(Status s) {this.s = s;super("");} Status s; } void delegate(Status) onError; static this() { import core.stdc.stdio; printf("initialising onError"); onError = (Status s) { throw new StatusException(s);}; printf("initialising onError: funcptr = 0x%x", onError.funcptr); } void main() { import std.stdio; writeln(onError.funcptr); } ---
core.stdc.time
The documentation says: -- This module contains bindings to selected types and functions from the standard C header . Note that this is not automatically generated, and may omit some types/functions from the original C header. --- It says "this is not automatically generated". I am seeing it on my Ubuntu Linux system. What would cause it to not be generated and what would be the solution?
Best way to display images with GTKD
I have to display images with a few controls: alpha channel, rotation, scaling, cropping. Generally it should be png but I want to be able to handle many images. The images will be memory based(I'll load the file in to memory then) and will be displayed in a drawing area. Any ideas how to go about this correctly?
Re: splitter string/char different behavior
In order to know where to split, it really has to do it from the front. If it starts from the back, you won't necessarily split in the same places as when iterating from the front, and that would violate how bidirectional ranges are supposed to work (the elements should be the same - just in reverse - if you iterate from the back). That being the case, it makes sense that splitting on a single element would result in a range that was bidirectional, whereas splitting on a range of elements would result in a range that's only a forward range. - Jonathan M Davis Nice! since dropBack is a BidirectionalRange everything make sense now. Thanks everybody! I just think that the error message should be a little better, since I have no idea about the incompatible Range types looking only to the error message. (Dont know if is possible, but anyway.. )
[Template] Mixins and foreach
struct MyType { void* raw; static struct Info { @(42) int foo; } mixin generateGetInfo!MyTypeGetInfo; } extern(C) void MyTypeGetInfo(void*,int,size_t,void*size_t*); mixin template generateGetInfo(alias func) { foreach(field; typeof(this).Info.tupleof) { mixin("@property " ~ typeof(field).stringof ~ " " ~ field.stringof ~ "()" ~ " { " ~ "typeof(return) ret;" ~ func.stringof ~ "(this.tupleof," ~ __traits(getAttributes, field)[0] ~ ",ret.sizeof,,null);" ~ "return ret; }"); } } Fails with Error: declaration expected, not 'foreach' Error: no identifier for declarator typeof(this).Info.tupleof Error: declaration expected, not ')' I also tried a double mixin, one for the foreach and one for the mixin to no avail. How do I do a foreach in a [template] mixin to procedurally inject multiple declarations ? Static foreach is not an option as I am using LDC.
Re: splitter string/char different behavior
On Saturday, September 30, 2017 20:18:25 Jon Degenhardt via Digitalmars-d- learn wrote: > On Saturday, 30 September 2017 at 17:17:17 UTC, SrMordred wrote: > > writeln( "a.b.c".splitter('.').dropBack(1) ); //compiles ok > > writeln( "a.b.c".splitter(".").dropBack(1) ); > > > > //error: > > Error: template std.range.dropBack cannot deduce function from > > argument types !()(Result, int), candidates are: > > (...) > > > > Hm.. can someone explain whats going on? > > Let's try again. I'm not sure the full explanation, but likely > involves two separate template overloads being instantiated, each > with a separate definition of the return type. > > * "a.b.c".splitter('.') - This overload: > https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L369 > 6-L3703 > > * "a.b.c".splitter(".") - This overload: > https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L397 > 3-L3982 > > But why one supports dropBack and the other doesn't I don't know. Well, figuring out where to split when iterating in reverse is trivial when splitting on a single element, but it's not when dealing with a range of elements. Sure, in this case, because the range happens to be only one character long, it would be easy, but as soon as it has multiple characters, it wouldn't be - especially if you got nonsense like auto result = "t".splitter("ttt"); In order to know where to split, it really has to do it from the front. If it starts from the back, you won't necessarily split in the same places as when iterating from the front, and that would violate how bidirectional ranges are supposed to work (the elements should be the same - just in reverse - if you iterate from the back). That being the case, it makes sense that splitting on a single element would result in a range that was bidirectional, whereas splitting on a range of elements would result in a range that's only a forward range. - Jonathan M Davis
Re: [Template] Mixins and foreach
On Sunday, 1 October 2017 at 01:05:56 UTC, Nicholas Wilson wrote: struct MyType { void* raw; static struct Info { @(42) int foo; } mixin generateGetInfo!MyTypeGetInfo; } extern(C) void MyTypeGetInfo(void*,int,size_t,void*size_t*); mixin template generateGetInfo(alias func) { foreach(field; typeof(this).Info.tupleof) { mixin("@property " ~ typeof(field).stringof ~ " " ~ field.stringof ~ "()" ~ " { " ~ "typeof(return) ret;" ~ func.stringof ~ "(this.tupleof," ~ __traits(getAttributes, field)[0] ~ ",ret.sizeof,,null);" ~ "return ret; }"); } } Fails with Error: declaration expected, not 'foreach' Error: no identifier for declarator typeof(this).Info.tupleof Error: declaration expected, not ')' I also tried a double mixin, one for the foreach and one for the mixin to no avail. How do I do a foreach in a [template] mixin to procedurally inject multiple declarations ? Static foreach is not an option as I am using LDC. Hmm, generating the mixed in code as all one string and then mixing it in should work I think. Rather ugly though.
Re: splitter string/char different behavior
On Sunday, October 01, 2017 00:56:23 SrMordred via Digitalmars-d-learn wrote: > > In order to know where to split, it really has to do it from > > the front. If it starts from the back, you won't necessarily > > split in the same places as when iterating from the front, and > > that would violate how bidirectional ranges are supposed to > > work (the elements should be the same - just in reverse - if > > you iterate from the back). That being the case, it makes sense > > that splitting on a single element would result in a range that > > was bidirectional, whereas splitting on a range of elements > > would result in a range that's only a forward range. > > > > - Jonathan M Davis > > Nice! > since dropBack is a BidirectionalRange everything make sense now. > Thanks everybody! > > I just think that the error message should be a little better, > since I have no idea about the incompatible Range types looking > only to the error message. (Dont know if is possible, but > anyway.. ) When the compiler can't find a matching overload for a templated function, look at its template constraint, since you either passed the wrong number of arguments, the wrong type of arguments, or the arguments you passed failed the template constraint. The template constraints aren't always as easy to read as would be nice (especially if there are several overloads), but the key information is there. - Jonathan M Davis
Re: [Template] Mixins and foreach
On Sunday, October 01, 2017 02:07:26 Nicholas Wilson via Digitalmars-d-learn wrote: > On Sunday, 1 October 2017 at 01:05:56 UTC, Nicholas Wilson wrote: > > struct MyType > > { > > > > void* raw; > > static struct Info > > { > > > > @(42) int foo; > > > > } > > mixin generateGetInfo!MyTypeGetInfo; > > > > } > > > > extern(C) void MyTypeGetInfo(void*,int,size_t,void*size_t*); > > mixin template generateGetInfo(alias func) > > { > > > > foreach(field; typeof(this).Info.tupleof) > > { > > > > mixin("@property " ~ typeof(field).stringof ~ " " ~ > > > > field.stringof ~ "()" ~ > > > >" { " ~ > >"typeof(return) ret;" ~ > >func.stringof ~ "(this.tupleof," ~ > > > > __traits(getAttributes, field)[0] ~ ",ret.sizeof,,null);" ~ > > > > "return ret; }"); > > > > } > > > > } > > > > Fails with > > Error: declaration expected, not 'foreach' > > Error: no identifier for declarator typeof(this).Info.tupleof > > Error: declaration expected, not ')' > > > > I also tried a double mixin, one for the foreach and one for > > the mixin to no avail. How do I do a foreach in a [template] > > mixin to procedurally inject multiple declarations ? Static > > foreach is not an option as I am using LDC. > > Hmm, generating the mixed in code as all one string and then > mixing it in should work I think. Rather ugly though. I would have thought that it would be pretty straightforward to just write a recursive, eponymous template to solve the problem and have it recursively build a single string to mix in for everything. In general though, without static foreach, you're either going to be using templates to operate in a functional manner rather than a procedural one, or you're going to be writing procedural code that generates a string to mix in. The latter doesn't really work though when the arguments are an AliasSeq of fields like you get from tupleof. This looks like it would be pretty straightforward to do with a recursive template though. - Jonathan M Davis
Re: splitter string/char different behavior
On Saturday, 30 September 2017 at 17:17:17 UTC, SrMordred wrote: writeln( "a.b.c".splitter('.').dropBack(1) ); //compiles ok writeln( "a.b.c".splitter(".").dropBack(1) ); //error: Error: template std.range.dropBack cannot deduce function from argument types !()(Result, int), candidates are: (...) Hm.. can someone explain whats going on? It's easy to overlook, but documentation for splitter starts out: Lazily splits a range using an element as a separator. An element of a string is a char, not a string. It needs to be read somewhat literally, but it is correct. It's also part of template constraint, useful once you've become accustomed to reading them: auto splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) if (is(typeof(binaryFun!pred(r.front, s)) : bool) && For "a.b.c"splitter(x), Range r is a string, r.front is a char. The template can only be instantiated if the predicate function is valid. The predicate function is "a == b". Since r.front is a char, then s must be a type that can be compared with '=='. A string and char cannot be compared with '==', which is why the a valid template instantiation could not be found.
Re: splitter string/char different behavior
On Saturday, 30 September 2017 at 18:21:11 UTC, Jon Degenhardt wrote: On Saturday, 30 September 2017 at 17:17:17 UTC, SrMordred wrote: [...] It's easy to overlook, but documentation for splitter starts out: Lazily splits a range using an element as a separator. An element of a string is a char, not a string. It needs to be read somewhat literally, but it is correct. It's also part of template constraint, useful once you've become accustomed to reading them: auto splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) if (is(typeof(binaryFun!pred(r.front, s)) : bool) && For "a.b.c"splitter(x), Range r is a string, r.front is a char. The template can only be instantiated if the predicate function is valid. The predicate function is "a == b". Since r.front is a char, then s must be a type that can be compared with '=='. A string and char cannot be compared with '==', which is why the a valid template instantiation could not be found. Would it be correct to just update the documentation to say "Lazily splits a range using an char as a separator" ? what is it; wchar and dchar too? I notice the example that is there has ' ' as the element.
Re: splitter string/char different behavior
For "a.b.c"splitter(x), Range r is a string, r.front is a char. The template can only be instantiated if the predicate function is valid. The predicate function is "a == b". Since r.front is a char, then s must be a type that can be compared with '=='. A string and char cannot be compared with '==', which is why the a valid template instantiation could not be found. Would it be correct to just update the documentation to say "Lazily splits a range using an char as a separator" ? what is it; wchar and dchar too? I notice the example that is there has ' ' as the element. But this works: writeln("a.b.c".splitter(".") );
Re: splitter string/char different behavior
On Saturday, 30 September 2017 at 19:26:14 UTC, SrMordred wrote: For "a.b.c"splitter(x), Range r is a string, r.front is a char. The template can only be instantiated if the predicate function is valid. The predicate function is "a == b". Since r.front is a char, then s must be a type that can be compared with '=='. A string and char cannot be compared with '==', which is why the a valid template instantiation could not be found. Would it be correct to just update the documentation to say "Lazily splits a range using an char as a separator" ? what is it; wchar and dchar too? I notice the example that is there has ' ' as the element. But this works: writeln("a.b.c".splitter(".") ); Geez, my mistake. I'm sorry about that. It's dropback that's failing, not splitter.
Re: splitter string/char different behavior
On Saturday, 30 September 2017 at 17:17:17 UTC, SrMordred wrote: writeln( "a.b.c".splitter('.').dropBack(1) ); //compiles ok writeln( "a.b.c".splitter(".").dropBack(1) ); //error: Error: template std.range.dropBack cannot deduce function from argument types !()(Result, int), candidates are: (...) Hm.. can someone explain whats going on? Let's try again. I'm not sure the full explanation, but likely involves two separate template overloads being instantiated, each with a separate definition of the return type. * "a.b.c".splitter('.') - This overload: https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L3696-L3703 * "a.b.c".splitter(".") - This overload: https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L3973-L3982 But why one supports dropBack and the other doesn't I don't know.
compile time sequence variable
Hello, can I make AliasSeq not inside template function, for example I want add function called `registerComponent` which will add the components classes to list and based on this generated list I want add additional fields inside `ComponentsManager`. Example: Registering components: struct MyComponent { float avg; string name; } struct MyComponent2 { string name; string text; string title; } static { registerComponent!(MyComponent); registerComponent!(MyComponent2); } And my `ComponentsManager`: class ComponentsManager { // Automatically generated fields Array!MyComponent myComponentList; Array!MyComponent2 myComponent2List; // Other fields and methods } How can I do this? furthermore I would like using `registerComponent` from different modules.
Re: [Template] Mixins and foreach
On Sunday, October 01, 2017 03:11:15 Nicholas Wilson via Digitalmars-d-learn wrote: > On Sunday, 1 October 2017 at 02:29:57 UTC, Jonathan M Davis wrote: > > I would have thought that it would be pretty straightforward to > > just write a recursive, eponymous template to solve the problem > > and have it recursively build a single string to mix in for > > everything. > > > > In general though, without static foreach, you're either going > > to be using templates to operate in a functional manner rather > > than a procedural one, or you're going to be writing procedural > > code that generates a string to mix in. The latter doesn't > > really work though when the arguments are an AliasSeq of fields > > like you get from tupleof. > > > > This looks like it would be pretty straightforward to do with a > > recursive template though. > > > > - Jonathan M Davis > > I think I've almost got it: > > string generateGetInfo( /*alias*/ Info,alias func,args...)() > { > string code; > foreach(field; AliasSeq!(Info.tupleof)) > { > code ~= "@property " ~ typeof(field).stringof ~ " " ~ > field.stringof ~ "()" ~ > "{ " ~ > "typeof(return) ret;" ~ > func.stringof ~ "(" ~ args.stringof ~ "," ~ > __traits(getAttributes, field).stringof ~ > ",ret.sizeof,,null);" ~ > "return ret; " ~ > "}"; > } > } > return code; > } > struct MyType > { > void* raw; > static struct Info > { > @(42) int foo; > } > mixin(generateGetInfo!(Info,MyTypeGetInfo,raw));//errors out > pragma(msg,generateGetInfo!(Info,MyTypeGetInfo,raw)); // also > errors out > } > but this gives a bunch of > > Error: need 'this' for 'foo' of type 'int'. > > even with the pragma msg. > I dont see why though: > a) the Info struct is static > b) I'm only using .stringof on the _type's_ fields > c) its got the name in the errors message! it just wont let > me use it. > > > The latter doesn't really work though when the arguments are an > > AliasSeq of fields like you get from tupleof. > > Why is that and is that what is causing the problem here? Well, what I meant was that you can't pass fields as function arguments, which is generally what you do with a function that's generating a string mixin, and if you pass the fields as template arguments, then you tend to be restricted in the ways that you're normally restricted with compile-time stuff, which means no procedural code. However, you can use foreach with an AliasSeq in the fashion that you're doing, which should work and give you some level of procedural code in spite of the fact that you're dealing with compile-time stuff. The explicit AliasSeq should not be necessary, since the tupleof already is one, but it shouldn't matter either way, since AliasSeqs automatically expand (one of the reasons that calling them tuples is a poor idea). I would note that the static on Info should have zero effect. It would matter if Info were declared inside of a function, and IIRC, it would matter when declaring a class inside a class, but I don't believe that it has any effect when declaring a struct inside a struct. Such structs aren't associated with the struct that they're in aside from namespacing. It's required in the case of nested classes, because otherwise, they get access to the class that they're in and are associated with an instance of it, and it's required for structs and classes in functions in order to indicate that they don't have access to the function's variables. But nothing like that is happening with a struct inside a struct. I don't see any reason why the compiler would be complaining about 'this' being required. I would think that that would imply that the compiler thinks that you're accessing the member rather than introspecting on it. The fact that you're passing raw to generateGetInfo does seem off though, since it wouldn't be accessible at compile time. I would have expected that to result in a compilation errero, but if it's complaining about 'this' when accessing foo rather than complaining about raw, then that implies that raw isn't the problem - or at least not that problem. - Jonathan M Davis
Re: Why does BinaryHeap sometime cause compile-error in foeach?
Oh, struct/class semantics really confuses me!
Re: [Template] Mixins and foreach
On Sunday, 1 October 2017 at 02:29:57 UTC, Jonathan M Davis wrote: I would have thought that it would be pretty straightforward to just write a recursive, eponymous template to solve the problem and have it recursively build a single string to mix in for everything. In general though, without static foreach, you're either going to be using templates to operate in a functional manner rather than a procedural one, or you're going to be writing procedural code that generates a string to mix in. The latter doesn't really work though when the arguments are an AliasSeq of fields like you get from tupleof. This looks like it would be pretty straightforward to do with a recursive template though. - Jonathan M Davis I think I've almost got it: string generateGetInfo( /*alias*/ Info,alias func,args...)() { string code; foreach(field; AliasSeq!(Info.tupleof)) { code ~= "@property " ~ typeof(field).stringof ~ " " ~ field.stringof ~ "()" ~ "{ " ~ "typeof(return) ret;" ~ func.stringof ~ "(" ~ args.stringof ~ "," ~ __traits(getAttributes, field).stringof ~ ",ret.sizeof,,null);" ~ "return ret; " ~ "}"; } } return code; } struct MyType { void* raw; static struct Info { @(42) int foo; } mixin(generateGetInfo!(Info,MyTypeGetInfo,raw));//errors out pragma(msg,generateGetInfo!(Info,MyTypeGetInfo,raw)); // also errors out } but this gives a bunch of Error: need 'this' for 'foo' of type 'int'. even with the pragma msg. I dont see why though: a) the Info struct is static b) I'm only using .stringof on the _type's_ fields c) its got the name in the errors message! it just wont let me use it. The latter doesn't really work though when the arguments are an AliasSeq of fields like you get from tupleof. Why is that and is that what is causing the problem here? Thanks Nic