Jump to page: 1 2
Thread overview
C to D: please help translate this weird macro
Sep 20
Ki Rill
Sep 20
Ki Rill
Sep 21
Ki Rill
Sep 21
Ki Rill
Sep 21
user1234
Sep 22
Ki Rill
Sep 20
ryuukk_
Sep 22
Ki Rill
Sep 23
Ki Rill
September 20

Here is the macro:

#define NK_CONTAINER_OF(ptr,type,member)\
    (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))

I'm trying to translate the Nuklear GUI library to D here.

September 20

On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote:

>

Here is the macro:

#define NK_CONTAINER_OF(ptr,type,member)\
    (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))

I'm trying to translate the Nuklear GUI library to D here.

Here is how NK_OFFSETOF is defined:

#define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
September 20

On Wednesday, 20 September 2023 at 13:55:14 UTC, Ki Rill wrote:

>

On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote:

>

Here is the macro:

#define NK_CONTAINER_OF(ptr,type,member)\
    (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))

I'm trying to translate the Nuklear GUI library to D here.

Here is how NK_OFFSETOF is defined:

#define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))

Looks like you are not the only one who has issue with them:

https://github.com/Immediate-Mode-UI/Nuklear/issues/94

https://github.com/Immediate-Mode-UI/Nuklear/pull/309

September 20

On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote:

>

Here is the macro:

#define NK_CONTAINER_OF(ptr,type,member)\
    (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))

I'm trying to translate the Nuklear GUI library to D here.

My workflow when trying to port weird C code to D is to have a small C file, put an example code, and then run the preprocessor, and try to get how things are expanded

Alternatively, latest version of visual studio allows you to see that in real time, you'll still have to write example code tho

https://devblogs.microsoft.com/cppblog/visualize-macro-expansion-for-c/

September 20

On Wednesday, 20 September 2023 at 13:55:14 UTC, Ki Rill wrote:

>

On Wednesday, 20 September 2023 at 13:53:08 UTC, Ki Rill wrote:

>

Here is the macro:

#define NK_CONTAINER_OF(ptr,type,member)\
    (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))

I'm trying to translate the Nuklear GUI library to D here.

Here is how NK_OFFSETOF is defined:

#define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))

NK_OFFSETOF is the same as D's struct .offsetof attribute.

NK_CONTAINER_OF should probably be translated to:

cast(T*)((cast(void*)ptr - __traits(getMember, T, member).offsetof))

PS. I did not invent this. My original idea was far worse than this. - It was suggested on IRC by a much cleverer D programmer than myself - Herringway@IRC

September 21

On Wednesday, 20 September 2023 at 17:14:41 UTC, Dejan Lekic wrote:

>

[...]

NK_CONTAINER_OF should probably be translated to:

cast(T*)((cast(void*)ptr - __traits(getMember, T, member).offsetof))

PS. I did not invent this. My original idea was far worse than this. - It was suggested on IRC by a much cleverer D programmer than myself - Herringway@IRC

Thanks! I translated it to this originally after looking at the links you've provided:

auto nk_container_of(P, T)(P ptr, T type, size_t member_offsetof)
{
    return cast(T*)(cast(void*)(cast(char*)(1 ? (ptr) : ptr - member_offsetof)));
}
>

cast(T*)((cast(void*)ptr - __traits(getMember, T, member).offsetof))

Now, how should I wrap it like a macro? Template mixin? I'm not that familiar with D meta programming... I shall skim through the D templates tutorial for hints.

September 21

On Thursday, 21 September 2023 at 02:23:32 UTC, Ki Rill wrote:

>

wrote:

>

[...]

Translated it to this eventually:

auto nk_container_of(P, T)(P ptr, T type, const(char)* member)
{
    return cast(T*)(cast(void*)(cast(char*)
        (ptr - __traits(getMember, type, member).offsetof)));
}
September 21

On Thursday, 21 September 2023 at 02:57:07 UTC, Ki Rill wrote:

>

On Thursday, 21 September 2023 at 02:23:32 UTC, Ki Rill wrote:

>

wrote:

>

[...]

Translated it to this eventually:

auto nk_container_of(P, T)(P ptr, T type, const(char)* member)
{
    return cast(T*)(cast(void*)(cast(char*)
        (ptr - __traits(getMember, type, member).offsetof)));
}

The 1st argument of getMember can just be T, like the original macro.
The 2nd argument needs to be a compile-time string.
Also the char* cast needs to apply to ptr before subtracting the offset AFAICS.

So reordering to keep type inference of ptr:

auto nk_container_of(T, string member, P)(P ptr)
{
    return cast(T*)(cast(void*)(cast(char*)ptr -
        __traits(getMember, T, member).offsetof)));
}

(Untested)

September 21

On Thursday, 21 September 2023 at 16:28:25 UTC, Nick Treleaven wrote:

>
return cast(T*)(cast(void*)(cast(char*)ptr -
    __traits(getMember, T, member).offsetof)));

There's a trailing ) that needs removing. Also pretty sure it can be simplified to:

return cast(T*)(cast(char*)ptr -
    __traits(getMember, T, member).offsetof);
September 21

On Thursday, 21 September 2023 at 16:28:25 UTC, Nick Treleaven wrote:

>

(Untested)

There might be a need this error

« First   ‹ Prev
1 2