Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r52554 - in sandbox/bitfield: boost/integer libs/integer/doc libs/integer/example libs/integer/test
From: vicente.botet_at_[hidden]
Date: 2009-04-22 17:24:13


Author: viboes
Date: 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
New Revision: 52554
URL: http://svn.boost.org/trac/boost/changeset/52554

Log:
Boost.Bitfield V0.1
Added:
   sandbox/bitfield/boost/integer/bitfield.hpp (contents, props changed)
   sandbox/bitfield/boost/integer/bitfield_dcl.hpp (contents, props changed)
   sandbox/bitfield/boost/integer/endian_bitfield_value_type.hpp.hpp (contents, props changed)
   sandbox/bitfield/libs/integer/doc/Jamfile.v2 (contents, props changed)
   sandbox/bitfield/libs/integer/doc/bitfield.qbk (contents, props changed)
   sandbox/bitfield/libs/integer/example/
   sandbox/bitfield/libs/integer/test/Jamfile.v2 (contents, props changed)
   sandbox/bitfield/libs/integer/test/bitfield_test.cpp (contents, props changed)

Added: sandbox/bitfield/boost/integer/bitfield.hpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/boost/integer/bitfield.hpp 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
@@ -0,0 +1,327 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Emile Cormier 2006.
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or
+// copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTEGER_BITFIELD__HPP
+#define BOOST_INTEGER_BITFIELD__HPP
+
+#include <cstddef>
+#include <boost/static_assert.hpp>
+//#include <boost/ref.hpp>
+
+#include <limits>
+#include <netinet/in.h>
+
+namespace boost { namespace integer {
+
+ template <typename T>
+ struct bitfield_value_type {
+ typedef T type;
+ };
+
+ //-----------------------------------------------------------------------------
+ template <class, std::size_t, std::size_t, class, class> class bitfield;
+
+ #if 0
+ template <class R, class V>
+ class bitfield_bit_proxy {
+ public:
+ bitfield_bit_proxy& operator=(bool state) {
+ field_ &= ~mask_;
+ if (state) field_ |= mask_;
+ return *this;
+ }
+
+ operator bool() const {
+ return (field_ & mask_) != 0;
+ }
+
+ bool operator~() const {return !(static_cast<bool>(*this));}
+
+ private:
+ R field_;
+ V mask_;
+
+ bitfield_bit_proxy(R f, V mask) : field_(f), mask_(mask) {
+ std::cout << "field_=" << std::hex << field_ << std::endl;
+ std::cout << "mask_=" << mask_ << std::endl;
+ }
+
+ template <class, std::size_t, std::size_t, class, class> friend class bitfield;
+ };
+
+ template <typename T> struct reference_traits;
+
+ template <typename T> struct reference_traits<const T&> {
+ typedef T value_type;
+ };
+ template <typename T> struct reference_traits<T&> {
+ typedef T value_type;
+ };
+
+ template <typename C> struct reference_traits {
+ typedef typename C::value_type value_type;
+ };
+ #endif
+
+ namespace detail {
+ template <bool is_signed, typename value_type
+ , typename storage_type, unsigned int WIDTH, unsigned int SIGN_MASK>
+ struct bitfield_complete_signed;
+
+ template <typename value_type, typename storage_type, unsigned int WIDTH, unsigned int SIGN_MASK>
+ struct bitfield_complete_signed<true, value_type, storage_type, WIDTH, SIGN_MASK> {
+ static value_type convert(storage_type val) {
+ if( (val>>(WIDTH-1))!=0) {
+ return (val | SIGN_MASK);
+ } else {
+ return val;
+ }
+ }
+ };
+
+ template <typename value_type, typename storage_type, unsigned int WIDTH, unsigned int SIGN_MASK>
+ struct bitfield_complete_signed<false, value_type, storage_type, WIDTH, SIGN_MASK> {
+ static value_type convert(storage_type val) {
+ return val;
+ }
+ };
+ }
+
+ //------------------------------------------------------------------------------
+ /*!
+ Used to easily manipulate groups of bits the same way as does C bitfields,
+ but in a portable manner.
+ \par Example declaration:
+ \code
+ struct Rgb565
+ {
+ typedef volatile uint16_t storage_type;
+ storage_type storage;
+ typedef volatile uint16_t value_type;
+ BOOST_BITFIELD_DCL(storage_type, storage, unsigned char, red, 0, 4);
+ BOOST_BITFIELD_DCL(storage_type, storage, unsigned char, green, 5, 10);
+ BOOST_BITFIELD_DCL(storage_type, storage, unsigned char, blue, 11,15);
+ };
+ \endcode
+ \par Example usage:
+ \code
+ Rgb565 r;
+ r.storage= 0xffff;
+
+ // Write to a bitfield. Note that parenthesis are needed around the bitfield so
+ r.red() = 23;
+
+ // Read from a bitfield
+ Rgb565::value_type b = r.blue();
+
+ // Access a bit within a bit field
+ bool bit = r.blue()[3];
+ \endcode
+ \note Bitfields within the same word may overlap.
+ \param STORAGE_TYPE Unsigned integer type of the word occupied by the bitfield
+ \param F Position of the first bit (0 is the least significant bit)
+ \param L Position of the last bit (0 is the least significant bit)
+ \param VALUE_TYPE Value type of the bitfield itself
+ \param REFERENCE_TYPE Reference type of the word occupied by the bitfield
+ */
+
+
+ /* concept ReferenceType {
+ * typedef value_type;
+ * operator value_type();
+ * ReferenceType operator=(ReferenceType rhs);
+ * ReferenceType(ReferenceType rhs);
+ * };
+ * */
+
+ template <typename STORAGE_TYPE, std::size_t F, std::size_t L
+ , typename VALUE_TYPE=typename bitfield_value_type<STORAGE_TYPE>::type
+ , typename REFERENCE_TYPE=VALUE_TYPE&>
+ class bitfield {
+ typedef bitfield<STORAGE_TYPE, F, L, VALUE_TYPE, REFERENCE_TYPE> this_type;
+ public:
+ //! storage type of the bitfield support
+ typedef STORAGE_TYPE storage_type;
+ //! Value type of the bitfield itself
+ typedef VALUE_TYPE value_type;
+ //! Reference type of the bitfield itself
+ typedef REFERENCE_TYPE reference_type;
+
+ private:
+
+ // the storage type must be unsigned
+ BOOST_STATIC_ASSERT( std::numeric_limits<storage_type>::is_signed==false );
+ // first and last index must be on the range corresponding to the storage_type
+ BOOST_STATIC_ASSERT( F < 8*sizeof(storage_type) );
+ BOOST_STATIC_ASSERT( L < 8*sizeof(storage_type) );
+ BOOST_STATIC_ASSERT( F <= L );
+ // The bitfield width can be stored on the value_type
+ BOOST_STATIC_ASSERT( (L - F + 1) <= 8*sizeof(value_type) );
+
+ static storage_type value_to_storage(value_type val) {
+ storage_type res =val;
+ return ((res & VAL_MASK) << LASTD);
+ }
+
+ static value_type storage_to_value(storage_type field) {
+ storage_type val = (field & FIELD_MASK) >> LASTD;
+ return detail::bitfield_complete_signed<std::numeric_limits<value_type>::is_signed, value_type, storage_type, WIDTH, SIGN_MASK>::convert(val);
+ }
+
+ void set_bit(std::size_t index, bool state) {
+ field_ &= ~value_to_storage(1<<index);
+ if (state) field_ |= value_to_storage(1<<index);
+ }
+
+ bool get_bit(std::size_t index) {
+ return (field_ & value_to_storage(1<<index)) != 0;
+ }
+
+ template <typename BITFIELD>
+ class bitfield_bit_proxy {
+ public:
+ bitfield_bit_proxy& operator=(bool state) {
+ field_.set_bit(index_, state);
+ }
+
+ operator bool() const {
+ return field_.get_bit(index_);
+ }
+
+ private:
+ BITFIELD& field_;
+ std::size_t index_;
+
+ bitfield_bit_proxy(BITFIELD& f, std::size_t index) : field_(f), index_(index) {}
+
+ template <class, std::size_t, std::size_t, class, class> friend class bitfield;
+ };
+ typedef bitfield_bit_proxy<this_type> bit_reference_type;
+ typedef bitfield_bit_proxy<const this_type> bit_const_reference_type;
+
+
+ //! private because a reference is nedeed
+ bitfield();
+
+ public:
+
+
+ //! Useful constants
+ static const std::size_t FIRST = F; //!< Position of the first bit
+ static const std::size_t LAST = L; //!< Position of the last bit
+ static const std::size_t STS = 8*sizeof(storage_type);
+ static const std::size_t LASTD = STS-LAST-1;
+ static const std::size_t WIDTH = LAST - FIRST + 1; //!< Width in bits of the bitfield
+ static const std::size_t VAL_MASK = (1 << WIDTH) - 1; //!< Mask applied against assigned values
+ static const std::size_t FIELD_MASK = (VAL_MASK << LASTD); //!< Mask of the field's bit positions
+ static const std::size_t SIGN_MASK = ~VAL_MASK; //!< Sign mask applied against assigned values
+ static const value_type MIN_VAL = std::numeric_limits<value_type>::is_signed?value_type((1<<(WIDTH-1))-1):0; //!< min value that can be represented with the bitfield
+ static const value_type MAX_VAL = std::numeric_limits<value_type>::is_signed?value_type(1<<(WIDTH-1)):(1<<(WIDTH))-1; //!< max value that can be represented with the bitfield
+
+ //! explicit constructor from a reference
+ explicit bitfield(storage_type& field) : field_(field) {
+ }
+
+ //! setter from a value type
+ void set(value_type val) {
+ field_ = (field_ & ~FIELD_MASK) | value_to_storage(val);
+ }
+ //! Assignment from a value type
+ bitfield& operator=(value_type val) {
+ field_ = (field_ & ~FIELD_MASK) | value_to_storage(val);
+ return *this;
+ }
+
+ //! Returns the bitfield value.
+ operator value_type() const {
+ return storage_to_value(field_);
+ }
+
+ value_type get() const {
+ return storage_to_value(field_);
+ }
+
+ //! Returns the negative of the bitfield value.
+ // this must be modified on the case of signed value_type
+ value_type operator~() const {return storage_to_value(~field_);}
+
+ #if 0
+ bit_reference_type operator[](std::size_t index) {
+ return bit_reference_type(field_, value_to_storage(1 << index));
+ }
+
+ bit_const_reference_type operator[](std::size_t index) const {
+ assert(index < WIDTH);
+ return bit_const_reference_type(field_, value_to_storage(1 << index));
+ }
+ #else
+ bit_reference_type operator[](std::size_t index) {
+ return bit_reference_type(*this,index);
+ }
+
+ bit_const_reference_type operator[](std::size_t index) const {
+ assert(index < WIDTH);
+ return bit_const_reference_type(*this, index);
+ }
+ #endif
+
+ //! Returns the current bitfield value as bit flags.
+ /*! The returned bit flags can be ORed with other bit flags. */
+ storage_type flags() const {return field_ & FIELD_MASK;}
+
+ //! Returns the given bitfield value as bit flags.
+ /*! The returned bit flags can be ORed with other bit flags. */
+ static storage_type get_flags(value_type val) {return value_to_storage(val);}
+
+ static std::size_t first() {return FIRST;}
+ static std::size_t last() {return LAST;}
+ static std::size_t width() {return WIDTH;}
+ static storage_type val_mask() {return VAL_MASK;}
+ static storage_type field_mask() {return FIELD_MASK;}
+
+ //! Arithmetic-assign operators
+ bitfield& operator++() {*this += 1; return *this;}
+ value_type operator++(int) {value_type ret(*this); ++*this; return ret;}
+
+ bitfield& operator--() {*this -= 1; return *this;}
+ value_type operator--(int) {value_type ret(*this); --*this; return ret;}
+
+ bitfield& operator+=(value_type rhs) {*this = value_type(*this) + rhs; return *this;}
+ bitfield& operator-=(value_type rhs) {*this = value_type(*this) - rhs; return *this;}
+
+ bitfield& operator*=(value_type rhs) {*this = value_type(*this) * rhs; return *this;}
+ bitfield& operator/=(value_type rhs) {*this = value_type(*this) / rhs; return *this;}
+ bitfield& operator%=(value_type rhs) {*this = value_type(*this) % rhs; return *this;}
+
+ bitfield& operator<<=(int rhs) {*this = value_type(*this) << rhs; return *this;}
+ bitfield& operator>>=(int rhs) {*this = value_type(*this) >> rhs; return *this;}
+
+ bitfield& operator&=(value_type rhs) {*this = value_type(*this) & rhs; return *this;}
+ bitfield& operator|=(value_type rhs) {*this = value_type(*this) | rhs; return *this;}
+ bitfield& operator^=(value_type rhs) {*this = value_type(*this) ^ rhs; return *this;}
+
+ private:
+ storage_type& field_;
+ };
+
+
+ template <typename STORAGE_TYPE, std::size_t F, std::size_t L
+ , typename VALUE_TYPE=typename bitfield_value_type<STORAGE_TYPE>::type
+ >
+ struct bitfield_traits {
+ typedef bitfield<STORAGE_TYPE, F, L, VALUE_TYPE> reference;
+ typedef bitfield<const STORAGE_TYPE, F, L, VALUE_TYPE> value;
+ };
+
+}}
+#endif
+

