From be3550dfe0cf8b1781d11652167e5616acfee3b8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 19 Mar 2007 17:12:50 +0000 Subject: [PATCH] Ditched read or write only subbitfields for now since they were proving difficult to implement. Allow component Bitfields to be instantiated without templates, clean up the implementation a little, and adjust the comments to match. --HG-- extra : convert_revision : b9b8aea285a95eeabbb4c0233c1bce49b8c773b8 --- src/base/bitfield.hh | 172 ++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 94 deletions(-) diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 408882a51..ff816286f 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -131,15 +131,16 @@ findMsbSet(uint64_t val) { } // The following implements the BitUnion system of defining bitfields -//on top of an underlying class. This is done through the extensive use of +//on top of an underlying class. This is done through the pervasive use of //both named and unnamed unions which all contain the same actual storage. //Since they're unioned with each other, all of these storage locations //overlap. This allows all of the bitfields to manipulate the same data -//without having to know about each other. More details are provided with the +//without having to have access to each other. More details are provided with the //individual components. //This namespace is for classes which implement the backend of the BitUnion -//stuff. Don't use any of this directly! Use the macros at the end instead. +//stuff. Don't use any of these directly, except for the Bitfield classes in +//the *BitfieldTypes class(es). namespace BitfieldBackend { //A base class for all bitfields. It instantiates the actual storage, @@ -169,57 +170,64 @@ namespace BitfieldBackend } }; - //A class which specializes a given base so that it can only be read - //from. This is accomplished by only passing through the conversion - //operator and explicitly making sure the assignment operator is blocked. - template - class _BitfieldRO : public Base + //This class contains all the "regular" bitfield classes. It is inherited + //by all BitUnions which give them access to those types. + template + class RegularBitfieldTypes { - private: - const Type - operator=(const Type & _data); - - public: - operator const Type () + protected: + //This class implements ordinary bitfields, that is a span of bits + //who's msb is "first", and who's lsb is "last". + template + class Bitfield : public BitfieldBase { - return *((Base *)this); - } - }; - - //Similar to the above, but only allows writing. - template - class _BitfieldWO : public Base - { - private: - operator const Type (); - - public: - const Type operator=(const Type & _data) + public: + operator const Type () + { + return this->getBits(first, last); + } + + const Type + operator=(const Type & _data) + { + this->setBits(first, last, _data); + return _data; + } + }; + + //A class which specializes the above so that it can only be read + //from. This is accomplished explicitly making sure the assignment + //operator is blocked. The conversion operator is carried through + //inheritance. This will unfortunately need to be copied into each + //bitfield type due to limitations with how templates work + template + class BitfieldRO : public Bitfield { - *((Base *)this) = _data; - return _data; - } - }; - - //This class implements ordinary bitfields, that is a span of bits - //who's msb is "first", and who's lsb is "last". - template - class _Bitfield : public BitfieldBase - { - public: - operator const Data () - { - return this->getBits(first, last); - } - - const Data - operator=(const Data & _data) + private: + const Type + operator=(const Type & _data); + }; + + //Similar to the above, but only allows writing. + template + class BitfieldWO : public Bitfield { - this->setBits(first, last, _data); - return _data; - } + private: + operator const Type (); + + public: + const Type operator=(const Type & _data) + { + *((Bitfield *)this) = _data; + return _data; + } + }; }; + template + class BitfieldTypes : public RegularBitfieldTypes + {}; + //When a BitUnion is set up, an underlying class is created which holds //the actual union. This class then inherits from it, and provids the //implementations for various operators. Setting things up this way @@ -275,7 +283,9 @@ namespace BitfieldBackend { \ class name; \ } \ - class BitfieldUnderlyingClasses::name { \ + class BitfieldUnderlyingClasses::name : \ + public BitfieldBackend::BitfieldTypes \ + { \ public: \ typedef type __DataType; \ union { \ @@ -296,58 +306,32 @@ namespace BitfieldBackend //__data member functions like the "underlying storage" of the top level //BitUnion. Like everything else, it overlays with the top level storage, so //making it a regular bitfield type makes the entire thing function as a -//regular bitfield when referred to by itself. The operators are defined in -//the macro itself instead of a class for technical reasons. If someone -//determines a way to move them to one, please do so. -#define __SubBitUnion(type, name) \ +//regular bitfield when referred to by itself. +#define __SubBitUnion(fieldType, first, last, name) \ + class : public BitfieldBackend::BitfieldTypes<__DataType> \ + { \ + public: \ union { \ - type __data; \ - inline operator const __DataType () \ - { return __data; } \ - \ - inline const __DataType operator = (const __DataType & _data) \ - { __data = _data; } + fieldType __data; //This closes off the union created above and gives it a name. Unlike the top //level BitUnion, we're interested in creating an object instead of a type. -#define EndSubBitUnion(name) } name; - -//The preprocessor will treat everything inside of parenthesis as a single -//argument even if it has commas in it. This is used to pass in templated -//classes which typically have commas to seperate their parameters. -#define wrap(guts) guts - -//Read only bitfields -//This wraps another bitfield class inside a _BitfieldRO class using -//inheritance. As explained above, the _BitfieldRO class only passes through -//the conversion operator, so the underlying bitfield can then only be read -//from. -#define __BitfieldRO(base) \ - BitfieldBackend::_BitfieldRO<__DataType, base> -#define __SubBitUnionRO(name, base) \ - __SubBitUnion(wrap(_BitfieldRO<__DataType, base>), name) - -//Write only bitfields -//Similar to above, but for making write only versions of bitfields with -//_BitfieldWO. -#define __BitfieldWO(base) \ - BitfieldBackend::_BitfieldWO<__DataType, base> -#define __SubBitUnionWO(name, base) \ - __SubBitUnion(wrap(_BitfieldWO<__DataType, base>), name) +//The operators are defined in the macro itself instead of a class for +//technical reasons. If someone determines a way to move them to one, please +//do so. +#define EndSubBitUnion(name) \ + }; \ + inline operator const __DataType () \ + { return __data; } \ + \ + inline const __DataType operator = (const __DataType & _data) \ + { __data = _data; } \ + } name; //Regular bitfields -//This uses all of the above to define macros for read/write, read only, and -//write only versions of regular bitfields. -#define Bitfield(first, last) \ - BitfieldBackend::_Bitfield<__DataType, first, last> +//These define macros for read/write regular bitfield based subbitfields. #define SubBitUnion(name, first, last) \ - __SubBitUnion(Bitfield(first, last), name) -#define BitfieldRO(first, last) __BitfieldRO(Bitfield(first, last)) -#define SubBitUnionRO(name, first, last) \ - __SubBitUnionRO(Bitfield(first, last), name) -#define BitfieldWO(first, last) __BitfieldWO(Bitfield(first, last)) -#define SubBitUnionWO(name, first, last) \ - __SubBitUnionWO(Bitfield(first, last), name) + __SubBitUnion(Bitfield, first, last, name) //Use this to define an arbitrary type overlayed with bitfields. #define BitUnion(type, name) __BitUnion(type, name) -- 2.30.2