$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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