Added: sandbox/bitfield/boost/integer/bitfield_dcl.hpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/boost/integer/bitfield_dcl.hpp 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
@@ -0,0 +1,13 @@
+#ifndef BOOST_INTEGER_BITFIELD_DCL__HPP
+#define BOOST_INTEGER_BITFIELD_DCL__HPP
+
+#include <boost/integer/bitfield.hpp>
+
+#define BOOST_BITFIELD_DCL(STORAGE_TYPE, STORAGE_VAR, VALUE_TYPE, FIELD, F, L) \
+ typedef boost::integer::bitfield_traits<STORAGE_TYPE,F,L,VALUE_TYPE> FIELD##_type; \
+ FIELD##_type::reference FIELD() { return FIELD##_type::reference(STORAGE_VAR); } \
+ FIELD##_type::value::value_type FIELD() const { return FIELD##_type::value(word).get(); } \
+ void set_##FIELD(VALUE_TYPE& val) { FIELD##_type::reference(STORAGE_VAR).set(val); } \
+ FIELD##_type::value::value_type get_##FIELD() const { return FIELD##_type::value(word).get(); }
+
+#endif

Added: sandbox/bitfield/boost/integer/endian_bitfield_value_type.hpp.hpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/boost/integer/endian_bitfield_value_type.hpp.hpp 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
@@ -0,0 +1,17 @@
+#ifndef BOOST_INTEGER_BITFIELD__HPP
+#define BOOST_INTEGER_BITFIELD__HPP
+
+#include <cstddef>
+#include <boost/integer/endian.hpp>
+#include <boost/bitfield.hpp>
+
+namespace boost { namespace integer {
+
+ template <endianness E, typename T, std::size_t n_bits, alignment A>
+ struct bitfield_value_type<endian<E,T,n_bits,A> > {
+ typedef typename endian<E,T,n_bits,A>::value_type type;
+ };
+
+}}
+#endif
+

