From 790a8798d4879e69aed3a4af9838901d6c19197b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 6 Jun 2014 13:21:03 +0200 Subject: [PATCH] Fixes Trac issue #9801 ("I can no longer create and iterator_range from a stable_vector") --- doc/container.qbk | 1 + include/boost/container/stable_vector.hpp | 322 +++++++++++----------- test/stable_vector_test.cpp | 8 +- 3 files changed, 162 insertions(+), 169 deletions(-) diff --git a/doc/container.qbk b/doc/container.qbk index 880d101..cb73c47 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -963,6 +963,7 @@ use [*Boost.Container]? There are several reasons for that: * Fixed bugs: * [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]]. * [@https://svn.boost.org/trac/boost/ticket/9648 #9648: ['"string construction optimization - char_traits::copy could be used ..."]]. + * [@https://svn.boost.org/trac/boost/ticket/9801 #9801: ['"I can no longer create and iterator_range from a stable_vector"]]. * [@https://svn.boost.org/trac/boost/ticket/9915 #9915: ['"Documentation issues regarding vector constructors and resize methods - value/default initialization"]]. * [@https://svn.boost.org/trac/boost/ticket/9916 #9916: ['"Allocator propagation incorrect in the assignment operator of most"]]. * [@https://svn.boost.org/trac/boost/ticket/9931 #9931: ['"flat_map::insert(ordered_unique_range_t...) fails with move_iterators"]]. diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index f5e9314..64ab850 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -130,160 +130,6 @@ struct node typename ::boost::intrusive::pointer_traits::element_type value; }; -template -class iterator -{ - typedef boost::intrusive::pointer_traits non_const_ptr_traits; - public: - typedef std::random_access_iterator_tag iterator_category; - typedef typename non_const_ptr_traits::element_type value_type; - typedef typename non_const_ptr_traits::difference_type difference_type; - typedef typename ::boost::container::container_detail::if_c - < IsConst - , typename non_const_ptr_traits::template - rebind_pointer::type - , Pointer - >::type pointer; - typedef typename ::boost::container::container_detail::if_c - < IsConst - , const value_type& - , value_type& - >::type reference; - - private: - typedef typename non_const_ptr_traits::template - rebind_pointer::type void_ptr; - typedef node node_type; - typedef node_base node_base_type; - typedef typename non_const_ptr_traits::template - rebind_pointer::type node_ptr; - typedef boost::intrusive:: - pointer_traits node_ptr_traits; - typedef typename non_const_ptr_traits::template - rebind_pointer::type node_base_ptr; - typedef typename non_const_ptr_traits::template - rebind_pointer::type node_base_ptr_ptr; - - node_ptr m_pn; - - public: - - explicit iterator(node_ptr p) BOOST_CONTAINER_NOEXCEPT - : m_pn(p) - {} - - iterator() BOOST_CONTAINER_NOEXCEPT - {} - - iterator(iterator const& other) BOOST_CONTAINER_NOEXCEPT - : m_pn(other.node_pointer()) - {} - - node_ptr &node_pointer() BOOST_CONTAINER_NOEXCEPT - { return m_pn; } - - const node_ptr &node_pointer() const BOOST_CONTAINER_NOEXCEPT - { return m_pn; } - - public: - //Pointer like operators - reference operator*() const BOOST_CONTAINER_NOEXCEPT - { return m_pn->value; } - - pointer operator->() const BOOST_CONTAINER_NOEXCEPT - { - typedef boost::intrusive::pointer_traits ptr_traits; - return ptr_traits::pointer_to(this->operator*()); - } - - //Increment / Decrement - iterator& operator++() BOOST_CONTAINER_NOEXCEPT - { - if(node_base_ptr_ptr p = this->m_pn->up){ - ++p; - this->m_pn = node_ptr_traits::static_cast_from(*p); - } - return *this; - } - - iterator operator++(int) BOOST_CONTAINER_NOEXCEPT - { iterator tmp(*this); ++*this; return iterator(tmp); } - - iterator& operator--() BOOST_CONTAINER_NOEXCEPT - { - if(node_base_ptr_ptr p = this->m_pn->up){ - --p; - this->m_pn = node_ptr_traits::static_cast_from(*p); - } - return *this; - } - - iterator operator--(int) BOOST_CONTAINER_NOEXCEPT - { iterator tmp(*this); --*this; return iterator(tmp); } - - reference operator[](difference_type off) const BOOST_CONTAINER_NOEXCEPT - { - iterator tmp(*this); - tmp += off; - return *tmp; - } - - iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT - { - if(node_base_ptr_ptr p = this->m_pn->up){ - p += off; - this->m_pn = node_ptr_traits::static_cast_from(*p); - } - return *this; - } - - friend iterator operator+(const iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT - { - iterator tmp(left); - tmp += off; - return tmp; - } - - friend iterator operator+(difference_type off, const iterator& right) BOOST_CONTAINER_NOEXCEPT - { - iterator tmp(right); - tmp += off; - return tmp; - } - - iterator& operator-=(difference_type off) BOOST_CONTAINER_NOEXCEPT - { *this += -off; return *this; } - - friend iterator operator-(const iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT - { - iterator tmp(left); - tmp -= off; - return tmp; - } - - friend difference_type operator-(const iterator& left, const iterator& right) BOOST_CONTAINER_NOEXCEPT - { return left.m_pn->up - right.m_pn->up; } - - //Comparison operators - friend bool operator== (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT - { return l.m_pn == r.m_pn; } - - friend bool operator!= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT - { return l.m_pn != r.m_pn; } - - friend bool operator< (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT - { return l.m_pn->up < r.m_pn->up; } - - friend bool operator<= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT - { return l.m_pn->up <= r.m_pn->up; } - - friend bool operator> (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT - { return l.m_pn->up > r.m_pn->up; } - - friend bool operator>= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT - { return l.m_pn->up >= r.m_pn->up; } -}; - template struct index_traits { @@ -377,22 +223,172 @@ struct index_traits } //namespace stable_vector_detail -#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) +template +class stable_vector_iterator +{ + typedef boost::intrusive::pointer_traits non_const_ptr_traits; + public: + typedef std::random_access_iterator_tag iterator_category; + typedef typename non_const_ptr_traits::element_type value_type; + typedef typename non_const_ptr_traits::difference_type difference_type; + typedef typename ::boost::container::container_detail::if_c + < IsConst + , typename non_const_ptr_traits::template + rebind_pointer::type + , Pointer + >::type pointer; + typedef typename ::boost::container::container_detail::if_c + < IsConst + , const value_type& + , value_type& + >::type reference; + + private: + typedef typename non_const_ptr_traits::template + rebind_pointer::type void_ptr; + typedef stable_vector_detail::node node_type; + typedef stable_vector_detail::node_base node_base_type; + typedef typename non_const_ptr_traits::template + rebind_pointer::type node_ptr; + typedef boost::intrusive:: + pointer_traits node_ptr_traits; + typedef typename non_const_ptr_traits::template + rebind_pointer::type node_base_ptr; + typedef typename non_const_ptr_traits::template + rebind_pointer::type node_base_ptr_ptr; + + node_ptr m_pn; + + public: + + explicit stable_vector_iterator(node_ptr p) BOOST_CONTAINER_NOEXCEPT + : m_pn(p) + {} + + stable_vector_iterator() BOOST_CONTAINER_NOEXCEPT + {} + + stable_vector_iterator(stable_vector_iterator const& other) BOOST_CONTAINER_NOEXCEPT + : m_pn(other.node_pointer()) + {} + + node_ptr &node_pointer() BOOST_CONTAINER_NOEXCEPT + { return m_pn; } + + const node_ptr &node_pointer() const BOOST_CONTAINER_NOEXCEPT + { return m_pn; } + + public: + //Pointer like operators + reference operator*() const BOOST_CONTAINER_NOEXCEPT + { return m_pn->value; } + + pointer operator->() const BOOST_CONTAINER_NOEXCEPT + { + typedef boost::intrusive::pointer_traits ptr_traits; + return ptr_traits::pointer_to(this->operator*()); + } + + //Increment / Decrement + stable_vector_iterator& operator++() BOOST_CONTAINER_NOEXCEPT + { + if(node_base_ptr_ptr p = this->m_pn->up){ + ++p; + this->m_pn = node_ptr_traits::static_cast_from(*p); + } + return *this; + } + + stable_vector_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT + { stable_vector_iterator tmp(*this); ++*this; return stable_vector_iterator(tmp); } + + stable_vector_iterator& operator--() BOOST_CONTAINER_NOEXCEPT + { + if(node_base_ptr_ptr p = this->m_pn->up){ + --p; + this->m_pn = node_ptr_traits::static_cast_from(*p); + } + return *this; + } + + stable_vector_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT + { stable_vector_iterator tmp(*this); --*this; return stable_vector_iterator(tmp); } + + reference operator[](difference_type off) const BOOST_CONTAINER_NOEXCEPT + { + stable_vector_iterator tmp(*this); + tmp += off; + return *tmp; + } + + stable_vector_iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT + { + if(node_base_ptr_ptr p = this->m_pn->up){ + p += off; + this->m_pn = node_ptr_traits::static_cast_from(*p); + } + return *this; + } + + friend stable_vector_iterator operator+(const stable_vector_iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT + { + stable_vector_iterator tmp(left); + tmp += off; + return tmp; + } + + friend stable_vector_iterator operator+(difference_type off, const stable_vector_iterator& right) BOOST_CONTAINER_NOEXCEPT + { + stable_vector_iterator tmp(right); + tmp += off; + return tmp; + } + + stable_vector_iterator& operator-=(difference_type off) BOOST_CONTAINER_NOEXCEPT + { *this += -off; return *this; } + + friend stable_vector_iterator operator-(const stable_vector_iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT + { + stable_vector_iterator tmp(left); + tmp -= off; + return tmp; + } + + friend difference_type operator-(const stable_vector_iterator& left, const stable_vector_iterator& right) BOOST_CONTAINER_NOEXCEPT + { return left.m_pn->up - right.m_pn->up; } + + //Comparison operators + friend bool operator== (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT + { return l.m_pn == r.m_pn; } + + friend bool operator!= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT + { return l.m_pn != r.m_pn; } + + friend bool operator< (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT + { return l.m_pn->up < r.m_pn->up; } + + friend bool operator<= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT + { return l.m_pn->up <= r.m_pn->up; } + + friend bool operator> (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT + { return l.m_pn->up > r.m_pn->up; } + + friend bool operator>= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT + { return l.m_pn->up >= r.m_pn->up; } +}; #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) - #define STABLE_VECTOR_CHECK_INVARIANT \ - invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); + #define STABLE_VECTOR_CHECK_INVARIANT \ + invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); #else //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING - #define STABLE_VECTOR_CHECK_INVARIANT + #define STABLE_VECTOR_CHECK_INVARIANT #endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) -#endif //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector @@ -501,10 +497,10 @@ class stable_vector { allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder); } friend class stable_vector_detail::clear_on_destroy; - typedef stable_vector_detail::iterator + typedef stable_vector_iterator < typename allocator_traits::pointer , false> iterator_impl; - typedef stable_vector_detail::iterator + typedef stable_vector_iterator < typename allocator_traits::pointer , false> const_iterator_impl; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp index d60e022..9abda43 100644 --- a/test/stable_vector_test.cpp +++ b/test/stable_vector_test.cpp @@ -56,12 +56,8 @@ template class stable_vector < test::movable_and_copyable_int , node_allocator >; -namespace stable_vector_detail{ - -template class iterator; -template class iterator; - -} //namespace stable_vector_detail{ +template class stable_vector_iterator; +template class stable_vector_iterator; }}