digitalmars.D - bit fields in struct
- Shawn Liu (19/19) Nov 06 2005 C struct has bit fields ability, e.g
- Regan Heath (65/85) Nov 06 2005 Here is what I did once:
- Shawn Liu (2/16) Nov 07 2005 Well done. Thanks!
- Regan Heath (7/28) Nov 07 2005 Ooops I forgot to comment out the bit fields in the struct I posted,
- Shawn Liu (50/56) Nov 08 2005 charset="iso-8859-15"
- Sean Kelly (3/6) Nov 06 2005 Use bit arrays.
- Regan Heath (56/61) Nov 07 2005 It's a nice idea but I found that it didn't really work that well.
- Sean Kelly (6/10) Nov 07 2005 True, but at least D has properties... and the methods don't affect the
- Shawn Liu (4/17) Nov 07 2005 The compiler complains that :
- Stewart Gordon (18/23) Nov 09 2005 http://www.digitalmars.com/d/dstyle.html
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 ?
Nov 06 2005
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
Nov 06 2005
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:Well done. Thanks!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 thebits. Hope it helps. Regan
Nov 07 2005
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...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. ReganOn Mon, 7 Nov 2005 06:59:22 +0000 (UTC), Shawn Liu <Shawn_member pathlink.com> wrote:Well done. Thanks!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 thebits. Hope it helps. Regan
Nov 07 2005
charset="iso-8859-15" Content-Transfer-Encoding: quoted-printable "Regan Heath" <regan netwin.co.nz> = wrote:opszuzgtvj23k2f5 nrage.netwin.co.nz...On Mon, 7 Nov 2005 06:59:22 +0000 (UTC), Shawn Liu =20 <Shawn_member pathlink.com> wrote:template BITWISE(T) { // bit value set void btvs(T* pData, uint bitnum, uint val){ *pData &=3D ~(0x01 << bitnum); if(val) *pData |=3D (0x01 << bitnum);=20 } // 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 &=3D 0xFFE0; data |=3D (val & 0x1F); = } void fOverrideDirection(uint val) { btvs(&data, 5, val); }=20 void fInhibitSymSwap(uint val) { btvs(&data, 6, val); }=20 void fCharShape(uint val) { btvs(&data, 7, val); }=20 void fDigitSubstitute(uint val) { btvs(&data, 8, val); }=20 void fInhibitLigate(uint val) { btvs(&data, 9, val); }=20 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 }C struct has bit fields ability, e.g typedef struct tag_SCRIPT_STATE { WORD uBidiLevel :5;
Nov 08 2005
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
Nov 06 2005
On Sun, 06 Nov 2005 23:24:06 -0800, Sean Kelly <sean f4.ca> wrote:Shawn Liu wrote: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. ReganThe 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.
Nov 07 2005
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
Nov 07 2005
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
Nov 07 2005
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.
Nov 09 2005