Added: sandbox/bitfield/libs/integer/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/bitfield/libs/integer/doc/Jamfile.v2 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
@@ -0,0 +1,72 @@
+# Boost.LUID library documentation Jamfile ---------------------------------
+#
+# Copyright Vicente J. Botet Escriba 2009. Use, modification and
+# distribution is subject to the Boost Software License, Version
+# 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+# See http://www.boost.org for updates, documentation, and revision history.
+
+#import doxygen ;
+import quickbook ;
+
+#doxygen autodoc
+# :
+# [ glob ../../../boost/interprocess/*.hpp ]
+# [ glob ../../../boost/interprocess/allocators/*.hpp ]
+# :
+# <doxygen:param>EXTRACT_ALL=NO
+# <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+# <doxygen:param>EXTRACT_PRIVATE=NO
+# <doxygen:param>EXPAND_ONLY_PREDEF=YES
+# <doxygen:param>PREDEFINED=BOOST_INTERPROCESS_DOXYGEN_INVOKED
+# <xsl:param>"boost.doxygen.reftitle=Boost.Interprocess Reference"
+# ;
+
+xml bitfield : bitfield.qbk ;
+
+boostbook standalone
+ :
+ bitfield
+ :
+ # HTML options first:
+ # Use graphics not text for navigation:
+ <xsl:param>navig.graphics=1
+ # How far down we chunk nested sections, basically all of them:
+ <xsl:param>chunk.section.depth=2
+ # Don't put the first section on the same page as the TOC:
+ <xsl:param>chunk.first.sections=1
+ # How far down sections get TOC's
+ <xsl:param>toc.section.depth=4
+ # Max depth in each TOC:
+ <xsl:param>toc.max.depth=2
+ # How far down we go with TOC's
+ <xsl:param>generate.section.toc.level=10
+ # Path for links to Boost:
+ <xsl:param>boost.root=../../../..
+ # Path for libraries index:
+ <xsl:param>boost.libraries=../../../../libs/libraries.htm
+ # Use the main Boost stylesheet:
+ <xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
+
+ # PDF Options:
+ # TOC Generation: this is needed for FOP-0.9 and later:
+ #<xsl:param>fop1.extensions=1
+ # Or enable this if you're using XEP:
+ <xsl:param>xep.extensions=1
+ # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
+ <xsl:param>fop.extensions=0
+ # No indent on body text:
+ <xsl:param>body.start.indent=0pt
+ # Margin size:
+ <xsl:param>page.margin.inner=0.5in
+ # Margin size:
+ <xsl:param>page.margin.outer=0.5in
+ # Yes, we want graphics for admonishments:
+ <xsl:param>admon.graphics=1
+ # Set this one for PDF generation *only*:
+ # default pnd graphics are awful in PDF form,
+ # better use SVG's instead:
+ <format>pdf:<xsl:param>admon.graphics.extension=".svg"
+ <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
+ ;

