How can I get this UDA at compile time?

2021-02-20 Thread Jack via Digitalmars-d-learn

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

2021-02-20 Thread kinke via Digitalmars-d-learn
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

2021-02-20 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2021-02-20 Thread Mike Brown via Digitalmars-d-learn

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

2021-02-20 Thread Mike Brown via Digitalmars-d-learn
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

2021-02-20 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2021-02-20 Thread Simon van Bernem via Digitalmars-d-learn
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

2021-02-20 Thread Simen Kjærås via Digitalmars-d-learn
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

2021-02-20 Thread Imperatorn via Digitalmars-d-learn

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

2021-02-20 Thread Simon van Bernem via Digitalmars-d-learn

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

2021-02-20 Thread rikki cattermole via Digitalmars-d-learn

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