Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 07, 2005 bit fields in struct | ||||
---|---|---|---|---|
| ||||
C struct has bit fields ability, e.g typedef struct tag_SCRIPT_STATE { WORD uBidiLevel :5; WORD fOverrideDirection :1; WORD fInhibitSymSwap :1; WORD fCharShape :1; WORD fDigitSubstitute :1; WORD fInhibitLigate :1; WORD fDisplayZWG :1; WORD fArabicNumContext :1; WORD fGcpClusters :1; WORD fReserved :1; WORD fEngineReserved :2; } SCRIPT_STATE; the C code sizeof(SCRIPT_STATE) results 2 According to D spec, no bit fields in D struct http://www.digitalmars.com/d/struct.html The question is how to implement the bit fileds operation around D struct. Declare a WORD, then wrapper bitwise method with this WORD ? |
November 07, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shawn Liu | On Mon, 7 Nov 2005 06:59:22 +0000 (UTC), Shawn Liu <Shawn_member@pathlink.com> wrote:
> C struct has bit fields ability, e.g
>
> typedef struct tag_SCRIPT_STATE {
> WORD uBidiLevel :5;
> WORD fOverrideDirection :1;
> WORD fInhibitSymSwap :1;
> WORD fCharShape :1;
> WORD fDigitSubstitute :1;
> WORD fInhibitLigate :1;
> WORD fDisplayZWG :1;
> WORD fArabicNumContext :1;
> WORD fGcpClusters :1;
> WORD fReserved :1;
> WORD fEngineReserved :2;
> } SCRIPT_STATE;
>
> the C code sizeof(SCRIPT_STATE) results 2
>
> According to D spec, no bit fields in D struct
> http://www.digitalmars.com/d/struct.html
>
> The question is how to implement the bit fileds operation around D struct.
> Declare a WORD, then wrapper bitwise method with this WORD ?
Here is what I did once:
struct DCB {
DWORD DCBlength; /* sizeof(DCB) */
DWORD BaudRate; /* Baudrate at which running */
uint BITS;
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
DWORD fParity: 1; /* Enable parity checking */
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
DWORD fDtrControl:2; /* DTR Flow control */
DWORD fDsrSensitivity:1; /* DSR Sensitivity */
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
DWORD fInX: 1; /* Enable input X-ON/X-OFF */
DWORD fErrorChar: 1; /* Enable Err Replacement */
DWORD fNull: 1; /* Enable Null stripping */
DWORD fRtsControl:2; /* Rts Flow control */
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
DWORD fDummy2:17; /* Reserved */
WORD wReserved; /* Not currently used */
WORD XonLim; /* Transmit X-ON threshold */
WORD XoffLim; /* Transmit X-OFF threshold */
BYTE ByteSize; /* Number of bits/byte, 4-8 */
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */
char XonChar; /* Tx and Rx X-ON character */
char XoffChar; /* Tx and Rx X-OFF character */
char ErrorChar; /* Error replacement char */
char EofChar; /* End of Input character */
char EvtChar; /* Received Event character */
WORD wReserved1; /* Fill for now. */
}
alias DCB* LPDCB;
void fBinary(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,0) : btr(&dcb.BITS,0); }
void fParity(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,1) : btr(&dcb.BITS,1); }
void fOutxCtsFlow(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,2) : btr(&dcb.BITS,2); }
void fOutxDsrFlow(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,3) : btr(&dcb.BITS,3); }
void fDtrControl(DCB* dcb, uint b) { (bt(&b,0)) ? bts(&dcb.BITS,4) : btr(&dcb.BITS,4); (bt(&b,1)) ? bts(&dcb.BITS,5) : btr(&dcb.BITS,5); }
void fDsrSensitivity(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,6) : btr(&dcb.BITS,6); }
void fTXContinueOnXoff(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,7) : btr(&dcb.BITS,7); }
void fOutX(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,8) : btr(&dcb.BITS,8); }
void fInX(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,9) : btr(&dcb.BITS,9); }
void fErrorChar(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,10) : btr(&dcb.BITS,10); }
void fNull(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,11) : btr(&dcb.BITS,11); }
void fRtsControl(DCB* dcb, uint b) { (bt(&b,0)) ? bts(&dcb.BITS,12) : btr(&dcb.BITS,12); (bt(&b,1)) ? bts(&dcb.BITS,13) : btr(&dcb.BITS,13); }
void fAbortOnError(DCB* dcb, uint b) { (b) ? bts(&dcb.BITS,14) : btr(&dcb.BITS,14); }
So, BITS replaces all the bit fields and methods replace all access to the bits.
Hope it helps.
Regan
|
November 07, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shawn Liu | Shawn Liu wrote:
>
> The question is how to implement the bit fileds operation around D struct.
> Declare a WORD, then wrapper bitwise method with this WORD ?
Use bit arrays.
Sean
|
November 07, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | In article <opszuzgtvj23k2f5@nrage.netwin.co.nz>, Regan Heath says... > >On Mon, 7 Nov 2005 06:59:22 +0000 (UTC), Shawn Liu <Shawn_member@pathlink.com> wrote: >> C struct has bit fields ability, e.g >> >> typedef struct tag_SCRIPT_STATE { >> >> The question is how to implement the bit fileds operation around D >> struct. >> Declare a WORD, then wrapper bitwise method with this WORD ? > >Here is what I did once: >>So, BITS replaces all the bit fields and methods replace all access to the >bits. > >Hope it helps. > >Regan Well done. Thanks! |
November 07, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shawn Liu | On Mon, 7 Nov 2005 08:05:49 +0000 (UTC), Shawn Liu <Shawn_member@pathlink.com> wrote:
> In article <opszuzgtvj23k2f5@nrage.netwin.co.nz>, Regan Heath says...
>>
>> On Mon, 7 Nov 2005 06:59:22 +0000 (UTC), Shawn Liu
>> <Shawn_member@pathlink.com> wrote:
>>> C struct has bit fields ability, e.g
>>>
>>> typedef struct tag_SCRIPT_STATE {
>>>
>>> The question is how to implement the bit fileds operation around D
>>> struct.
>>> Declare a WORD, then wrapper bitwise method with this WORD ?
>>
>> Here is what I did once:
>>> So, BITS replaces all the bit fields and methods replace all access to the
>> bits.
>>
>> Hope it helps.
>>
>> Regan
>
>
> Well done. Thanks!
Ooops I forgot to comment out the bit fields in the struct I posted, that'll teach me for copy/pasting them from the original source instead of my slightly modified one. Just remove/comment the bitfields and you have what I have. Sorry.
Regan
|
November 07, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Sun, 06 Nov 2005 23:24:06 -0800, Sean Kelly <sean@f4.ca> wrote: > Shawn Liu wrote: >> The question is how to implement the bit fileds operation around D struct. >> Declare a WORD, then wrapper bitwise method with this WORD ? > > Use bit arrays. It's a nice idea but I found that it didn't really work that well. I asked this same question once before here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.learn/1503 Using this struct: struct DCB { DWORD DCBlength; /* sizeof(DCB) */ DWORD BaudRate; /* Baudrate at which running */ DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ DWORD fParity: 1; /* Enable parity checking */ DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ DWORD fDtrControl:2; /* DTR Flow control */ DWORD fDsrSensitivity:1; /* DSR Sensitivity */ DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ DWORD fInX: 1; /* Enable input X-ON/X-OFF */ DWORD fErrorChar: 1; /* Enable Err Replacement */ DWORD fNull: 1; /* Enable Null stripping */ DWORD fRtsControl:2; /* Rts Flow control */ DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ DWORD fDummy2:17; /* Reserved */ WORD wReserved; /* Not currently used */ WORD XonLim; /* Transmit X-ON threshold */ WORD XoffLim; /* Transmit X-OFF threshold */ BYTE ByteSize; /* Number of bits/byte, 4-8 */ BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ char XonChar; /* Tx and Rx X-ON character */ char XoffChar; /* Tx and Rx X-OFF character */ char ErrorChar; /* Error replacement char */ char EofChar; /* End of Input character */ char EvtChar; /* Received Event character */ WORD wReserved1; /* Fill for now. */ } alias DCB* LPDCB; Ideally I'd like to be able to say: struct DCB { ..etc.. bit[32] BITS; alias BITS[0] fBinary; alias BITS[1] fParity; } and so on, then use them like so: void main() { DCB d; d.fBinary = 1; d.fParity = 0; } I tried a number of things but couldn't come up with anything short of writing methods for each bitfield, meaning you end up with a getter and setter for every bit, ick. The best implementation I found was what posted to the other branch of this thread, and I guess I could have used a bit array there, but the intrinsic functions seemed better somehow. Regan |
November 07, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath wrote:
>
> I tried a number of things but couldn't come up with anything short of writing methods for each bitfield, meaning you end up with a getter and setter for every bit, ick.
True, but at least D has properties... and the methods don't affect the size of the struct. I suppose it's a toss-up whether size concerns are better addressed by an enum and get/set methods or per-bit properties. The enum method has the advantage of being more easily maintainable however.
Sean
|
November 08, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | In article <opszu3vig823k2f5@nrage.netwin.co.nz>, Regan Heath says... > >Ideally I'd like to be able to say: > >struct DCB { > ..etc.. > bit[32] BITS; > alias BITS[0] fBinary; > alias BITS[1] fParity; >} > >and so on, then use them like so: > >void main() { > DCB d; > d.fBinary = 1; > d.fParity = 0; >} > The compiler complains that : bits_struct.d(3): BITS is used as a type bits_struct.d(4): BITS is used as a type |
November 08, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath Attachments:
| "Regan Heath" <regan@netwin.co.nz> wrote:opszuzgtvj23k2f5@nrage.netwin.co.nz... > On Mon, 7 Nov 2005 06:59:22 +0000 (UTC), Shawn Liu <Shawn_member@pathlink.com> wrote: >> C struct has bit fields ability, e.g >> >> typedef struct tag_SCRIPT_STATE { >> WORD uBidiLevel :5; template BITWISE(T) { // bit value set void btvs(T* pData, uint bitnum, uint val){ *pData &= ~(0x01 << bitnum); if(val) *pData |= (0x01 << bitnum); } // bit value get T btvg(T* data, uint bitnum){ return cast(T)((*data >> bitnum) & 0x01); } } alias BITWISE!(BYTE).btvs btvs; alias BITWISE!(WORD).btvs btvs; alias BITWISE!(DWORD).btvs btvs; alias BITWISE!(BYTE).btvg btvg; alias BITWISE!(WORD).btvg btvg; alias BITWISE!(DWORD).btvg btvg; struct SCRIPT_STATE { WORD data; // getter uint uBidiLevel() { return cast(uint)(data & 0x1F);} uint fOverrideDirection() { return btvg(data, 5); } uint fInhibitSymSwap() { return btvg(data, 6); } uint fCharShape() { return btvg(data, 7); } uint fDigitSubstitute() { return btvg(data, 8); } uint fInhibitLigate() { return btvg(data, 9); } uint fDisplayZWG() { return btvg(data, 10); } uint fArabicNumContext() { return btvg(data, 11); } uint fGcpClusters() { return btvg(data, 12); } uint fReserved() { return btvg(data, 13); } uint fEngineReserved() { return 0; }//do nothing with reserved // setter void uBidiLevel(uint val) { data &= 0xFFE0; data |= (val & 0x1F); } void fOverrideDirection(uint val) { btvs(&data, 5, val); } void fInhibitSymSwap(uint val) { btvs(&data, 6, val); } void fCharShape(uint val) { btvs(&data, 7, val); } void fDigitSubstitute(uint val) { btvs(&data, 8, val); } void fInhibitLigate(uint val) { btvs(&data, 9, val); } void fDisplayZWG(uint val) { btvs(&data, 10, val); } void fArabicNumContext(uint val) { btvs(&data, 11, val); } void fGcpClusters(uint val) { btvs(&data, 12, val); } void fReserved(uint val) { btvs(&data, 13, val); } void fEngineReserved(uint val) { } //do nothing with reserved } |
November 09, 2005 Re: bit fields in struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to Shawn Liu | Shawn Liu wrote: <snip> > According to D spec, no bit fields in D struct > http://www.digitalmars.com/d/struct.html > > The question is how to implement the bit fileds operation around D struct. > Declare a WORD, then wrapper bitwise method with this WORD ? http://www.digitalmars.com/d/dstyle.html "Meaningless Type Aliases Things like: alias void VOID; alias int INT; alias int* pint; should be avoided." Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit. |
Copyright © 1999-2021 by the D Language Foundation