Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57677 - in sandbox/bitfield: boost/integer libs/integer/test
From: vicente.botet_at_[hidden]
Date: 2009-11-15 04:14:56


Author: viboes
Date: 2009-11-15 04:14:54 EST (Sun, 15 Nov 2009)
New Revision: 57677
URL: http://svn.boost.org/trac/boost/changeset/57677

Log:
Boost.Bitfield: Added ongoing work on bitfield group and pointer plus bits

Added:
   sandbox/bitfield/boost/integer/bitfield_group.hpp (contents, props changed)
   sandbox/bitfield/boost/integer/pointer_plus_bits.hpp (contents, props changed)
   sandbox/bitfield/libs/integer/test/bitfield_group_test.cpp (contents, props changed)
   sandbox/bitfield/libs/integer/test/pointer_plus_small_int_test.cpp (contents, props changed)

Added: sandbox/bitfield/boost/integer/bitfield_group.hpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/boost/integer/bitfield_group.hpp 2009-11-15 04:14:54 EST (Sun, 15 Nov 2009)
@@ -0,0 +1,151 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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/integer for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTEGER_BITFIELD_GROUP__HPP
+#define BOOST_INTEGER_BITFIELD_GROUP__HPP
+
+#include <boost/integer/bitfield.hpp>
+
+namespace boost { namespace integer {
+
+ namespace detail {
+ }
+
+ /*
+ Used to easily manipulate groups of bitfields the same way as does C bitfields,
+ but in a portable manner.
+ \par Example declaration:
+ \code
+ struct Rgb565
+ {
+ struct red {};
+ struct green {};
+ struct blue {};
+ typedef bitfields<mpl::vector<
+ member<unsigned char, red, 5>,
+ member<unsigned char, green, 6>,
+ member<unsigned char, blue, 5>
+ > > type;
+ //typedef bitfields_group<mpl::vector_c<5,6,5> > type2;
+ };
+
+ \endcode
+ \par Example usage:
+ \code
+ Rgb565::type r = make_bitfields<Rgb565::type, 1,2,3>;
+
+ // Write to a bitfield.
+ r.get<Rgb565::red>() = 23;same
+ r.set<Rgb565::red>(23);
+
+ // Read from a bitfield
+ Rgb565::at<Rgb565::blue>::value_type b = r.get<Rgb565::blue>();
+
+ // Access a bit within a bit field
+ bool bit = r.get<Rgb565::blue>()[3];
+ \endcode
+ \note Bitfields within the 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
+ */
+
+ template <typename IntegerType, typename Tag, std::size_t Bits>
+ struct member {
+ typedef IntegerType integer_type;
+ typedef Tag tag_type;
+ static const std::size_t BITS = Bits;
+ };
+
+ template <typename Member>
+ struct bitfield_size {
+ static const std::size_t value = Member::BITS;
+ };
+
+ template <typename StorageType>
+ struct member_bitfield_type {
+ template <typename Member, typename State>
+ struct apply {
+ static const std::size_t F= State::FIRST;
+ struct type {
+ static const FIRST=F+Member::BITS;
+ typedef mpl::insert<State::map_type,
+ mpl::pair<typename Member::tag_type, bitfield<StorageType, F, F+Member::BITS-1, typename Member::integer_type>
+ >::type map_type;
+ };
+ };
+ };
+
+ struct bitfields_type_initial_state {
+ struct type {
+ static const FIRST=0;
+ typedef mpl::map<> map_type;
+ };
+ };
+
+ template <typename Members, typename Storage>
+ struct bitfields_type {
+ typedef mpl::fold<
+ Members
+ , bitfields_type_initial_state
+ , member_bitfield_type<Storage>
+ >::type::map_type type ;
+ };
+
+
+ template <typename Members>
+ struct bitfields_size {
+ typedef mpl::fold<
+ Members
+ , mpl::int_<0>
+ , mpl::plus< _1, bitfield_size<_2> >
+ >::type::value value ;
+ };
+
+ template <typename Members, typename Storage=mpl::void_>
+ struct bitfields_group {
+
+ // number of bits of all the bitfields
+ static const std::size_t size = bitfields_size<Members>::value;
+ // if not explicit select the storage associated to the number of bits of all the bitfields
+ typedef mpl::if<is_void<Storage>, uint_t<size>::least, Storage> storage_type;
+ // assert bits of storage_type >= size
+
+ // mpl map of all the bitfields types
+ typedef bitfields_type<Members, storage_type>::type map_type;
+ storage_type value;
+ bitfields_group() : value(0) {}
+
+ };
+
+ template <typename Key, typename typename Members, typename Storage>
+ typename result_of::has_key<bitfields_group<Members, Storage>, Key>::type
+ has_key(bitfields_group<Members, Storage> const& seq) {
+ return mpl::has_key<bitfields_group<Members, Storage>::map_type>::type;
+ };
+
+ template <typename Key, typename typename Members, typename Storage>
+ typename result_of::has_key<bitfields_group<Members, Storage>, Key>::type
+ at_key(bitfields_group<Members, Storage> const& seq) {
+ return mpl::at_key<Key,bitfields_group<Members, Storage>::map_type>::type(value);
+ };
+
+ template <typename Key, typename typename Members, typename Storage>
+ typename result_of::has_key<bitfields_group<Members, Storage>, Key>::type
+ at_key(bitfields_group<Members, Storage> & seq) {
+ return mpl::at_key<Key,bitfields_group<Members, Storage>::map_type>::type(value);
+ };
+
+}}
+#endif
+

