diff --git a/pvDataApp/misc/sharedVector.h b/pvDataApp/misc/sharedVector.h index 755e256..cd8ee39 100644 --- a/pvDataApp/misc/sharedVector.h +++ b/pvDataApp/misc/sharedVector.h @@ -47,13 +47,18 @@ namespace detail { template friend class shared_vector_base; protected: std::tr1::shared_ptr m_data; - //! Offset in the data array of first element + //! Offset in the data array of first visible element size_t m_offset; //! Number of visible elements between m_offset and end of data size_t m_count; //! Total number of elements between m_offset and the end of data size_t m_total; + /* invariants + * m_count <= m_total (enforced) + * m_offset + m_total <= (size_t)-1 (checked w/ assert()) + */ + public: //! @brief Empty vector (not very interesting) @@ -68,6 +73,9 @@ namespace detail { { if(!m_data.get()) { m_offset = m_total = m_count = 0; + } else { + // ensure we won't have integer overflows later + assert( m_offset <= ((size_t)-1) - m_total); } } public: @@ -96,6 +104,8 @@ namespace detail { protected: typedef typename meta::strip_const::type _E_non_const; public: + //! Constructor used to implement freeze(). + //! Should not be called directly. shared_vector_base(shared_vector_base<_E_non_const>& O, _shared_vector_freeze_tag) :m_data() @@ -109,6 +119,8 @@ namespace detail { O.clear(); } + //! Constructor used to implement thaw(). + //! Should not be called directly. shared_vector_base(shared_vector& O, _shared_vector_thaw_tag) :m_data() @@ -180,20 +192,16 @@ namespace detail { */ void slice(size_t offset, size_t length=(size_t)-1) { - if(offset>m_total) - offset = m_total; + if(offset>m_count) + offset = m_count; // will slice down to zero length + + const size_t max_count = m_count - offset; m_offset += offset; m_total -= offset; - if(offset>m_count) { - m_count = 0; - } else { - if(length > m_count - offset) - length = m_count - offset; - m_count = length; - } + m_count = std::min(length, max_count); } // Access to members. diff --git a/testApp/misc/testSharedVector.cpp b/testApp/misc/testSharedVector.cpp index a1bcd1f..0c1487d 100644 --- a/testApp/misc/testSharedVector.cpp +++ b/testApp/misc/testSharedVector.cpp @@ -250,7 +250,13 @@ static void testSlice() testOk1(half2.dataOffset()==5); testOk1(half2a.dataOffset()==5); - testOk1(half2.size() == half2a.size()); + testOk1(half1.size()==5); + testOk1(half2.size()==5); + testOk1(half2a.size()==5); + + testOk1(half1.dataTotal()==10); + testOk1(half2.dataTotal()==5); + testOk1(half2a.dataTotal()==5); testOk1(original.data() == half1.data()); testOk1(half2.data() == half2a.data()); @@ -259,13 +265,17 @@ static void testSlice() half2.slice(1); half2a.slice(1,1); + testOk1(half1.dataOffset()==5); + testOk1(half2.dataOffset()==6); + testOk1(half2a.dataOffset()==6); + testOk1(half1.size()==0); testOk1(half2.size()==4); testOk1(half2a.size()==1); - testOk1(half1.dataOffset()==10); - testOk1(half2.dataOffset()==6); - testOk1(half2a.dataOffset()==6); + testOk1(half1.dataTotal()==5); + testOk1(half2.dataTotal()==4); + testOk1(half2a.dataTotal()==4); half2.clear(); testOk1(half2.dataOffset()==0); @@ -525,7 +535,7 @@ static void testICE() MAIN(testSharedVector) { - testPlan(154); + testPlan(162); testDiag("Tests for shared_vector"); testDiag("sizeof(shared_vector)=%lu",