www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to translate this C macro to D mixin/template mixin?

reply VitaliiY <yvitaliy1980 yandex.ru> writes:
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<<a)-1)); \
         numbits += (a); \
         STOREBITS \
       }
Jun 15
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Jun 15
parent VitaliiY <yvitaliy1980 yandex.ru> writes:
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.
Jun 15
prev sibling parent reply Dennis <dkorpel gmail.com> writes:
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")); ```
Jun 15
parent reply VitaliiY <yvitaliy1980 yandex.ru> writes:
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.
Jun 15
parent Tejas <notrealemail gmail.com> writes:
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/pro erty.html#stringof) property. That should do it.
Jun 16