Added: sandbox/bitfield/boost/integer/pointer_plus_bits.hpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/boost/integer/pointer_plus_bits.hpp 2009-11-15 04:14:54 EST (Sun, 15 Nov 2009)
@@ -0,0 +1,339 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Joaquín M Lopez Munoz 2008.
+// (C) Copyright Vicente J. Botet Escriba 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/integer for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTEGER_POINTER_PLUS_BITS__HPP
+#define BOOST_INTEGER_POINTER_PLUS_BITS__HPP
+
+#include <cstddef>
+#include <boost/static_assert.hpp>
+#include <boost/config.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+
+namespace boost { namespace integer {
+
+template<int N>struct uintptr_candidates;
+template<>struct uintptr_candidates<-1>{typedef unsigned int type;};
+template<>struct uintptr_candidates<0> {typedef unsigned int type;};
+template<>struct uintptr_candidates<1> {typedef unsigned short type;};
+template<>struct uintptr_candidates<2> {typedef unsigned long type;};
+
+#if defined(BOOST_HAS_LONG_LONG)
+template<>struct uintptr_candidates<3> {typedef boost::ulong_long_type type;};
+#else
+template<>struct uintptr_candidates<3> {typedef unsigned int type;};
+#endif
+
+#if defined(BOOST_HAS_MS_INT64)
+template<>struct uintptr_candidates<4> {typedef unsigned __int64 type;};
+#else
+template<>struct uintptr_candidates<4> {typedef unsigned int type;};
+#endif
+
+struct uintptr_aux
+{
+ BOOST_STATIC_CONSTANT(int,index=
+ sizeof(void*)==sizeof(uintptr_candidates<0>::type)?0:
+ sizeof(void*)==sizeof(uintptr_candidates<1>::type)?1:
+ sizeof(void*)==sizeof(uintptr_candidates<2>::type)?2:
+ sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3:
+ sizeof(void*)==sizeof(uintptr_candidates<4>::type)?4:-1);
+
+ BOOST_STATIC_CONSTANT(bool,has_uintptr_type=(index>=0));
+
+ typedef uintptr_candidates<index>::type type;
+};
+
+typedef boost::mpl::bool_<uintptr_aux::has_uintptr_type> has_uintptr_type;
+typedef uintptr_aux::type uintptr_type;
+
+
+template <std::size_t ALIGN>
+struct num_low_bits_available_for_alignement {
+ static const std::size_t value=0;
+};
+
+template <>
+struct num_low_bits_available_for_alignement<1> {
+ static const std::size_t value=0;
+};
+
+template <>
+struct num_low_bits_available_for_alignement<2> {
+ static const std::size_t value=1;
+};
+
+template <>
+struct num_low_bits_available_for_alignement<4> {
+ static const std::size_t value=2;
+};
+
+template <>
+struct num_low_bits_available_for_alignement<8> {
+ static const std::size_t value=3;
+};
+
+template <typename T>
+struct num_low_bits_available {
+};
+
+template <typename T>
+struct num_low_bits_available<T*> {
+ static const std::size_t value=num_low_bits_available_for_alignement<boost::alignment_of<T>::value>::value;
+};
+
+namespace detail {
+
+// Selects between a compressed and a regular class depending on whether
+// * the user wants the compression,
+// * the compilers has a unsigned integer type with the size of the the pointer and
+// * the alignement of the structure let unsued the BITS
+
+template <bool Compression, typename Compressed, typename Regular>
+struct select_compressed_if_required_aux {
+ typedef Compressed type;
+};
+
+template <typename Compressed, typename Regular>
+struct select_compressed_if_required_aux<false, Compressed, Regular> {
+ typedef Regular type;
+};
+
+template <typename Pointer, typename Compressed, typename Regular, std::size_t BITS, bool Compression=true>
+struct select_compressed_if_required {
+ static const bool cond = Compression && has_uintptr_type::value && (num_low_bits_available<Pointer>::value>=BITS);
+ typedef typename select_compressed_if_required_aux<
+ cond,
+ Compressed,
+ Regular
+ >::type type;
+};
+
+
+
+// compressed version
+template <typename Pointer, std::size_t BITS, typename Int>
+class compressed_pointer_plus_bits {
+ uintptr_type ui_;
+ enum {
+ /// pointer_bit_mask - The bits that come from the pointer.
+ pointer_bit_mask =
+ ~uintptr_type((uintptr_type(1) << num_low_bits_available<Pointer>::value)-1),
+
+ /// int_shift - The number of low bits that we reserve for other uses, and
+ /// keep zero.
+ int_shift = num_low_bits_available<Pointer>::value-BITS,
+
+ /// int_mask - This is the unshifted mask for valid bits of the int type.
+ int_mask = uintptr_type((uintptr_type(1) << BITS)-1),
+
+ // shifted_int_mask - This is the bits for the integer shifted in place.
+ shifted_int_mask = uintptr_type(int_mask << BITS)
+ };
+
+ struct pointer_ref {
+ uintptr_type& ui_;
+ pointer_ref(uintptr_type& ui): ui_(ui) {}
+ operator Pointer() const {
+ return reinterpret_cast<Pointer>(ui_ & pointer_bit_mask);
+ }
+
+ operator Pointer() {
+ return reinterpret_cast<Pointer>(ui_ & pointer_bit_mask);
+ }
+
+ pointer_ref& operator=(Pointer p) {
+ uintptr_type ptr_val = reinterpret_cast<uintptr_type>(p);
+ assert((ptr_val & ((1 << num_low_bits_available<Pointer>::value)-1)) == 0 &&
+ "Pointer is not sufficiently aligned");
+ // Preserve all low bits, just update the pointer.
+ ui_ = ptr_val | (ui_ & ~pointer_bit_mask);
+ return *this;
+ }
+ pointer_ref& operator=(const pointer_ref& x) {
+ return operator=(x.operator Pointer());
+ }
+ // behaves like a pointer
+ Pointer operator->() const {
+ return operator Pointer();
+ }
+ };
+
+ struct small_int_ref {
+ uintptr_type& ui_;
+ small_int_ref(uintptr_type& ui): ui_(ui) {}
+
+ operator Int() const {
+ return (Int)((ui_ >> int_shift) & int_mask);
+ }
+
+
+ small_int_ref& operator=(Int i) {
+ uintptr_type int_val = i;
+ assert(int_val < (1 << BITS) && "Integer too large for field");
+
+ // Preserve all bits other than the ones we are updating.
+ ui_ &= ~shifted_int_mask; // Remove integer field.
+ ui_ |= int_val << int_shift; // Set new integer.
+ return *this;
+ }
+ small_int_ref& operator=(const small_int_ref& x) {
+ return operator=(x.operator Int());
+ }
+ };
+
+public:
+ compressed_pointer_plus_bits (): ui_(0){}
+ compressed_pointer_plus_bits (uintptr_type ui): ui_(ui){}
+ compressed_pointer_plus_bits (Pointer p, Int i): ui_(0){
+ set_pointer(p);
+ set_int(i);
+ }
+
+ Pointer get_pointer() const {
+ //return reinterpret_cast<Pointer>(ui_ & pointer_bit_mask);
+ return Pointer(ui_ & pointer_bit_mask);
+ }
+
+ Int get_int() const {
+ return (Int)((ui_ >> int_shift) & int_mask);
+ }
+
+ void set_pointer(Pointer p) {
+ uintptr_type ptr_val = reinterpret_cast<uintptr_type>(p);
+ assert((ptr_val & ((1 << num_low_bits_available<Pointer>::value)-1)) == 0 &&
+ "Pointer is not sufficiently aligned");
+ // Preserve all low bits, just update the pointer.
+ ui_ = ptr_val | (ui_ & ~pointer_bit_mask);
+ }
+
+ void set_int(Int i) {
+ uintptr_type int_val = i;
+ assert(int_val < (1 << BITS) && "Integer too large for field");
+
+ // Preserve all bits other than the ones we are updating.
+ ui_ &= ~shifted_int_mask; // Remove integer field.
+ ui_ |= int_val << int_shift; // Set new integer.
+ }
+
+ void *get_opaque_value() const { return reinterpret_cast<void*>(ui_); }
+ void set_from_opaque_value(void *val) { ui_ = reinterpret_cast<uintptr_type>(val);}
+
+ static compressed_pointer_plus_bits get_from_opaque_value(void *p) {
+ compressed_pointer_plus_bits ppb; ppb.set_from_opaque_value(p); return ppb;
+ }
+
+ pointer_ref pointer() {return pointer_ref(ui_);}
+ small_int_ref small_int() {return small_int_ref(ui_);}
+ Pointer pointer() const {return get_pointer();}
+ Int small_int() const {return get_int(ui_);}
+};
+
+// regular version
+template <typename Pointer, typename Int>
+class regular_pointer_plus_bits {
+ Pointer pointer_;
+ Int i_;
+public:
+ regular_pointer_plus_bits ():pointer_(0),i_(0){}
+ regular_pointer_plus_bits (Pointer p, Int b):pointer_(p),i_(b){}
+
+ Pointer get_pointer() const {return pointer_;}
+ Int get_int() const {return i_;}
+ void set_pointer(Pointer p) {pointer_=p;}
+ void set_int(Int i) {return i_=i;}
+
+ Pointer& pointer() {return pointer_;}
+ Pointer pointer() const {return pointer_;}
+ Int& small_int() {return i_;}
+ Int small_int() const {return i_;}
+};
+
+}
+
+// This class implements a pair of a pointer and small integer represented by the given nomber of BITS.
+// It is designed to represent this in the space required by one pointer by bitmangling the integer
+// into the low part of the pointer. This can only be done for small integers: typically up to 3 bits,
+// but it depends on the number of bits available according to the trait num_low_bits_available_for_alignement for the
+// type.
+//
+// Note that pointer_plus_bits always puts the Int part in the highest bits
+// possible. For example, pointer_plus_bits<uint_64*, 1, bool> will put the bit for
+// the bool into bit #2, not bit #0, which allows the low two bits to be used
+// for something else. For example, this allows:
+// pointer_plus_bits<pointer_plus_bits<uint_64*, 1, bool>, 1, bool>
+// ... and the two bools will land in different bits.
+//
+
+// selects the best of the compressed or the regular version
+template <typename Pointer, std::size_t BITS, typename Int, bool Compression=true>
+struct pointer_plus_bits {
+ typedef typename detail::select_compressed_if_required<Pointer,
+ detail::compressed_pointer_plus_bits<Pointer, BITS, Int>, //num_low_bits_available<Pointer>::value>,
+ detail::regular_pointer_plus_bits<Pointer, Int>,
+ BITS, Compression
+ >::type type;
+};
+
+template <typename Pointer, std::size_t BITS, typename Int, bool Compression>
+struct num_low_bits_available<typename pointer_plus_bits<Pointer,BITS,Int,Compression>::type > {
+ static const std::size_t value= num_low_bits_available<Pointer>::value - BITS;
+};
+
+template <typename Pointer, std::size_t BITS, typename Int>
+struct num_low_bits_available<detail::compressed_pointer_plus_bits<Pointer,BITS,Int> > {
+ static const std::size_t value= num_low_bits_available<Pointer>::value - BITS;
+};
+
+namespace detail{
+template <typename T>
+struct max_bits {
+ static const std::size_t value=3;
+};
+
+template <>
+struct max_bits<bool> {
+ static const std::size_t value=1;
+};
+}
+
+template <typename T, typename Tag, std::size_t BITS=detail::max_bits<T>::value>
+struct member {
+ typedef T type;
+ typedef Tag tag_type;
+ static const std::size_t bits=BITS;
+};
+
+template <typename Tag>
+struct boolean : member<bool, Tag> {};
+
+template <typename Tag, std::size_t BITS=detail::max_bits<Tag>::value>
+struct signed_integer : member<signed int, Tag, BITS> {};
+
+template <typename Tag, std::size_t BITS=detail::max_bits<Tag>::value>
+struct unsigned_integer : member<unsigned int, Tag, BITS> {};
+
+template <typename Tag, std::size_t BITS=detail::max_bits<Tag>::value>
+struct signed_short : member<signed short, Tag, BITS> {};
+
+template <typename Tag, std::size_t BITS=detail::max_bits<Tag>::value>
+struct unsigned_short : member<unsigned short, Tag, BITS> {};
+
+template <typename Pointer, bool Compression, typename Member_1, typename Member_2=mpl::void_, typename Member_3=mpl::void_>
+struct pointer_plus_bitfields {
+
+};
+
+}}
+#endif
+