Added: sandbox/bitfield/libs/integer/doc/bitfield.qbk
==============================================================================
--- (empty file)
+++ sandbox/bitfield/libs/integer/doc/bitfield.qbk 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
@@ -0,0 +1,693 @@
+[/
+ / Copyright (c) 2008 Vicente J. Botet Escriba
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[library Boost.Bitfield
+ [quickbook 1.3]
+ [authors [Botet Escriba, Vicente J.]]
+ [copyright 2009 Vicente J. Botet Escriba]
+ [id boost.bitfield]
+ [dirname integer]
+ [purpose Bitfield traits]
+ [license
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ [@http://www.boost.org/LICENSE_1_0.txt])
+ ]
+]
+
+
+[/
+[section Preface]
+
+[:[".]]
+[:[*['-- ]]]
+
+[endsect]
+/]
+
+[warning Bitfield is not a part of the Boost libraries.]
+
+[/========================]
+[section Overview]
+[/========================]
+
+[/==================]
+[heading Description]
+[/==================]
+
+Portable bitfields.
+
+The main source of inspiration of this library was Boost.Bitfield from Emile Cormier.
+
+[*Boost.Bitfield] provides:
+
+* a generic bitfield traits class providing generic getter and setter.
+* a BOOST_BITFIELD_DCL macro making easier the definition of the bitfield helper type and the bitfield getter and setter functions.
+
+
+[/====================================]
+[heading How to Use This Documentation]
+[/====================================]
+
+This documentation makes use of the following naming and formatting conventions.
+
+* Code is in `fixed width font` and is syntax-highlighted.
+* Replaceable text that you will need to supply is in [~italics].
+* If a name refers to a free function, it is specified like this:
+ `free_function()`; that is, it is in code font and its name is followed by `()` to indicate that it is a free function.
+* If a name refers to a class template, it is specified like this: `class_template<>`; that is, it is in code font and its name is followed by `<>` to indicate that it is a class template.
+* If a name refers to a function-like macro, it is specified like this: `MACRO()`;
+ that is, it is uppercase in code font and its name is followed by `()` to indicate that it is a function-like macro. Object-like macros appear without the trailing `()`.
+* Names that refer to /concepts/ in the generic programming sense are specified in CamelCase.
+
+[note In addition, notes such as this one specify non-essential information that provides additional background or rationale.]
+
+Finally, you can mentally add the following to any code fragments in this document:
+
+ // Include all of Bitfield files
+ #include <boost/integer/bitfield.hpp>
+ #include <boost/integer/bitfield_dcl.hpp>
+
+[section Motivation]
+
+In order for an application or a device driver to use the same source code base on both platforms, it must either be endian neutral, or use conditional compilation to select appropriate code modules. A program module is considered endian neutral if it retains its functionality while being ported across platforms of different endianness. In other words, there is no relation between its functionality and the endianness of the platform it is running on.
+Endianness issues become important when porting the pieces of the application that relate to client communication over a heterogeneous network, persistent data storage on the disk, product tracing (it is important that trace generated on SPARC gets formatted correctly on x86) and other related areas.
+
+Boost.Endian handles with most of the issues related to the byte ordering, but do not manage the bit ordering. E.g. the following structure has a different layout in big and little endian machines.
+
+ struct X {
+ unsigned int d00:1;
+ unsigned int d01:7;
+ unsigned int d02:2;
+ unsigned int d03:6;
+ unsigned int d04:4;
+ unsigned int d05:4;
+ unsigned int d06:1;
+ unsigned int d07:3;
+ unsigned int d08:4;
+ };
+
+In order to make this structure endian neutral, we need to use conditional compilation, and swap on byte level of the fields
+
+
+ struct X {
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int d00:1;
+ unsigned int d01:7;
+ unsigned int d02:2;
+ unsigned int d03:6;
+ unsigned int d04:4;
+ unsigned int d05:4;
+ unsigned int d06:1;
+ unsigned int d07:3;
+ unsigned int d08:4;
+ #else
+ unsigned int d01:7;
+ unsigned int d00:1;
+ unsigned int d03:6;
+ unsigned int d02:2;
+ unsigned int d05:4;
+ unsigned int d04:4;
+ unsigned int d08:4;
+ unsigned int d07:3;
+ unsigned int d06:1;
+ #endif
+ }
+
+The preceding technique can be applied as far as the bitfield is contained on a byte boundary. But for bitfields using several bytes as
+
+ struct X {
+ unsigned int d00:11;
+ unsigned int d01:21;
+ };
+
+There is no way using conditional compilation to to adapt the structure and preserve the fields.
+
+Two approaches can be considered:
+
+[heading Decompose the fields not defined on a byte boundary on several bitfield defined on a byte boundary]
+
+ struct X {
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int d00_b0:8;
+ unsigned int d00_b1:3;
+ unsigned int d01_b0:5;
+ unsigned int d01_b1:8;
+ unsigned int d01_b2:8;
+ #else
+ unsigned int d01_b2:8;
+ unsigned int d01_b1:8;
+ unsigned int d01_b0:5;
+ unsigned int d00_b1:3;
+ unsigned int d00_b0:8;
+ #endif
+ };
+
+and define a way to access the bitfield information of the ENDIAN_UNSAFE structure. This library do not use this apprach.
+
+[heading Replace the bitfields by the integer type]
+
+When it is possible, a suggestion would be to transform the bitfields into integers, as follows:
+
+ struct X {
+ #ifdef ATRIUM_PORTABLE
+ unsigned int d0;
+ #else
+ unsigned int d00:11; /* ENDIAN_UNSAFE */
+ unsigned int d01:21; /* ENDIAN_UNSAFE */
+ #endif
+ };
+
+and define a way to access the bitfield information.
+
+When the structure is used by a C++ program, all the uses of the bit fields (d00 and d01) could be replaced by an inline function, so
+
+ y = x.d00;
+
+could be replaced by
+
+ y = x.d00();
+
+or
+
+ y = x.get_d00();
+
+and
+ x.d00= y;
+
+could be replaced by
+
+ x.d00()= y;
+
+or
+
+ x.set_d00(y)
+
+where
+
+ struct X {
+ typedef boost::ubig_32 storage_type;
+ storage_type d0;
+ typedef unsigned int value_type;
+ BOOST_BITFIELD_DCL(storage_type, d0, unsigned int, d00, 0, 10);
+ BOOST_BITFIELD_DCL(storage_type, d0, unsigned int, d01, 11, 31);
+ };
+
+
+The goal of Boost.Bitfield is to make possible this simple portable translation.
+
+[endsect]
+[endsect]
+
+[/==============================]
+[section:users_guide Users'Guide]
+[/==============================]
+
+[/======================================]
+[section:getting_started Getting Started]
+[/======================================]
+
+[/======================================]
+[section:install Installing Bitfield]
+[/======================================]
+
+[/=================================]
+[heading Getting Boost.Bitfield]
+[/=================================]
+
+You can get the last stable release of Boost.Bitfield by downloading [^bitfield.zip] from the
+[@http://www.boost-consulting.com/vault/index.php?directory=Endianess%20Programming Boost Vault]
+
+You can also access the latest (unstable?) state from the [@https://svn.boost.org/svn/boost/sandbox/bitfield Boost Sandbox].
+
+[/=================================]
+[heading Building Boost.Bitfield]
+[/=================================]
+
+There is no need to compile [*Boost.Bitfield], since it's a header only library. Just include your Boost header directory in your compiler include path.
+
+[/=========================]
+[heading Requirements]
+[/=========================]
+
+[*Boost.Bitfield] depends on some Boost library. For these specific parts you must use either Boost version 1.38.0 or the version in SVN trunk (even if older version should works also).
+
+
+[/========================]
+[heading Exceptions safety]
+[/========================]
+
+All functions in the library are exception-neutral and provide strong guarantee of exception safety as long as
+the underlying parameters provide it.
+
+[/====================]
+[heading Thread safety]
+[/====================]
+
+All functions in the library are thread-unsafe except when noted explicitly.
+
+
+[/=======================]
+[heading Tested compilers]
+[/=======================]
+
+Currently, [*Boost.Bitfield] has been tested in the following compilers/platforms:
+
+* GCC 3.4.4 Cygwin
+* GCC 3.4.6 Linux
+[/* GCC 4.3.2 Cygwin]
+* GCC 4.1.2 Linux
+
+[note Please send any questions, comments and bug reports to boost <at> lists <dot> boost <dot> org.]
+
+[endsect]
+[/=============================]
+[section Hello World! ]
+[/=============================]
+
+
+[endsect]
+
+[endsect]
+
+[section Tutorial]
+
+[section Declaring a storage variable]
+
+ struct Rgb565
+ {
+ typedef ubig16_t storage_type;
+ storage_type storage;
+ };
+
+[endsect]
+
+[section Bitfieds helper classes and bitfield accessors]
+
+[heading Declaring a bitfield helper type]
+
+ struct Rgb565
+ {
+ //...
+ typedef bitfield_traits<storage_type, 0, 4, unsigned char> red_type;
+ };
+
+
+[heading bitfield getters]
+
+ struct Rgb565
+ {
+ //...
+ red_type::value::value_type red() const { return red_type::value(storage).get(); }
+ red_type::value::value_type get_red() const { return red_type::value(storage).get(); }
+ };
+
+[heading bitfield setters]
+
+ struct Rgb565
+ {
+ //...
+ red_type::reference red() { return red_type::reference(storage); }
+ void set_red(unsigned char val) { return red_type::reference(storage).set(val); }
+ };
+
+
+
+[endsect]
+
+[section Using macros to declare portable bitfields ]
+
+ struct Rgb565
+ {
+ typedef volatile uint16_t storage_type;
+ storage_type storage;
+ typedef volatile uint16_t value_type;
+ BOOST_BITFIELD_DCL(storage_type, storage, unsigned char, red, 0, 4);
+ BOOST_BITFIELD_DCL(storage_type, storage, unsigned char, green, 5, 10);
+ BOOST_BITFIELD_DCL(storage_type, storage, unsigned char, blue, 11,15);
+ };
+
+[endsect]
+
+[section Using bitfield getters and setters]
+
+ Rgb565 r;
+ r.storage= 0xffff;
+
+ // Write to a bitfield. Note that parenthesis are needed around the bitfield so
+ r.red() = 23;
+
+ // Read from a bitfield
+ Rgb565::value_type b = r.blue();
+
+ // Access a bit within a bit field
+ bool bit = r.blue()[3];
+
+[endsect]
+
+[endsect]
+
+
+[section:ext_references References]
+[variablelist
+
+[
+ [[@http://www.boost.org/libs/integer/endian.htm [*Boost.Endian]]]
+ [general integer-like byte-holder binary types with explicit control over byte order, value type, size, and alignment from Beman Dawes]
+]
+
+
+]
+
+[endsect]
+
+[endsect]
+
+
+[section Reference]
+[/==========================================================================================]
+[section:bitfield_hpp Header `<boost/integer/bitfield.hpp>`]
+[/==========================================================================================]
+
+This is the main file of Boost.Bitfield, which includes the definition of the bitfield<> class.
+
+ template <typename T>
+ struct bitfield_default_value_type;
+
+ template <class, std::size, std::size, class, bool, class>
+ class bitfield;
+
+ template <class T, class R, class V>
+ class bitfield_bit_proxy;
+
+ template <typename STORAGE_TYPE, int F, int L
+ , typename VALUE_TYPE=bitfield_default_value_type<typename STORAGE_TYPE::type>
+ >
+ strcut bitfield_traits;
+
+[/==========================================================================================]
+[section:bitfield_default_value_type Metafunction `bitfield_default_value_type<>`]
+[/==========================================================================================]
+
+The default value type associated to an storage type is the storage type.
+
+ template <typename T>
+ struct bitfield_value_type {
+ typedef T type;
+ };
+
+The user could need to specialize this metafunction for some specific types.
+
+[endsect]
+
+[/==========================================================================================]
+[section:bitfield_default_value_type Template class `bitfield<>`]
+[/==========================================================================================]
+
+The bitfield class is a wrapper to an storage type that allows to get/set a bitfield of a given value type defined by the first and last bit that the bitfield occupes in the strogae type. It defines the conversion to the bitfield value type as weel as all the arithmetic assignement operators.
+
+This template class behaves as a reference to a bitfield. Note that C/C++ do not allows to take directly the address of a bit field.
+
+ template <typename STORAGE_TYPE, std::size F, std::size L
+ , typename VALUE_TYPE=typename bitfield_value_type<typename STORAGE_TYPE::type>
+ , typename REFERENCE_TYPE=STORAGE_TYPE&>
+ class bitfield {
+ public:
+ //! Reference type of the word occupied by the bitfield
+ typedef REFERENCE_TYPE reference_type;
+ //! Value type of the bitfield itself
+ typedef VALUE_TYPE value_type;
+ //! storage type of the bitfield support
+ typedef typename reference_traits<REFERENCE_TYPE>::value_type storage_type;
+
+ //! Useful constants
+ static const unsigned int FIRST; //!< Position of the first bit
+ static const unsigned int LAST; //!< Position of the last bit
+ static const unsigned int STS;
+ static const unsigned int LASTD;
+ static const unsigned int WIDTH; //!< Width in bits of the bitfield
+ static const unsigned int VAL_MASK; //!< Mask applied against assigned values
+ static const unsigned int SIGN_MASK; //!< Sign Mask applied against assigned values
+ static const value_type MIN_VAL; //!< min value that can be represented with the bitfield
+ static const value_type MAX_VAL; //!< max value that can be represented with the bitfield
+ static const unsigned int FIELD_MASK; //!< Mask of the field's bit positions
+
+ static std::size_t first();
+ static std::size_t last();
+ static std::size_t width();
+ static storage_type val_mask();
+ static storage_type field_mask();
+
+ //! deleted because a reference is nedeed
+ bitfield() = delete;
+ //! explicit constructor from a reference
+ explicit bitfield(reference_type field);
+
+ //! Assignment from a value type
+ bitfield& operator=(value_type val);
+
+ //! value_type implicit conversion
+ operator value_type() const;
+
+ //! value_type explicit getter
+ value_type get() const;
+
+ //! Returns the negative of the bitfield value.
+ // this must be modified on the case of signed value_type
+ value_type operator~() const;
+
+ bit_reference_type operator[](std::size_t index);
+
+ bit_const_reference_type operator[](std::size_t index) const;
+
+ //! Returns the current bitfield value as bit flags.
+ /*! The returned bit flags can be ORed with other bit flags. */
+ storage_type flags() const;
+
+ //! Returns the current bitfield value as bit flags.
+ /*! The returned bit flags can be ORed with other bit flags. */
+ static storage_type flags(value_type val) const;
+
+ //! Arithmetic-assign operators
+ bitfield& operator++();
+ value_type operator++(int);
+
+ bitfield& operator--();
+ value_type operator--(int);
+
+ bitfield& operator+=(value_type rhs);
+ bitfield& operator-=(value_type rhs);
+
+ bitfield& operator*=(value_type rhs);
+ bitfield& operator/=(value_type rhs);
+ bitfield& operator%=(value_type rhs);
+
+ bitfield& operator<<=(int rhs);
+ bitfield& operator>>=(int rhs);
+
+ bitfield& operator&=(value_type rhs);
+ bitfield& operator|=(value_type rhs);
+ bitfield& operator^=(value_type rhs);
+ };
+
+[endsect]
+
+[/==========================================================================================]
+[section:bitfield_bit_proxy Template class `bitfield_bit_proxy<>`]
+[/==========================================================================================]
+
+This template class behaves as a reference to a bitfield bit. Note that C/C++ do not allows to take directly the address of a bit field. The class takes a reference to the storage and the index of the bit.
+
+ template <class T, class R, class V>
+ class bitfield_bit_proxy {
+ public:
+ bitfield_bit_proxy& operator=(bool state);
+
+ operator bool() const;
+ };
+
+
+[endsect]
+
+[/==========================================================================================]
+[section:bitfield_traits Template class `bitfield_traits<>`]
+[/==========================================================================================]
+
+This traits class defies two traits:
+
+* reference: used to modify a bitfield
+* value: used to get the value of a bitset
+
+ template <typename STORAGE_TYPE, int F, int L
+ , typename VALUE_TYPE=typename bitfield_value_type<typename STORAGE_TYPE::type>
+ >
+ struct bitfield_traits {
+ typedef bitfield<STORAGE_TYPE, F, L, VALUE_TYPE> reference;
+ typedef bitfield<const STORAGE_TYPE, F, L, VALUE_TYPE> value;
+ };
+
+[endsect]
+
+[endsect]
+
+[/==========================================================================================]
+[section:bitfield_dcl_hpp Header `<boost/integer/bitfield_dcl.hpp>`]
+[/==========================================================================================]
+
+This file constains the macro making easier the definition of the bitfield helper type and the bitfield getter and setter functions.
+
+ #define BOOST_BITFIELD_DCL(STORAGE_TYPE, STORAGE_VAR, VALUE_TYPE, FIELD, F, L)
+
+[/==========================================================================================]
+[section:BOOST_BITFIELD_DCL Macro `BOOST_BITFIELD_DCL`]
+[/==========================================================================================]
+
+ #define BOOST_BITFIELD_DCL(STORAGE_TYPE, STORAGE_VAR, VALUE_TYPE, FIELD, F, L)
+
+* Parameters
+ * STORAGE_TYPE: the type to store the bitfield
+ * STORAGE_VAR: the variable used to store the bitfield
+ * VALUE_TYPE: the type for the bitfield
+ * FIELD: the name of the bitfield
+ * F: the first bit
+ * L: the last bit
+
+* Effect
+This macro defines the bitfield traits and the functions necessary to make valid the following expressions:
+ * str.FIELD() = value;
+ * var= str.FIELD();
+ * str.set_FIELD(var);
+ * var= str.get_FIELD()
+
+
+Two styles of getter/setter are provided: one using overloading on the field name, the other suning clasical prefic get_/set_.
+
+[endsect]
+
+[endsect]
+
+[/==========================================================================================]
+[section:endian_bitfield_value_type_hpp Header `<boost/integer/endian_bitfield_value_type.hpp>`]
+[/==========================================================================================]
+
+This file includes the customization for the endian types for the bitfield_default_value_type metafunction. You need to include this file if you use endian types as storage for the bitfields.
+
+ template <endianness E, typename T, std::size_t n_bits, alignment A>
+ struct bitfield_value_type<endian<E,T,n_bits,A> > {
+ typedef typename endian<E,T,n_bits,A>::value_type type;
+ };
+
+[endsect]
+
+[endsect]
+
+[section Examples]
+[section bitfield signed value type]
+[SIGNED__HPP]
+
+[endsect]
+
+[endsect]
+
+[/=================]
+[section Appendices]
+[/=================]
+[section:history Appendix A: History]
+[section [*Version 0.1.0, April 25, 2009] ['Announcement of Bitfield]]
+
+[*Features:]
+
+* a generic bitfield traits class providing generic getter and setter for portable bitfields.
+* a BOOST_BITFIELD_DCL macro making easier the definition of the bitfield helper type and the bitfield getter and setter functions.
+
+[endsect]
+[endsect]
+
+[section:rationale Appendix B: Rationale]
+
+[heading Why we can not declare portable bitfields ?]
+
+[endsect]
+
+[section:implementation Appendix C: Implementation Notes]
+
+[heading Why we can not declare portable bitfields ?]
+
+[heading FAQ]
+
+* Why bother with endian bitfields ?
+
+External data portability and both speed and space efficiency.
+Availability of bit order representations is important in some applications.
+
+* Why not just use Boost.Serialization?
+
+Serialization involves a conversion for every object involved in I/O. Endian objects require no conversion or copying. They are already in the desired format for binary I/O. Thus they can be read or written in bulk.
+
+* Do these types have any uses outside of I/O?
+
+Probably not.
+
+* Is there is a performance hit when doing arithmetic using these types?
+
+Yes, for sure, compared to arithmetic operations on native bitfields integer types.
+However, these types are usually faster, and sometimes much faster, for I/O compared to stream inserters and extractors, or to serialization.
+
+* These types are really just byte-holders. Why provide the arithmetic operations at all?
+
+Providing a full set of operations reduces program clutter and makes code both easier to write and to read. Consider incrementing a variable in a record. It is very convenient to write:
+
+ ++record.foo();
+
+Rather than:
+
+ int temp( record.foo());
+ ++temp;
+ record.foo() = temp;
+
+[heading Design considerations for Boost.Endian]
+
+* Must provide exactly the size and internal bit ordering specified.
+* It is better software engineering if the same implementation works regardless of the CPU endianness. In other words, #ifdefs should be avoided where possible.
+
+[endsect]
+[section:acknowledgements Appendix D: Acknowledgements]
+
+Thanks to Emile Cormier whic was the initiator of this library.
+
+[endsect]
+[section Appendix E: Tests]
+
+[section aligned bitfields]
+[table
+ [[Name] [kind] [Description] [Result] [Ticket]]
+ [[get] [run] [check assign_to works for builting types] [Pass] [#]]
+ [[assign] [run] [check convert_to works for builting types] [Pass] [#]]
+]
+[endsect]
+
+
+[endsect]
+[section Appendix F: Tickets]
+
+[endsect]
+
+[/=====================================]
+[section:todo Appendix F: Future plans]
+[/=====================================]
+
+[heading Tasks to do before review]
+
+
+[heading For later releases]
+
+
+[endsect]
+[endsect]
+
+
+

Added: sandbox/bitfield/libs/integer/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/bitfield/libs/integer/test/Jamfile.v2 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
@@ -0,0 +1,49 @@
+#
+# Boost.Bitfield
+# Build script for tests.
+#
+# Copyright (c) 2008-2009 Vicente J. Botet Escriba]
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+using testing ;
+
+if ! $(BOOST_ROOT)
+{
+ BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
+}
+
+# bjam -V2 threading=multi target-os=cygwin threadapi=pthread variant=debug
+
+project :
+ : requirements
+ <include>$(BOOST_ROOT)
+ <include>../../..
+# <include>/cvs/wss100/build_temp/botet/boost/boost_1_38_0/
+ <include>/home/Vicente/boost/boost_1_38_0/
+
+ <include>$(BOOST_SANDBOX)/endian
+
+ <threading>multi
+# <target-os>cygwin
+ #<threadapi>pthread
+ <variant>debug
+
+ #<library>/boost/test//boost_unit_test_framework/<link>static
+ #<library>/boost/thread//boost_thread/<link>static
+ #<library>$(BOOST_SANDBOX)/libs/chrono/build//boost_chrono/<link>static
+
+ #<library>$(BOOST_ROOT)/libs/test/build//boost_unit_test_framework/<link>static
+# <library>/cvs/wss100/build_temp/botet/boost/boost_1_38_0/libs/test/build//boost_unit_test_framework/<link>static
+# <library>../../../../../boost_1_38_0/libs/thread/build//boost_thread/<link>static
+# <library>../../../../../boost_1_38_0/libs/system/build//boost_system/<link>static
+
+;
+
+
+
+
+test-suite "bitfield" :
+ [ run bitfield_test.cpp ]
+ ;
+

Added: sandbox/bitfield/libs/integer/test/bitfield_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/libs/integer/test/bitfield_test.cpp 2009-04-22 17:24:12 EDT (Wed, 22 Apr 2009)
@@ -0,0 +1,320 @@
+#include <iostream>
+#include <cassert>
+#include "boost/integer/bitfield.hpp"
+#include "boost/integer/bitfield_dcl.hpp"
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+#define ASSERT_EQUALS(a,b) assert((a) == (b))
+#define ASSERT_UNEQUALS(a,b) assert((a) != (b))
+#define ASSERT(a) assert((a))
+
+//typedef unsigned short uint16_t;
+//typedef unsigned char uint8_t;
+
+struct Register
+{
+ typedef uint16_t T;
+ T word;
+ struct STR {
+ uint8_t f:3;
+ uint16_t m:9;
+ uint32_t l:4;
+ };
+ union {
+ uint16_t padd;
+ STR value;
+ } s, sl;
+
+ typedef boost::integer::bitfield_traits<T, 0, 2, uint8_t> f_type;
+ typedef boost::integer::bitfield_traits<T, 3, 11> m_type;
+ typedef boost::integer::bitfield_traits<T, 12, 15, uint32_t> l_type;
+ typedef boost::integer::bitfield_traits<T, 0, 7> high_type;
+ typedef boost::integer::bitfield_traits<T, 4, 11> mid_type; // Intentionally overlap
+ typedef boost::integer::bitfield_traits<T, 8, 15> low_type;
+ typedef boost::integer::bitfield_traits<T, 0, 15> all_type;
+ typedef boost::integer::bitfield_traits<T, 4, 4> single_type;
+ //typedef bitfield_traits<T, 2, 4, signed char> ss_type;
+ typedef boost::integer::bitfield_traits<T, 2, 4, signed char> ss_type;
+
+ f_type::reference f() { return f_type::reference(s.padd); }
+ l_type::reference l() { return l_type::reference(s.padd); }
+ m_type::reference m() { return m_type::reference(s.padd); }
+
+ high_type::reference high() { return high_type::reference(word); }
+ mid_type::reference mid() { return mid_type::reference(word); }
+ low_type::reference low() { return low_type::reference(word); }
+ all_type::reference all() { return all_type::reference(word); }
+ single_type::reference single() { return single_type::reference(word); }
+ ss_type::reference ss() { return ss_type::reference(word); }
+
+
+ f_type::value::value_type f() const { return f_type::value(word).get(); }
+ l_type::value::value_type l() const { return l_type::value(word).get(); }
+ m_type::value::value_type m() const { return m_type::value(word).get(); }
+ high_type::value::value_type high() const { return high_type::value(word).get(); }
+ mid_type::value::value_type mid() const { return mid_type::value(word).get(); }
+ low_type::value::value_type low() const { return low_type::value(word).get(); }
+ all_type::value::value_type all() const { return all_type::value(word).get(); }
+ single_type::value::value_type single() const { return single_type::value(word).get(); }
+ ss_type::value::value_type ss() const { return ss_type::value(word).get(); }
+
+
+};
+
+struct Register2
+{
+ typedef uint32_t T;
+ T word;
+ struct STR {
+ unsigned char f:3;
+ uint16_t m:9;
+ int32_t l:4;
+ };
+ union {
+ uint32_t padd;
+ STR value;
+ } s, sl;
+
+ BOOST_BITFIELD_DCL(uint32_t, word, unsigned char, f, 0, 2);
+ BOOST_BITFIELD_DCL(uint32_t, word, uint32_t, m, 3, 11);
+ BOOST_BITFIELD_DCL(uint32_t, word, uint32_t, l, 12, 15);
+
+ typedef boost::integer::bitfield_traits<T, 0, 7> high_type;
+ typedef boost::integer::bitfield_traits<T, 4, 11> mid_type; // Intentionally overlap
+ typedef boost::integer::bitfield_traits<T, 8, 15> low_type;
+ typedef boost::integer::bitfield_traits<T, 0, 15> all_type;
+ typedef boost::integer::bitfield_traits<T, 4, 4> single_type;
+ typedef boost::integer::bitfield_traits<T, 2, 4, signed char> ss_type;
+
+ high_type::reference high() { return high_type::reference(word); }
+ mid_type::reference mid() { return mid_type::reference(word); }
+ low_type::reference low() { return low_type::reference(word); }
+ all_type::reference all() { return all_type::reference(word); }
+ single_type::reference single() { return single_type::reference(word); }
+ ss_type::reference ss() { return ss_type::reference(word); }
+
+ high_type::value::value_type high() const { return high_type::value(word).get(); }
+ mid_type::value::value_type mid() const { return mid_type::value(word).get(); }
+ low_type::value::value_type low() const { return low_type::value(word).get(); }
+ all_type::value::value_type all() const { return all_type::value(word).get(); }
+ single_type::value::value_type single() const { return single_type::value(word).get(); }
+ ss_type::value::value_type ss() const { return ss_type::value(word).get(); }
+
+
+};
+
+
+namespace
+{
+ Register r;
+}
+
+void test_tt()
+{
+ Register r;
+ // 0001|0001|0001|0010
+
+ r.s.padd=0x1112;
+ std::cout << "f=" << std::hex << int(r.s.value.f) << std::endl;
+ std::cout << "m=" << std::hex << int(r.s.value.m) << std::endl;
+ std::cout << "l=" << std::hex << int(r.s.value.l) << std::endl;
+
+ r.s.padd=0x1112;
+ // 0001|001000110|100
+ std::cout << "f()=" << std::hex << int(r.f()) << std::endl;
+ std::cout << "m()=" << std::hex << int(r.m()) << std::endl;
+ std::cout << "l()=" << std::hex << int(r.l()) << std::endl;
+
+
+ //ASSERT_EQUALS(0, 1);
+
+}
+
+//-----------------------------------------------------------------------------
+void test_assign()
+{
+ r.word = 0;
+ r.high() = 0x12;
+ //printf("word=%x\n",int(r.word));
+ //printf("all=%x\n",int(r.all()));
+ ASSERT_EQUALS(r.all(), 0x1200);
+ r.low() = 0x34;
+ //printf("word=%x\n",int(r.word));
+ //printf("all=%x\n",int(r.all()));
+ ASSERT_EQUALS(r.all(), 0x1234);
+ r.mid() = 0xab;
+ //printf("word=%x\n",int(r.word));
+ //printf("all=%x\n",int(r.all()));
+
+ ASSERT_EQUALS(r.all(), 0x1ab4);
+ r.all() = 0x4321;
+ //printf("word=%x\n",int(r.word));
+ //printf("all=%x\n",int(r.all()));
+ ASSERT_EQUALS(r.all(), 0x4321);
+ r.single() = 1;
+ //printf("word=%x\n",int(r.word));
+ //printf("all=%x\n",int(r.all()));
+ ASSERT_EQUALS(r.all(), 0x4b21);
+}
+
+//-----------------------------------------------------------------------------
+void test_get()
+{
+ r.word = 0x1234;
+ ASSERT_EQUALS(r.high(), 0x12);
+ ASSERT_EQUALS(r.low(), 0x34);
+ ASSERT_EQUALS(r.mid(), 0x23);
+ ASSERT_EQUALS(r.all(), 0x1234);
+ ASSERT_EQUALS(r.single(), 0);
+ r.word = 0x1A34;
+ ASSERT_EQUALS(r.single(), 1);
+}
+
+//-----------------------------------------------------------------------------
+void test_flags()
+{
+
+
+ typedef uint16_t T;
+ ASSERT_EQUALS((boost::integer::bitfield<T, 8, 15>::get_flags(0x12)), 0x12);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 4, 11>::get_flags(0x34)), 0x0340);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 7>::get_flags(0x56)), 0x5600);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 15>::get_flags(0xabcd)), 0xabcd);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 4, 4>::get_flags(0)), 0);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 4, 4>::get_flags(1)), 0x0800);
+}
+
+//-----------------------------------------------------------------------------
+void test_invert()
+{
+ r.word = 0xff00;
+ ASSERT_EQUALS(~r.high(), 0x00);
+ ASSERT_EQUALS(~r.mid(), 0x0f);
+ ASSERT_EQUALS(~r.low(), 0xff);
+ ASSERT_EQUALS(~r.all(), 0x00ff);
+ ASSERT_EQUALS(~r.single(), 0);
+}
+
+//-----------------------------------------------------------------------------
+void test_traits()
+{
+ typedef uint8_t T;
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 0>::FIRST), 0);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 3, 5>::FIRST), 3);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 7, 7>::FIRST), 7);
+
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 0>::LAST), 0);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 3, 5>::LAST), 5);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 7, 7>::LAST), 7);
+
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 0>::WIDTH), 1);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 4, 7>::WIDTH), 4);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 7>::WIDTH), 8);
+
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 0>::VAL_MASK), 0x01);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 4, 4>::VAL_MASK), 0x01);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 1, 3>::VAL_MASK), 0x07);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 7, 7>::VAL_MASK), 0x01);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 7>::VAL_MASK), 0xff);
+
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 0>::FIELD_MASK), 0x80);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 3>::FIELD_MASK), 0xf0);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 4, 7>::FIELD_MASK), 0x0f);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 7, 7>::FIELD_MASK), 0x01);
+ ASSERT_EQUALS((boost::integer::bitfield<T, 0, 7>::FIELD_MASK), 0xff);
+}
+
+//-----------------------------------------------------------------------------
+template <class B, class CB>
+void do_bit_access_test(B bf, CB& cbf)
+{
+ // Manually set and clear each bit (using r.word) in the bitfield and verify
+ // that the changes are reflected while reading bf[i].
+ // Also test bit inversion and constant access at the same time.
+ for (int i=0; i<B::WIDTH; ++i)
+ {
+ r.word = htons(1u << (B::FIRST + i));
+ ASSERT_EQUALS(cbf[i], true);
+ ASSERT_EQUALS(~cbf[i], false);
+
+ r.word = htons(~ (1u << (B::FIRST + i)));
+ ASSERT_EQUALS(bf[i], false);
+ ASSERT_EQUALS(~cbf[i], true);
+ }
+
+ // Set and clear bf[i] and verify that the changes are reflected while
+ // reading r.word.
+ for (int i=0; i<B::WIDTH; ++i)
+ {
+ r.word = htons(0);
+ bf[i] = 1u;
+ ASSERT_EQUALS(htons(r.word), 1u << (B::FIRST + i));
+
+ r.word = htons(0xffff);
+ bf[i] = 0;
+ ASSERT_EQUALS( htons(r.word), (uint16_t)(~(1u << (B::FIRST + i))) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void test_bit_access()
+{
+ r.high()=0;
+ bool b = r.high()[0];
+ ASSERT_EQUALS(b, false);
+ r.high() = 0x01;
+ ASSERT_EQUALS(r.high(), 0x01);
+ ASSERT_EQUALS(r.high()[0], true);
+ ASSERT_EQUALS(r.high()[1], false);
+ ASSERT_EQUALS(r.high()[2], false);
+ ASSERT_EQUALS(r.high()[3], false);
+
+#if 0
+ Register& cr = r;
+ do_bit_access_test(r.high(), cr.high());
+ do_bit_access_test(r.mid(), cr.mid());
+ do_bit_access_test(r.low(), cr.low());
+ do_bit_access_test(r.all(), cr.all());
+ do_bit_access_test(r.single(), cr.single());
+#endif
+}
+
+//-----------------------------------------------------------------------------
+
+void test_signed_unsigned() {
+ r.word = 0;
+
+ r.ss() = -2;
+ r.ss()++;
+ r.ss()--;
+ int i = r.ss();
+ signed char c= r.ss();
+ //printf("----- l=%d %x\n", int(r.ss()), int(r.ss()));
+ //std::cout << std::hex << -2 << " " << r.word << " " << int(r.ss) << std::endl;
+ ASSERT_EQUALS(r.ss(), -2);
+ ASSERT_EQUALS(i, -2);
+ ASSERT_EQUALS(c, -2);
+
+}
+
+//-----------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+ test_tt();
+ test_assign();
+
+ test_get();
+ test_flags();
+ test_invert();
+ test_traits();
+ test_bit_access();
+ test_signed_unsigned();
+
+ std::cout << "All tests successful!\n";
+ return 0;
+}
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk