www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - bit fields in struct

reply Shawn Liu <Shawn_member pathlink.com> writes:
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
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
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
next sibling parent reply Shawn Liu <Shawn_member pathlink.com> writes:
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  

Hope it helps. Regan

Well done. Thanks!
Nov 07 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
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

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
Nov 07 2005
prev sibling parent "Shawn Liu" <shawn666.liu gmail.com> writes:
Content-Type: text/plain;
	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:
 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 &=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 }
Nov 08 2005
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
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
parent reply "Regan Heath" <regan netwin.co.nz> writes:
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: 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
Nov 07 2005
next sibling parent Sean Kelly <sean f4.ca> writes:
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
prev sibling parent Shawn Liu <Shawn_member pathlink.com> writes:
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
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
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