Added: sandbox/bitfield/libs/integer/test/bitfield_group_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/libs/integer/test/bitfield_group_test.cpp 2009-11-15 04:14:54 EST (Sun, 15 Nov 2009)
@@ -0,0 +1,228 @@
+#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;
+using namespace boost;
+using namespace boost::integer;
+
+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 Register {
+ struct f_tag{};
+ struct m_tag{};
+ struct l_tag{};
+ typedef bitfield_group<mpl::vector<
+ member<uint8_t, f_tag, 3>,
+ member<uint16_t, m_tag, 9>,
+ member<uint32_t, l_tag, 4>
+ > > type;
+ type word;
+
+ struct STR {
+ uint8_t f:3;
+ uint16_t m:9;
+ uint32_t l:4;
+ };
+ union {
+ uint16_t padd;
+ STR value;
+ } s, sl;
+
+ 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); }
+};
+
+
+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.word=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);
+
+}
+
+struct Register2 {
+ struct high_tag{};
+ struct low_tag{};
+ struct mid_tag{};
+ typedef bitfield_group<mpl::vector<
+ member<uint16_t, high_tag, 4>,
+ member<uint16_t, mid_tag, 8>,
+ member<uint16_t, low_tag, 4>
+ > > type;
+ type word;
+
+ result_of::at_key<type, high_tag>::type high() { return at_key<high_tag>(word); }
+ result_of::at_key<type, mid_tag>::type mid() { return at_key<mid_tag>(word); }
+ result_of::at_key<type, low_tag>::type low() { return at_key<low_tag>(word); }
+
+ result_of::at_key<type, high_tag>::type::value_type get_high() const { return at_key<high_tag>(word).get(); }
+ result_of::at_key<type, mid_tag>::type::value_type get_mid() const { return at_key<mid_tag>(word).get(); }
+ result_of::at_key<type, low_tag>::type::value_type get_low() const { return at_key<low_tag>(word).get(); }
+
+ uint16_t& all() { return word.value; }
+ uint16_t all() const { return word.value; }
+
+};
+
+//-----------------------------------------------------------------------------
+void test_assign()
+{
+ Register2 r;
+ r.all() = 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()
+{
+ Register2 r;
+ r.all() = 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.all() = 0x1A34;
+}
+
+//-----------------------------------------------------------------------------
+void test_invert()
+{
+ Register2 r;
+ r.all() = 0xff00;
+ ASSERT_EQUALS(~r.high(), 0x00);
+ ASSERT_EQUALS(~r.mid(), 0x0f);
+ ASSERT_EQUALS(~r.low(), 0xff);
+ ASSERT_EQUALS(~r.all(), 0x00ff);
+}
+
+//-----------------------------------------------------------------------------
+
+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;
+}
+

