|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r64801 - in sandbox/SOC/2010/bit_masks: boost/integer/detail/bitfield_vector lib/integer/test/bitfield_vector_testing
From: bbartmanboost_at_[hidden]
Date: 2010-08-14 13:09:26
Author: bbartman
Date: 2010-08-14 13:09:22 EDT (Sat, 14 Aug 2010)
New Revision: 64801
URL: http://svn.boost.org/trac/boost/changeset/64801
Log:
implemented bitfield_vector_iterator_base and tested it's entire interface
Text files modified:
sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/bitfield_vector_member_impl.hpp | 56 ++++++--
sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/iterator_base.hpp | 201 ++++++++++++++++++++++++++++++
sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/iterator_base_test.cpp | 260 ++++++++++++++++++++++++++++++++++++++++
sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/proxy_reference_test.cpp | 2
sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/test_utility.hpp | 4
5 files changed, 507 insertions(+), 16 deletions(-)
Modified: sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/bitfield_vector_member_impl.hpp
==============================================================================
--- sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/bitfield_vector_member_impl.hpp (original)
+++ sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/bitfield_vector_member_impl.hpp 2010-08-14 13:09:22 EDT (Sat, 14 Aug 2010)
@@ -110,12 +110,12 @@
//@{
/** Copy Constructor. */
- explicit proxy_reference_type(_self const& x)
+ proxy_reference_type(_self const& x)
:_ptr(x._ptr), _mask(x._mask )
{ }
/** pointer, offset constructor. */
- explicit proxy_reference_type(storage_type* ptr, offset_type offset)
+ proxy_reference_type(storage_type* ptr, offset_type offset)
:_ptr(ptr), _mask(get_mask_detail<Width>(offset) )
{ }
//@}
@@ -263,11 +263,6 @@
}
return *this;
}
-/*
- bool operator==(_self const& rhs);
- bool operator!=(_self const& rhs);
- bool operator<(_self const& rhs);
-*/
/** Member variables. */
storage_type* _ptr;
@@ -292,12 +287,12 @@
//@{
/** Copy Constructor. */
- explicit proxy_reference_type(_self const& x)
+ proxy_reference_type(_self const& x)
:_ptr(x._ptr), _mask(x._mask)
{ }
/** pointer, offset constructor. */
- explicit proxy_reference_type(storage_type* ptr, offset_type offset)
+ proxy_reference_type(storage_type* ptr, offset_type offset)
:_ptr(ptr), _mask(get_mask_detail<Width>(offset))
{ }
//@}
@@ -421,11 +416,6 @@
}
return *this;
}
-/*
- bool operator==(_self const& rhs);
- bool operator!=(_self const& rhs);
- bool operator<(_self const& rhs);
-*/
/** Member variables. */
storage_type* _ptr;
@@ -433,6 +423,44 @@
};
+template <typename RetType, std::size_t Width>
+class const_proxy_reference_type
+ :proxy_reference_type<RetType,Width>
+{
+ typedef proxy_reference_type<RetType,Width> _base;
+ typedef const_proxy_reference_type<RetType,Width> _self;
+ const_proxy_reference_type();
+public:
+
+ typedef typename _base::storage_type storage_type;
+ typedef typename _base::value_type value_type;
+ typedef typename _base::offset_type offset_type;
+ BOOST_STATIC_CONSTANT( std::size_t, width = Width );
+
+
+ const_proxy_reference_type(_self const& x)
+ :_base( static_cast<_base>(x) )
+ { }
+
+ explicit const_proxy_reference_type(_base const& x)
+ :_base(x)
+ { }
+
+ const_proxy_reference_type(storage_type* ptr, offset_type offset)
+ :_base(ptr, offset)
+ { }
+
+ _self& operator=(_self const& rhs) {
+ static_cast<_base>(*this) = static_cast<_base>(rhs);
+ return *this;
+ }
+
+ operator value_type() const {
+ return static_cast<_base>(*this);
+ }
+
+};
+
}} // end boost::detail
Modified: sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/iterator_base.hpp
==============================================================================
--- sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/iterator_base.hpp (original)
+++ sandbox/SOC/2010/bit_masks/boost/integer/detail/bitfield_vector/iterator_base.hpp 2010-08-14 13:09:22 EDT (Sat, 14 Aug 2010)
@@ -7,11 +7,208 @@
#define BOOST_BITFIELD_ITERATOR_BASE_HPP
#include "bitfield_vector_member_impl.hpp"
#include <cstddef>
+#include <iterator>
+#include <boost/assert.hpp>
+#include <boost/type_traits/make_signed.hpp>
+#include <iostream>
+#include <boost/cstdint.hpp>
-namespace boost { namespace detail {
+namespace boost { namespace detail { namespace safe_bool_impl {
+class safe_bool_base {
+protected:
+ typedef void (safe_bool_base::* bool_type )() const;
+ void this_type_does_not_support_comparisons() const {
+ BOOST_ASSERT((false));
+ }
+
+ safe_bool_base() { }
+ safe_bool_base(const safe_bool_base&) { }
+ safe_bool_base& operator=(const safe_bool_base&) { return *this; }
+ ~safe_bool_base() {}
+};
+
+template <typename T>
+struct safe_bool_impl
+ :safe_bool_base
+{
+operator bool_type() const {
+ return (static_cast<const T*>(this))->has_value()
+ ? &safe_bool_base::this_type_does_not_support_comparisons : 0;
+}
+protected:
+ ~safe_bool_impl() {}
+};
+
+template <typename T, typename U>
+void operator==(safe_bool_impl<T> const & lhs,safe_bool_impl<U> const& rhs) {
+ lhs.this_type_does_not_support_comparisons();
+ return false;
+}
+
+template <typename T,typename U>
+void operator!=(safe_bool_impl<T> const& lhs, safe_bool_impl<U> const& rhs) {
+ lhs.this_type_does_not_support_comparisons();
+ return false;
+}
+
+// Here's how to use safe_bool:
+
+
+// class Testable_without_virtual :
+// public safe_bool <Testable_without_virtual> {
+// public:
+// bool boolean_test() const {
+// Perform Boolean logic here
+// }
+// };
+} // end safe bool impl.
+
+/** bitfield_vector_iterator_base
+ * This class is used to abstract all of the baisc operations which are
+ * preformed on an iterator from a bitfield tuple. This iterator may differ
+ * from what its expected from a normal iterator however that is still TBD.
+ *
+ * Things to consider as "optimizations"/"corrections" to the uasual
+ * vector iterator design.
+ *
+ * 1) Should these iterators be non-invalidaing iterators?
+ * If I cache the index and a pointer to the _impl member of the
+ * vector base class then ever thing works great. If I instead
+ * keep a copy of the reference type I believe everthing actually get's
+ * larger.
+ * 2) cacheing the index.
+ *
+ *
+ *
+ *
+ */
template <typename T, std::size_t Width>
-struct bitfield_vector_iterator_base {
+struct bitfield_vector_iterator_base
+ // :safe_bool_impl::safe_bool_impl< bitfield_vector_iterator_base<T,Width> >
+{
+
+ /** Typedef's for iterator base class. */
+ //@{
+ typedef bitfield_vector_iterator_base<T,Width> _self;
+ typedef proxy_reference_type<T,Width> proxy_ref_type;
+ typedef const_proxy_reference_type<T,Width> const_proxy_ref_type;
+
+ // I don't believe that this iterator can be a random access iterator
+ // until C++0x
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef proxy_ref_type reference;
+ typedef std::ptrdiff_t difference_type;
+ BOOST_STATIC_CONSTANT( std::size_t, width = Width );
+ //@}
+
+ /** bitfield_vector_iterator_base
+ * constructors and destructor
+ */
+ //@{
+ // default
+ bitfield_vector_iterator_base()
+ :_ptr(0),
+ _bit_offset(0)
+ { }
+
+ // copy
+ bitfield_vector_iterator_base( _self const& rhs )
+ :_ptr(rhs._ptr),
+ _bit_offset(rhs._bit_offset)
+ { }
+
+ // over a reference type
+ explicit bitfield_vector_iterator_base(proxy_ref_type const& ref)
+ : _ptr( ref._ptr),
+ _bit_offset(ref._mask._offset)
+ { }
+
+ bitfield_vector_iterator_base(storage_ptr_t ptr, std::size_t bit_offset)
+ :_ptr(ptr),
+ _bit_offset(bit_offset)
+ { }
+ //@}
+
+ /** iterator operations.
+ * This are the functions which will be used to implement the actual
+ * iterator functionality.
+ */
+ //@{
+ void advance(intmax_t rhs) {
+ typedef typename make_signed<std::size_t>::type signed_size_t;
+
+ signed_size_t previous_offset = signed_size_t(_bit_offset);
+ previous_offset += (signed_size_t(Width)*rhs);
+ _ptr -= std::size_t((previous_offset%8)<0)+((previous_offset / 8)*-1);
+
+ // Comment for the following line of code.
+ // In the case that previous_offset%8 is actually less then 8
+ // will construct a size_t with 1 and left shift it 3 making it
+ // positive 8. This is done to avoid branching inside of a
+ // decrement operation and this only works if the value is true
+ // otherwise the value is zero which is the behavior I want.
+ _bit_offset = (std::size_t((previous_offset%8)<0)<<3)
+ + (previous_offset % 8);
+ }
+
+ void next() {
+ unsigned int next_offset;
+ next_offset = _bit_offset + Width;
+ _ptr += (next_offset / 8);
+ _bit_offset = next_offset % 8;
+ }
+
+ void previous() {
+ typedef typename make_signed<std::size_t>::type signed_size_t;
+ signed_size_t previous_offset = signed_size_t(_bit_offset);
+ previous_offset -= signed_size_t(Width);
+ _ptr -= std::size_t((previous_offset%8)<0)+((previous_offset / 8)*-1);
+
+ // Comment for the following line of code.
+ // In the case that previous_offset%8 is actually less then 8
+ // will construct a size_t with 1 and left shift it 3 making it
+ // positive 8. This is done to avoid branching inside of a
+ // decrement operation and this only works if the value is true
+ // otherwise the value is zero which is the behavior I want.
+ _bit_offset = (std::size_t((previous_offset%8)<0)<<3)
+ + (previous_offset % 8);
+ }
+
+ std::ptrdiff_t distance(_self const& rhs) const {
+ std::ptrdiff_t ret = 8 * (_ptr - rhs._ptr);
+ ret -= rhs._bit_offset;
+ ret += _bit_offset;
+ return ret / Width;
+ }
+
+ bool is_equal(_self const& rhs) const {
+ return _ptr == rhs._ptr && _bit_offset == rhs._bit_offset;
+ }
+
+ _self& assign(_self const& rhs) {
+ _ptr = rhs._ptr;
+ _bit_offset = rhs._bit_offset;
+ return *this;
+ }
+
+ const_proxy_ref_type const_deref() const {
+ return const_proxy_ref_type(_ptr, _bit_offset);
+ }
+
+ proxy_ref_type deref() const {
+ return proxy_ref_type(_ptr, _bit_offset);
+ }
+
+ bool has_value() const {
+ return _ptr;
+ }
+ //@)
+
+ storage_ptr_t _ptr;
+ std::size_t _bit_offset;
};
}} // end boost::detail
Modified: sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/iterator_base_test.cpp
==============================================================================
--- sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/iterator_base_test.cpp (original)
+++ sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/iterator_base_test.cpp 2010-08-14 13:09:22 EDT (Sat, 14 Aug 2010)
@@ -7,6 +7,266 @@
#include <boost/integer/bitfield_vector.hpp>
#include "test_utility.hpp"
+using namespace boost::detail;
+
+typedef bitfield_vector_iterator_base<unsigned int, 3> test_type_1;
+typedef bitfield_vector_iterator_base<int, 20> test_type_2;
+typedef bitfield_vector_iterator_base<int, 8> test_type_3;
+
int main() {
+ // iterator base
+
+ // default constructor.
+ {
+ test_type_1 t1;
+ test_type_2 t2;
+ test_type_3 t3;
+
+ BOOST_TEST( t1._ptr == 0);
+ BOOST_TEST( t2._ptr == 0);
+ BOOST_TEST( t3._ptr == 0);
+
+ BOOST_TEST( t1._bit_offset == 0);
+ BOOST_TEST( t2._bit_offset == 0);
+ BOOST_TEST( t3._bit_offset == 0);
+ }
+
+ // testing 2 param constructor
+ {
+ storage_t storage[20];
+ test_type_1 t1(storage,0);
+ test_type_2 t2(storage,2);
+ test_type_3 t3(storage,3);
+
+
+ BOOST_TEST( t1._ptr == storage);
+ BOOST_TEST( t2._ptr == storage);
+ BOOST_TEST( t3._ptr == storage);
+
+ BOOST_TEST( t1._bit_offset == 0);
+ BOOST_TEST( t2._bit_offset == 2);
+ BOOST_TEST( t3._bit_offset == 3);
+ }
+
+ // testing copy constructor.
+ {
+ storage_t storage[20];
+ test_type_1 t1(storage,0);
+ test_type_2 t2(storage,2);
+ test_type_3 t3(storage,3);
+
+ test_type_1 t4(t1);
+ BOOST_TEST( t4._ptr == t1._ptr);
+ BOOST_TEST( t4._bit_offset == t1._bit_offset);
+ }
+
+ // Testing constructor over a normal "non-const proxy_reference_type"
+ {
+ storage_t storage[20];
+ test_type_1::reference r1(storage,0);
+ test_type_1 t1(r1);
+ BOOST_TEST( t1._ptr == storage);
+ BOOST_TEST( t1._bit_offset == 0);
+
+ }
+
+ // testing next
+ {
+ // test type 1
+ storage_t storage[20];
+ storage_ptr_t ptr = storage;
+ test_type_1 t1(storage, 0);
+ t1.next();
+ BOOST_TEST( t1._ptr == storage);
+ BOOST_TEST( t1._bit_offset == 3);
+ t1.next();
+ BOOST_TEST( t1._ptr == storage);
+ BOOST_TEST( t1._bit_offset == 6);
+ ++ptr;
+ t1.next();
+ BOOST_TEST( t1._ptr == ptr);
+ BOOST_TEST( t1._bit_offset == 1);
+
+ // test type 2
+ ptr = storage;
+ test_type_2 t2(storage,0);
+ t2.next();
+ ptr += 2;
+ BOOST_TEST( t2._ptr == ptr);
+ BOOST_TEST( t2._bit_offset == 4);
+ t2.next();
+ ptr += 3;
+ BOOST_TEST( t2._ptr == ptr);
+ BOOST_TEST( t2._bit_offset == 0);
+
+ // test type 3
+ ptr = storage;
+ test_type_3 t3(storage, 0);
+ t3.next();
+ ++ptr;
+ BOOST_TEST( t3._ptr == ptr);
+ BOOST_TEST( t3._bit_offset == 0);
+ }
+
+ // testing previous
+ {
+ storage_t storage[20];
+ storage_ptr_t ptr = storage;
+ test_type_1 t1(ptr, 0);
+
+ --ptr;
+ t1.previous();
+ BOOST_TEST( t1._ptr == ptr);
+ BOOST_TEST( t1._bit_offset == 5);
+
+ t1.previous();
+ BOOST_TEST( t1._ptr == ptr);
+ BOOST_TEST( t1._bit_offset == 2);
+
+ --ptr;
+ t1.previous();
+ BOOST_TEST( t1._ptr == ptr);
+ BOOST_TEST( t1._bit_offset == 7);
+
+ t1.previous();
+ BOOST_TEST( t1._ptr == ptr);
+ BOOST_TEST( t1._bit_offset == 4);
+
+
+ ptr = storage;
+ test_type_2 t2(storage,0);
+
+ ptr -= 3;
+ t2.previous();
+ BOOST_TEST( t2._ptr == ptr);
+ BOOST_TEST( t2._bit_offset == 4);
+
+ ptr -= 2;
+ t2.previous();
+ BOOST_TEST( t2._ptr == ptr);
+ BOOST_TEST( t2._bit_offset == 0);
+
+
+ ptr = storage;
+ test_type_3 t3(storage,0);
+ --ptr;
+ t3.previous();
+ BOOST_TEST( t3._ptr == ptr);
+ BOOST_TEST( t3._bit_offset == 0);
+ }
+
+ // testing distance
+ {
+ storage_t storage[20];
+ storage_ptr_t ptr = storage;
+ ptr = storage;
+
+ test_type_1 t1(storage,0);
+ test_type_1 t2(storage,0);
+ t2.next();
+ t2.next();
+ t2.next();
+ BOOST_TEST( t2.distance(t1) == 3 );
+
+
+ test_type_1 t3(storage,0);
+ test_type_1 t4(storage,0);
+ t3.next();
+ t3.next();
+ t3.next();
+ t3.next();
+ BOOST_TEST(t3.distance(t4) == 4);
+
+ test_type_3 t5(storage,0);
+ test_type_3 t6(storage,0);
+ t5.next();
+ BOOST_TEST( t5.distance(t6) == 1);
+ }
+
+ // testing is_equal
+ {
+ storage_t storage[20];
+ storage_ptr_t ptr = storage;
+ ptr = storage;
+
+ test_type_1 t1(storage,0);
+ test_type_1 t2(storage,0);
+ BOOST_TEST( t1.is_equal(t2) );
+ BOOST_TEST( t2.is_equal(t1) );
+ BOOST_TEST( t1.is_equal(t1) );
+ }
+
+
+ // testing assign
+ {
+ storage_t storage[20];
+ // storage_ptr_t ptr = storage;
+ // ptr = storage;
+
+ test_type_1 t1(storage,0);
+ test_type_1 t2(storage,0);
+ t2.next();
+ t2.next();
+ BOOST_TEST( !t1.is_equal(t2) );
+ t1.assign(t2);
+ BOOST_TEST( t1.is_equal(t2) );
+ }
+
+ // testing const_deref
+ {
+ storage_t storage[20];
+ storage_ptr_t ptr = storage;
+ ptr = storage;
+ test_type_1::proxy_ref_type r1(storage,0);
+ r1 = 2;
+ BOOST_TEST( *ptr != 0);
+ test_type_1 t1(storage,0);
+ BOOST_TEST(t1.const_deref() == 2);
+
+ }
+
+ // testing deref
+ {
+ storage_t storage[20];
+ std::memset(storage,0,20);
+ test_type_1 t1(storage,0);
+ BOOST_TEST(t1.deref() == 0);
+ t1.deref() = 2;
+ BOOST_TEST( *storage != 0);
+ BOOST_TEST(t1.deref() == 2);
+
+
+ }
+
+ // testing has_value
+ {
+ storage_t storage[20];
+ test_type_1 t1;
+ BOOST_TEST( !t1.has_value() );
+ test_type_2 t2(storage,0);
+ BOOST_TEST( t2.has_value() );
+ }
+
+ // testing advance function
+ {
+ storage_t storage[20];
+ std::memset(storage,0,20);
+ storage_ptr_t ptr = storage;
+ test_type_1 t1(storage, 0);
+ ++ptr;
+ t1.advance(3);
+ BOOST_TEST( t1._ptr == ptr);
+ BOOST_TEST( t1._bit_offset == 1);
+ t1.advance(-3);
+ BOOST_TEST( t1._ptr == storage);
+ BOOST_TEST( t1._bit_offset == 0);
+ }
+/*
+
+typedef bitfield_vector_iterator_base<unsigned int, 3> test_type_1;
+typedef bitfield_vector_iterator_base<int, 20> test_type_2;
+typedef bitfield_vector_iterator_base<int, 8> test_type_3;
+*/
+
return boost::report_errors();
}
Modified: sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/proxy_reference_test.cpp
==============================================================================
--- sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/proxy_reference_test.cpp (original)
+++ sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/proxy_reference_test.cpp 2010-08-14 13:09:22 EDT (Sat, 14 Aug 2010)
@@ -687,6 +687,8 @@
BOOST_TEST(t1 == -2);
}
+
+
return boost::report_errors();
}
Modified: sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/test_utility.hpp
==============================================================================
--- sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/test_utility.hpp (original)
+++ sandbox/SOC/2010/bit_masks/lib/integer/test/bitfield_vector_testing/test_utility.hpp 2010-08-14 13:09:22 EDT (Sat, 14 Aug 2010)
@@ -120,4 +120,8 @@
print_from_to(x._ptr, x._mask._size);
}
+template <typename T>
+void print_typestr() {
+ std::cout << typestr<T>() << std::endl;
+}
#endif
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