How can I get this UDA at compile time?
I've had a struct like this: struct Attr { string value; } struct Foo { @(Attr("a attr")) enum a = Foo(10); @(Attr("b attr")) enum b = Foo(11); int x; int y; bool doY = true; int value() { return x; } } I'd like to get that atrribute's value at compile time, something like this: enum s = Foo.a.baa; enum s2 = Foo.b.baa; writeln(s); // a attr writeln(s2); // b attr I did this: string baa() { import std.traits : getUDAs, hasUDA; static foreach(field; __traits(allMembers, Foo)) {{ alias m = __traits(getMember, Foo, field); static if(is(typeof(m) == Foo)) { if(m.value == this.value) return getUDAs!(m, Attr)[0].value; } }} return null; } that was working fine, but I needed to switch value property from Foo struct, so that I can't read this value at CTFE anymore, so this fails now: if(m.value == this.value) return getUDAs!(m, Attr)[0].value; How can I solve this?
Re: Class instance alignment
On Saturday, 20 February 2021 at 18:43:53 UTC, Steven Schveighoffer wrote: Last I checked*, the GC uses pools of 16-byte, 32-byte, 64-byte, etc blocks. That has changed [to reduce wastage]; the new bin sizes are here and include sizes like 176 (11*16): https://github.com/dlang/druntime/blob/728f1d9c3b7a37eba4d59ee2637fb924053cba6d/src/core/internal/gc/impl/conservative/gc.d#L1166 (not sure about stack alignment for scope instances) This works with LDC at least. E.g., this: class C { align(64) int[2] data; } void foo() { scope c = new C(); } allocates 72 bytes aligned at a 64-bytes stack boundary. 72 bytes? :) Yes - vptr, monitor, then 48 padding bytes (for 64-bit target...), then 8 `data` bytes with .offsetof of 64. [And classes don't need tail padding, as you can't allocate arrays of class *instances* directly in the language.] Structs are generally better suited for alignment purposes, but the same GC limitations apply when allocating them on the heap.
Re: Strings and Slices
On 2/20/21 2:31 PM, Mike Brown wrote: On Saturday, 20 February 2021 at 19:28:00 UTC, Mike Brown wrote: On Thursday, 18 February 2021 at 21:08:45 UTC, Adam D. Ruppe wrote: [...] Thank you. Is there a standardised type to make "mark"? size_t or is a normal integer suitable? Ah, and whats the recommended way to iterate over a slice using a mark? Can I get the current iteration point from a foreach loop? ints work as slice endpoints just fine. They will get cast to size_t when used for slicing. If you are going to keep the mark valid, you shouldn't slice away the input, because now 0 becomes the point at the mark. Typically with slices, you don't store a position (sometimes), you just divvy up the slice into pieces you care about. It all depends on what information is important. -Steve
Re: Strings and Slices
On Saturday, 20 February 2021 at 19:28:00 UTC, Mike Brown wrote: On Thursday, 18 February 2021 at 21:08:45 UTC, Adam D. Ruppe wrote: [...] Thank you. Is there a standardised type to make "mark"? size_t or is a normal integer suitable? Ah, and whats the recommended way to iterate over a slice using a mark? Can I get the current iteration point from a foreach loop?
Re: Strings and Slices
On Thursday, 18 February 2021 at 21:08:45 UTC, Adam D. Ruppe wrote: On Thursday, 18 February 2021 at 20:47:33 UTC, Mike Brown wrote: [...] My c++ is rusty af but yes I think so. A d slice is `struct slice { size_t length; T* ptr; }` so when in doubt just think back to what that does. [...] And that makes this ref iffy. Since it is already passed as a ptr+length pair, you rarely need ref on it. Only when you'd use a char** in C; that is, when you can reassign the value of the pointer and have the caller see that change (e.g. you are appending to it). If you're just looking, no need for ref. [...] I do it in two steps: piece = input[0 .. mark]; // get piece out input = input[mark .. $]; // advance the original slice Note that such operations are just `ptr += mark; length -= mark;` so they are very cheap. Thank you. Is there a standardised type to make "mark"? size_t or is a normal integer suitable?
Re: Class instance alignment
On 2/20/21 2:13 AM, tsbockman wrote: On Saturday, 20 February 2021 at 05:44:33 UTC, kinke wrote: There's https://github.com/dlang/druntime/blob/728f1d9c3b7a37eba4d59ee2637fb924053cba6d/src/core/internal/traits.d#L261. Thanks! That's helpful. But AFAIK, the GC only guarantees an alignment of 16 and doesn't respect any overaligned members or alignment spec for the class. Well, that's just another reason not to use the GC for my current project, then: I'm using 256-bit AVX vectors extensively. That alignment limit really *needs* to be raised to at least 32 bytes, given that even DMD has some support for AVX. 64 bytes would be better, since AVX512 is going mainstream soon. And, 128 bytes is the largest common cache line size, I think? The GC should align anything over 16 bytes to 32 bytes (at least). Last I checked*, the GC uses pools of 16-byte, 32-byte, 64-byte, etc blocks. And you don't have mixed allocations in those pools, e.g. a block is ALL 16-byte blocks, or ALL 32-byte blocks. If you specify an alignment of a field in your class, I would expect the compiler to obey the layout. Which means, your class should be over 32-bytes in size since it has to pad it up to the end. This would align it to 32-bytes (or more) naturally. What is the offset of your aligned member in the class? i.e. pragma(msg, Class.member.offsetof) 1. if classInstanceSize is >= 32, I presume it will always be 32-byte aligned on the GC (not sure about stack alignment for scope instances) 2. If the offsetof of your member is not a multiple of 32, then you might have problems. -Steve *Note, this was a long time ago I had anything to do with the GC, so things may have changed.
Re: Templated delegate as template argument for structs
Thanks! The alias solution works and is good enough for me. Also thanks for providing the code to typecheck the alias, I would have never been able to come up with that myself.
Re: Templated delegate as template argument for structs
On Saturday, 20 February 2021 at 09:16:46 UTC, Simon van Bernem wrote: I have the following struct declaration: struct Hash_Table(Key, Value, u32 delegate(ref Key) custom_hash_function = null) [snip] I take it from the error that the problem is not actually the delegate that I am passing, but the fact that the delegate type has another template parameter as the argument type. Can template arguments in D not reference previous template arguments? Is there some way I can get around this? The D way would be an alias parameter: struct Hash_Table(Key, Value, alias custom_hash_function) { // ... } Probably also adding a constraint: struct Hash_Table(Key, Value, alias custom_hash_function) if (is_valid_hash_function!(Key, custom_hash_function)) { // ... } // Check if the hash function can be called with a Key // as argument, and the result be assigned to a u32 enum is_valid_hash_function(Key, alias fn) = __traits(compiles, (Key k){ u32 u = fn(k); }); D lets you refer to other template parameters in the same template parameter list in three cases, as far as I know: 1) A type may be a subtype of an earlier parameter: class C {} struct S(TBase, TDerived : TBase) {} S!(Object, C) a; 2) A type parameter with a type specialization followed by template parameter list: struct Fn(U) {} struct S(T: Fn!Arg, Arg) {} S!(Fn!int) a; 3) Following a type parameter, a value parameter of that type may appear: struct S(T, T value) {} S!(int, 4) a; The first two can also be combined: struct Fn(U) {} struct S(T1, T2: Fn!T3, T3 : T1) {} S!(int, Fn!int) a; However, it seems 3) only works with that specific type, modulo storage classes. No Foo!T, no void delegate(T). At any rate, the alias parameter is the way it's generally done, and is more flexible, so just leave it at that. -- Simen
Re: Include http based module
On Friday, 19 February 2021 at 19:20:39 UTC, tcak wrote: I have written a test module and put it into /var/www/html: module mymodule; import std.stdio; void testMe(){ writeln("I tested you!"); } Then I have a main file where I would like to call the function "testMe". My build line is as follows: dmd main.d "http://localhost/mymodule.d"; Result: Error: module mymodule is in file 'http://localhost/mymodule.d' which cannot be read import path[0] = /usr/include/dmd/phobos import path[1] = /usr/include/dmd/druntime/import Is there any way to include http(s) based modules into compilation (Please do not suggest dub etc)? If you *desperately* wanted that I guess you could map it via some fs-network driver or similar.
Templated delegate as template argument for structs
I have the following struct declaration: struct Hash_Table(Key, Value, u32 delegate(ref Key) custom_hash_function = null){ ... } When I try to instance the Type like this: Hash_Table!(Component*, Component_Tick_Info, (c) => hash32(c.handle.bitfield)) my_hash_table; I get the following compile error source\vbl.d(2338): Error: undefined identifier `Key` source\vessel.d(840):while looking for match for `__lambda4!Key` source\vessel.d(840):while looking for match for `Hash_Table!(Component*, Component_Tick_Info, (c) => hash32(c.handle.bitfield))` vbl.d(2338) is the line of the struct declaration. I take it from the error that the problem is not actually the delegate that I am passing, but the fact that the delegate type has another template parameter as the argument type. Can template arguments in D not reference previous template arguments? Is there some way I can get around this?
Re: Class instance alignment
On 20/02/2021 8:13 PM, tsbockman wrote: Well, that's just another reason not to use the GC for my current project, then: I'm using 256-bit AVX vectors extensively. You can still use the GC. You just can't use it to allocate the classes you care about. https://dlang.org/phobos/core_memory.html#.GC.addRange