Added: sandbox/bitfield/libs/integer/test/pointer_plus_small_int_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/bitfield/libs/integer/test/pointer_plus_small_int_test.cpp 2009-11-15 04:14:54 EST (Sun, 15 Nov 2009)
@@ -0,0 +1,75 @@
+#include <iostream>
+#include <cassert>
+#include "boost/integer/pointer_plus_bits.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))
+
+
+void test_tt()
+{
+ typedef boost::integer::pointer_plus_bits<int*,1,bool>::type pint_and_bool;
+
+ int i=0;
+ pint_and_bool v1;
+ ASSERT_EQUALS(v1.pointer(),0);
+ ASSERT_EQUALS(v1.small_int(),false);
+ pint_and_bool v2(&i, true);
+ ASSERT_EQUALS(v2.pointer(),&i);
+ ASSERT_EQUALS(v2.small_int(),true);
+ v1.pointer()=v2.pointer();
+ v1.small_int()=true;
+ ASSERT_EQUALS(v1.pointer(),&i);
+ ASSERT_EQUALS(v1.small_int(),true);
+ //ASSERT_EQUALS(0, 1);
+
+}
+
+void test_tt2()
+{
+ typedef boost::integer::pointer_plus_bits<boost::integer::pointer_plus_bits<int*,1,bool>::type,1, bool>::type pint_and_bool;
+
+ //int i=0;
+ pint_and_bool v1;
+ boost::integer::pointer_plus_bits<int*,1,bool>::type p1 = v1.get_pointer();
+// ASSERT_EQUALS(v1.pointer(),0);
+ ASSERT_EQUALS(v1.small_int(),false);
+ ASSERT_EQUALS(v1.pointer().get_pointer(),0);
+ ASSERT_EQUALS(v1.get_pointer().get_pointer(),0);
+ ASSERT_EQUALS(v1.get_pointer().small_int(),false);
+
+}
+
+#if 0
+void test_tt3()
+{
+ typedef boost::integer::pointer_plus_bitfields<int*,
+ boolean<a>,boolean<b> >::type pint_and_bool;
+
+ //int i=0;
+ pint_and_bool v1;
+ int* p1 = v1.get_pointer();
+// ASSERT_EQUALS(v1.pointer(),0);
+ ASSERT_EQUALS(get<a>(v1),false);
+ ASSERT_EQUALS(get<b>(v1),false);
+
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+ test_tt();
+ test_tt2();
+
+ 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