diff --git a/example/doc_stateful_value_traits.cpp b/example/doc_stateful_value_traits.cpp index d26e8b7..2906220 100644 --- a/example/doc_stateful_value_traits.cpp +++ b/example/doc_stateful_value_traits.cpp @@ -36,11 +36,11 @@ struct stateful_value_traits {} ///Note: non static functions! - node_ptr to_node_ptr (value_type &value) + node_ptr to_node_ptr (value_type &value) const { return this->nodes_ + (&value - this->ids_); } const_node_ptr to_node_ptr (const value_type &value) const { return this->nodes_ + (&value - this->ids_); } - pointer to_value_ptr(node_ptr n) + pointer to_value_ptr(node_ptr n) const { return this->ids_ + (n - this->nodes_); } const_pointer to_value_ptr(const_node_ptr n) const { return this->ids_ + (n - this->nodes_); } diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 32554fb..ecd3999 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -13,6 +13,7 @@ #define BOOST_INTRUSIVE_BSTREE_HPP #include +#include #include #include #include @@ -22,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include namespace boost { @@ -52,91 +54,93 @@ struct bstree_defaults template struct bstbase3 - : public detail::get_real_value_traits::type::node_traits::node - , public ValueTraits { typedef ValueTraits value_traits; - typedef typename detail::get_real_value_traits::type real_value_traits; - typedef typename real_value_traits::node_traits node_traits; + typedef typename value_traits::node_traits node_traits; typedef typename node_traits::node node_type; typedef typename get_algo::type node_algorithms; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; - bstbase3(const ValueTraits &vtraits) - : ValueTraits(vtraits) - {} + struct holder_t : public ValueTraits + { + explicit holder_t(const ValueTraits &vtraits) + : ValueTraits(vtraits) + {} + node_type root; + } holder; - static const bool external_value_traits = - detail::external_value_traits_bool_is_true::value; + static bstbase3 &get_tree_base_from_root(node_type &root) + { + holder_t *holder = get_parent_from_member(&root, &holder_t::root); + bstbase3 *base = get_parent_from_member (holder, &bstbase3::holder); + return *base; + } + + bstbase3(const ValueTraits &vtraits) + : holder(vtraits) + { + node_algorithms::init_header(this->header_ptr()); + } node_ptr header_ptr() - { return pointer_traits::pointer_to(static_cast(*this)); } + { return pointer_traits::pointer_to(this->holder.root); } const_node_ptr header_ptr() const - { return pointer_traits::pointer_to(static_cast(*this)); } + { return pointer_traits::pointer_to(this->holder.root); } - const value_traits &val_traits() const - { return *this; } + const value_traits &get_value_traits() const + { return this->holder; } - value_traits &val_traits() - { return *this; } + value_traits &get_value_traits() + { return this->holder; } - const real_value_traits &get_real_value_traits(detail::bool_) const - { return *this; } + typedef typename pointer_traits::template + rebind_pointer::type const_value_traits_ptr; - const real_value_traits &get_real_value_traits(detail::bool_) const - { return this->val_traits().get_value_traits(*this); } + const_value_traits_ptr value_traits_ptr() const + { return pointer_traits::pointer_to(this->get_value_traits()); } - real_value_traits &get_real_value_traits(detail::bool_) - { return *this; } - - real_value_traits &get_real_value_traits(detail::bool_) - { return this->val_traits().get_value_traits(*this); } - - const real_value_traits &get_real_value_traits() const - { return this->get_real_value_traits(detail::bool_()); } - - real_value_traits &get_real_value_traits() - { return this->get_real_value_traits(detail::bool_()); } - - typedef typename pointer_traits::template rebind_pointer::type const_real_value_traits_ptr; - - const_real_value_traits_ptr real_value_traits_ptr() const - { return pointer_traits::pointer_to(this->get_real_value_traits()); } - - - typedef tree_iterator iterator; - typedef tree_iterator const_iterator; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; typedef boost::intrusive::detail::reverse_iterator reverse_iterator; typedef boost::intrusive::detail::reverse_iterator const_reverse_iterator; - typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer; - typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; - static const bool safemode_or_autounlink = is_safe_autounlink::value; - static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; iterator begin() - { return iterator (node_traits::get_left(this->header_ptr()), this->real_value_traits_ptr()); } + { return iterator(node_algorithms::begin_node(this->header_ptr()), this->value_traits_ptr()); } const_iterator begin() const { return cbegin(); } const_iterator cbegin() const - { return const_iterator (node_traits::get_left(this->header_ptr()), this->real_value_traits_ptr()); } + { return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->value_traits_ptr()); } iterator end() - { return iterator (this->header_ptr(), this->real_value_traits_ptr()); } + { return iterator(node_algorithms::end_node(this->header_ptr()), this->value_traits_ptr()); } const_iterator end() const { return cend(); } const_iterator cend() const - { return const_iterator (detail::uncast(this->header_ptr()), this->real_value_traits_ptr()); } + { return const_iterator(node_algorithms::end_node(this->header_ptr()), this->value_traits_ptr()); } + + iterator root() + { return iterator(node_algorithms::root_node(this->header_ptr()), this->value_traits_ptr()); } + + const_iterator root() const + { return croot(); } + + const_iterator croot() const + { return const_iterator(node_algorithms::root_node(this->header_ptr()), this->value_traits_ptr()); } reverse_iterator rbegin() { return reverse_iterator(end()); } @@ -158,9 +162,9 @@ struct bstbase3 void replace_node(iterator replace_this, reference with_this) { - node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) + node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this) , this->header_ptr() - , get_real_value_traits().to_node_ptr(with_this)); + , get_value_traits().to_node_ptr(with_this)); if(safemode_or_autounlink) node_algorithms::init(replace_this.pointed_node()); } @@ -169,25 +173,25 @@ struct bstbase3 { node_algorithms::rebalance(this->header_ptr()); } iterator rebalance_subtree(iterator root) - { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->real_value_traits_ptr()); } + { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->value_traits_ptr()); } static iterator s_iterator_to(reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr()); + return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr()); } static const_iterator s_iterator_to(const_reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - return const_iterator (value_traits::to_node_ptr(const_cast (value)), const_real_value_traits_ptr()); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), const_value_traits_ptr()); } iterator iterator_to(reference value) - { return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr()); } + { return iterator (this->get_value_traits().to_node_ptr(value), this->value_traits_ptr()); } const_iterator iterator_to(const_reference value) const - { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this->real_value_traits_ptr()); } + { return const_iterator (this->get_value_traits().to_node_ptr(const_cast (value)), this->value_traits_ptr()); } static void init_node(reference value) { node_algorithms::init(value_traits::to_node_ptr(value)); } @@ -196,16 +200,17 @@ struct bstbase3 template struct bstbase2 - : public bstbase3 - , public detail::ebo_functor_holder::type::value_type + //Put the (possibly empty) functor in the first position to get EBO in MSVC + : public detail::ebo_functor_holder::type> + , public bstbase3 { typedef bstbase3 treeheader_t; - typedef typename treeheader_t::real_value_traits real_value_traits; + typedef typename treeheader_t::value_traits value_traits; typedef typename treeheader_t::node_algorithms node_algorithms; typedef typename get_less - < VoidOrKeyComp, typename real_value_traits::value_type>::type value_compare; + < VoidOrKeyComp, typename value_traits::value_type>::type value_compare; typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare; typedef typename treeheader_t::iterator iterator; typedef typename treeheader_t::const_iterator const_iterator; @@ -213,7 +218,7 @@ struct bstbase2 typedef typename treeheader_t::const_node_ptr const_node_ptr; bstbase2(const value_compare &comp, const ValueTraits &vtraits) - : treeheader_t(vtraits), detail::ebo_functor_holder(comp) + : detail::ebo_functor_holder(comp), treeheader_t(vtraits) {} const value_compare &comp() const @@ -222,8 +227,8 @@ struct bstbase2 value_compare &comp() { return this->get(); } - typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer; - typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; @@ -237,6 +242,7 @@ struct bstbase2 key_compare key_comp() const { return this->comp(); } + //lower_bound iterator lower_bound(const_reference value) { return this->lower_bound(value, this->comp()); } @@ -246,31 +252,32 @@ struct bstbase2 template iterator lower_bound(const KeyType &key, KeyValueCompare comp) { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); return iterator(node_algorithms::lower_bound - (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + (this->header_ptr(), key, key_node_comp), this->value_traits_ptr()); } template const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); return const_iterator(node_algorithms::lower_bound - (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + (this->header_ptr(), key, key_node_comp), this->value_traits_ptr()); } + //upper_bound iterator upper_bound(const_reference value) { return this->upper_bound(value, this->comp()); } template iterator upper_bound(const KeyType &key, KeyValueCompare comp) { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); return iterator(node_algorithms::upper_bound - (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + (this->header_ptr(), key, key_node_comp), this->value_traits_ptr()); } const_iterator upper_bound(const_reference value) const @@ -279,22 +286,23 @@ struct bstbase2 template const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); return const_iterator(node_algorithms::upper_bound - (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + (this->header_ptr(), key, key_node_comp), this->value_traits_ptr()); } + //find iterator find(const_reference value) { return this->find(value, this->comp()); } template iterator find(const KeyType &key, KeyValueCompare comp) { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); return iterator - (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->value_traits_ptr()); } const_iterator find(const_reference value) const @@ -303,24 +311,25 @@ struct bstbase2 template const_iterator find(const KeyType &key, KeyValueCompare comp) const { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); return const_iterator - (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->value_traits_ptr()); } + //equal_range std::pair equal_range(const_reference value) { return this->equal_range(value, this->comp()); } template std::pair equal_range(const KeyType &key, KeyValueCompare comp) { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); std::pair ret (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp)); - return std::pair( iterator(ret.first, this->real_value_traits_ptr()) - , iterator(ret.second, this->real_value_traits_ptr())); + return std::pair( iterator(ret.first, this->value_traits_ptr()) + , iterator(ret.second, this->value_traits_ptr())); } std::pair @@ -331,14 +340,46 @@ struct bstbase2 std::pair equal_range(const KeyType &key, KeyValueCompare comp) const { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); std::pair ret (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp)); - return std::pair( const_iterator(ret.first, this->real_value_traits_ptr()) - , const_iterator(ret.second, this->real_value_traits_ptr())); + return std::pair( const_iterator(ret.first, this->value_traits_ptr()) + , const_iterator(ret.second, this->value_traits_ptr())); } + //lower_bound_range + std::pair lower_bound_range(const_reference value) + { return this->lower_bound_range(value, this->comp()); } + + template + std::pair lower_bound_range(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); + std::pair ret + (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp)); + return std::pair( iterator(ret.first, this->value_traits_ptr()) + , iterator(ret.second, this->value_traits_ptr())); + } + + std::pair + lower_bound_range(const_reference value) const + { return this->lower_bound_range(value, this->comp()); } + + template + std::pair + lower_bound_range(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); + std::pair ret + (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp)); + return std::pair( const_iterator(ret.first, this->value_traits_ptr()) + , const_iterator(ret.second, this->value_traits_ptr())); + } + + //bounded_range std::pair bounded_range (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); } @@ -347,13 +388,13 @@ struct bstbase2 std::pair bounded_range (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); std::pair ret (node_algorithms::bounded_range (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); - return std::pair( iterator(ret.first, this->real_value_traits_ptr()) - , iterator(ret.second, this->real_value_traits_ptr())); + return std::pair( iterator(ret.first, this->value_traits_ptr()) + , iterator(ret.second, this->value_traits_ptr())); } std::pair bounded_range @@ -364,25 +405,26 @@ struct bstbase2 std::pair bounded_range (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const { - detail::key_nodeptr_comp - key_node_comp(comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_value_traits()); std::pair ret (node_algorithms::bounded_range (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); - return std::pair( const_iterator(ret.first, this->real_value_traits_ptr()) - , const_iterator(ret.second, this->real_value_traits_ptr())); + return std::pair( const_iterator(ret.first, this->value_traits_ptr()) + , const_iterator(ret.second, this->value_traits_ptr())); } + //insert_unique_check template std::pair insert_unique_check (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) { - detail::key_nodeptr_comp - ocomp(key_value_comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + ocomp(key_value_comp, &this->get_value_traits()); std::pair ret = (node_algorithms::insert_unique_check (this->header_ptr(), key, ocomp, commit_data)); - return std::pair(iterator(ret.first, this->real_value_traits_ptr()), ret.second); + return std::pair(iterator(ret.first, this->value_traits_ptr()), ret.second); } template @@ -390,63 +432,101 @@ struct bstbase2 (const_iterator hint, const KeyType &key ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) { - detail::key_nodeptr_comp - ocomp(key_value_comp, &this->get_real_value_traits()); + detail::key_nodeptr_comp + ocomp(key_value_comp, &this->get_value_traits()); std::pair ret = (node_algorithms::insert_unique_check (this->header_ptr(), hint.pointed_node(), key, ocomp, commit_data)); - return std::pair(iterator(ret.first, this->real_value_traits_ptr()), ret.second); + return std::pair(iterator(ret.first, this->value_traits_ptr()), ret.second); } }; +//Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member +//in the first position, but if size is not going to be stored then we'll use an specialization +//that doesn't inherit from size_holder template -struct bstbase +struct bstbase_hack : public detail::size_holder , public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType> { - typedef typename detail::get_real_value_traits::type real_value_traits; typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType> base_type; typedef typename base_type::value_compare value_compare; - typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare; + typedef SizeType size_type; + typedef typename base_type::node_traits node_traits; + typedef typename get_algo + ::type algo_type; + + bstbase_hack(const value_compare & comp, const ValueTraits &vtraits) + : base_type(comp, vtraits) + { + this->sz_traits().set_size(size_type(0)); + } + + typedef detail::size_holder size_traits; + + size_traits &sz_traits() + { return static_cast(*this); } + + const size_traits &sz_traits() const + { return static_cast(*this); } +}; + +//Specialization for ConstantTimeSize == false +template +struct bstbase_hack + : public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType> +{ + typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType> base_type; + typedef typename base_type::value_compare value_compare; + bstbase_hack(const value_compare & comp, const ValueTraits &vtraits) + : base_type(comp, vtraits) + {} + + typedef detail::size_holder size_traits; + + size_traits &sz_traits() + { return s_size_traits; } + + const size_traits &sz_traits() const + { return s_size_traits; } + + static size_traits s_size_traits; +}; + +template +detail::size_holder bstbase_hack::s_size_traits; + +//This class will +template +struct bstbase + : public bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType> +{ + typedef bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType> base_type; + typedef ValueTraits value_traits; + typedef typename base_type::value_compare value_compare; + typedef value_compare key_compare; typedef typename base_type::const_reference const_reference; typedef typename base_type::reference reference; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::node_traits node_traits; typedef typename get_algo - ::type algo_type; + ::type node_algorithms; typedef SizeType size_type; bstbase(const value_compare & comp, const ValueTraits &vtraits) : base_type(comp, vtraits) {} - public: - typedef detail::size_holder size_traits; - - size_traits &sz_traits() - { return *this; } - - const size_traits &sz_traits() const - { return *this; } - - size_type count(const_reference value) const - { return size_type(this->count(value, this->comp())); } - - template - size_type count(const KeyType &key, KeyValueCompare comp) const + //Detach all inserted nodes. This will add exception safety to bstree_impl + //constructors inserting elements. + ~bstbase() { - std::pair ret = this->equal_range(key, comp); - return size_type(std::distance(ret.first, ret.second)); - } - - bool empty() const - { - if(ConstantTimeSize){ - return !this->sz_traits().get_size(); - } - else{ - return algo_type::unique(this->header_ptr()); + if(is_safe_autounlink::value){ + node_algorithms::clear_and_dispose + ( this->header_ptr() + , detail::node_disposer + (detail::null_disposer(), &this->get_value_traits())); } } }; @@ -476,25 +556,18 @@ template - , private detail::clear_on_destructor_base - < bstree_impl - , is_safe_autounlink::type::link_mode>::value - > { template friend class detail::clear_on_destructor_base; public: - typedef ValueTraits value_traits; /// @cond - static const bool external_value_traits = - detail::external_value_traits_bool_is_true::value; - typedef typename detail::get_real_value_traits::type real_value_traits; - typedef bstbase data_type; - typedef tree_iterator iterator_type; - typedef tree_iterator const_iterator_type; + typedef bstbase data_type; + typedef tree_iterator iterator_type; + typedef tree_iterator const_iterator_type; /// @endcond - typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer; - typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(ValueTraits) value_traits; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; @@ -507,7 +580,7 @@ class bstree_impl typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator; typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::detail::reverse_iterator) reverse_iterator; typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::detail::reverse_iterator) const_reverse_iterator; - typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::node_traits) node_traits; + typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::node_traits) node_traits; typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node) node; typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node_ptr) node_ptr; typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::const_node_ptr) const_node_ptr; @@ -517,17 +590,17 @@ class bstree_impl typedef BOOST_INTRUSIVE_IMPDEF(algo_type) node_algorithms; static const bool constant_time_size = ConstantTimeSize; - static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; /// @cond private: //noncopyable BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree_impl) - static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const bool safemode_or_autounlink = is_safe_autounlink::value; //Constant-time size is incompatible with auto-unlink hooks! - BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink))); protected: @@ -549,10 +622,7 @@ class bstree_impl explicit bstree_impl( const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) : data_type(cmp, v_traits) - { - node_algorithms::init_header(this->header_ptr()); - this->sz_traits().set_size(size_type(0)); - } + {} //! Requires: Dereferencing iterator must yield an lvalue of type value_type. //! cmp must be a comparison function that induces a strict weak ordering. @@ -572,8 +642,6 @@ class bstree_impl , const value_traits &v_traits = value_traits()) : data_type(cmp, v_traits) { - node_algorithms::init_header(this->header_ptr()); - this->sz_traits().set_size(size_type(0)); if(unique) this->insert_unique(b, e); else @@ -583,10 +651,8 @@ class bstree_impl //! Effects: to-do //! bstree_impl(BOOST_RV_REF(bstree_impl) x) - : data_type(::boost::move(x.comp()), ::boost::move(x.val_traits())) + : data_type(::boost::move(x.comp()), ::boost::move(x.get_value_traits())) { - node_algorithms::init_header(this->header_ptr()); - this->sz_traits().set_size(size_type(0)); this->swap(x); } @@ -708,8 +774,8 @@ class bstree_impl //! Complexity: Constant. static bstree_impl &container_from_end_iterator(iterator end_iterator) { - return *static_cast - (boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())); + return static_cast + (data_type::get_tree_base_from_root(*boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()))); } //! Precondition: end_iterator must be a valid end const_iterator @@ -722,8 +788,8 @@ class bstree_impl //! Complexity: Constant. static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) { - return *static_cast - (boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())); + return static_cast + (data_type::get_tree_base_from_root(*boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()))); } //! Precondition: it must be a valid iterator @@ -764,14 +830,22 @@ class bstree_impl //! Throws: If value_compare copy-constructor throws. value_compare value_comp() const; + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: Returns true if the container is empty. //! //! Complexity: Constant. //! //! Throws: Nothing. - bool empty() const; - - #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + bool empty() const + { + if(ConstantTimeSize){ + return !this->data_type::sz_traits().get_size(); + } + else{ + return algo_type::unique(this->header_ptr()); + } + } //! Effects: Returns the number of elements stored in the container. //! @@ -831,8 +905,8 @@ class bstree_impl node_algorithms::clone (const_node_ptr(src.header_ptr()) ,node_ptr(this->header_ptr()) - ,detail::node_cloner (cloner, &this->get_real_value_traits()) - ,detail::node_disposer(disposer, &this->get_real_value_traits())); + ,detail::node_cloner (cloner, &this->get_value_traits()) + ,detail::node_disposer(disposer, &this->get_value_traits())); this->sz_traits().set_size(src.sz_traits().get_size()); this->comp() = src.comp(); rollback.release(); @@ -852,13 +926,13 @@ class bstree_impl //! No copy-constructors are called. iterator insert_equal(reference value) { - detail::key_nodeptr_comp - key_node_comp(this->comp(), &this->get_real_value_traits()); - node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + detail::key_nodeptr_comp + key_node_comp(this->comp(), &this->get_value_traits()); + node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); iterator ret(node_algorithms::insert_equal_upper_bound - (this->header_ptr(), to_insert, key_node_comp), this->real_value_traits_ptr()); + (this->header_ptr(), to_insert, key_node_comp), this->value_traits_ptr()); this->sz_traits().increment(); return ret; } @@ -879,13 +953,13 @@ class bstree_impl //! No copy-constructors are called. iterator insert_equal(const_iterator hint, reference value) { - detail::key_nodeptr_comp - key_node_comp(this->comp(), &this->get_real_value_traits()); - node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + detail::key_nodeptr_comp + key_node_comp(this->comp(), &this->get_value_traits()); + node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); iterator ret(node_algorithms::insert_equal - (this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->real_value_traits_ptr()); + (this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->value_traits_ptr()); this->sz_traits().increment(); return ret; } @@ -1077,13 +1151,13 @@ class bstree_impl //! erased between the "insert_check" and "insert_commit" calls. iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) { - node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); node_algorithms::insert_unique_commit (this->header_ptr(), to_insert, commit_data); this->sz_traits().increment(); - return iterator(to_insert, this->real_value_traits_ptr()); + return iterator(to_insert, this->value_traits_ptr()); } //! Requires: value must be an lvalue, "pos" must be @@ -1102,12 +1176,12 @@ class bstree_impl //! by advanced users. iterator insert_before(const_iterator pos, reference value) { - node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); this->sz_traits().increment(); return iterator(node_algorithms::insert_before - (this->header_ptr(), pos.pointed_node(), to_insert), this->real_value_traits_ptr()); + (this->header_ptr(), pos.pointed_node(), to_insert), this->value_traits_ptr()); } //! Requires: value must be an lvalue, and it must be no less @@ -1126,7 +1200,7 @@ class bstree_impl //! by advanced users. void push_back(reference value) { - node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); this->sz_traits().increment(); @@ -1149,7 +1223,7 @@ class bstree_impl //! by advanced users. void push_front(reference value) { - node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); this->sz_traits().increment(); @@ -1243,7 +1317,7 @@ class bstree_impl { node_ptr to_erase(i.pointed_node()); iterator ret(this->erase(i)); - disposer(this->get_real_value_traits().to_value_ptr(to_erase)); + disposer(this->get_value_traits().to_value_ptr(to_erase)); return ret; } @@ -1351,36 +1425,55 @@ class bstree_impl void clear_and_dispose(Disposer disposer) { node_algorithms::clear_and_dispose(this->header_ptr() - , detail::node_disposer(disposer, &this->get_real_value_traits())); + , detail::node_disposer(disposer, &this->get_value_traits())); node_algorithms::init_header(this->header_ptr()); this->sz_traits().set_size(0); } - #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) - //! Effects: Returns the number of contained elements with the given value //! //! Complexity: Logarithmic to the number of elements contained plus lineal //! to number of objects with the given value. //! - //! Throws: Nothing. - size_type count(const_reference value) const; + //! Throws: If `value_compare` throws. + size_type count(const_reference value) const + { return size_type(this->count(value, this->comp())); } //! Effects: Returns the number of contained elements with the given key //! //! Complexity: Logarithmic to the number of elements contained plus lineal //! to number of objects with the given key. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template - size_type count(const KeyType &key, KeyValueCompare comp) const; + size_type count(const KeyType &key, KeyValueCompare comp) const + { + std::pair ret = this->equal_range(key, comp); + return size_type(std::distance(ret.first, ret.second)); + } + + #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //Add non-const overloads to theoretically const members + //as some algorithms have different behavior when non-const versions are used (like splay trees). + size_type count(const_reference value) + { return size_type(this->count(value, this->comp())); } + + template + size_type count(const KeyType &key, KeyValueCompare comp) + { + std::pair ret = this->equal_range(key, comp); + return size_type(std::distance(ret.first, ret.second)); + } + + #else //defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Effects: Returns an iterator to the first element whose //! key is not less than k or end() if that element does not exist. //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. iterator lower_bound(const_reference value); //! Effects: Returns an iterator to the first element whose @@ -1388,7 +1481,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. const_iterator lower_bound(const_reference value) const; //! Effects: Returns an iterator to the first element whose @@ -1396,7 +1489,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template iterator lower_bound(const KeyType &key, KeyValueCompare comp); @@ -1405,7 +1498,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const; @@ -1414,7 +1507,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. iterator upper_bound(const_reference value); //! Effects: Returns an iterator to the first element whose @@ -1423,7 +1516,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template iterator upper_bound(const KeyType &key, KeyValueCompare comp); @@ -1432,7 +1525,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. const_iterator upper_bound(const_reference value) const; //! Effects: Returns an iterator to the first element whose @@ -1441,7 +1534,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const; @@ -1450,7 +1543,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. iterator find(const_reference value); //! Effects: Finds an iterator to the first element whose key is @@ -1458,7 +1551,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template iterator find(const KeyType &key, KeyValueCompare comp); @@ -1467,7 +1560,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. const_iterator find(const_reference value) const; //! Effects: Finds a const_iterator to the first element whose key is @@ -1475,7 +1568,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template const_iterator find(const KeyType &key, KeyValueCompare comp) const; @@ -1485,7 +1578,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. std::pair equal_range(const_reference value); //! Effects: Finds a range containing all elements whose key is k or @@ -1494,7 +1587,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template std::pair equal_range(const KeyType &key, KeyValueCompare comp); @@ -1504,7 +1597,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `value_compare` throws. std::pair equal_range(const_reference value) const; @@ -1514,7 +1607,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: Nothing. + //! Throws: If `comp` throws. template std::pair equal_range(const KeyType &key, KeyValueCompare comp) const; @@ -1530,7 +1623,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: If the predicate throws. + //! Throws: If `value_compare` throws. //! //! Note: This function can be more efficient than calling upper_bound //! and lower_bound for lower_value and upper_value. @@ -1553,7 +1646,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: If "comp" throws. + //! Throws: If `comp` throws. //! //! Note: This function can be more efficient than calling upper_bound //! and lower_bound for lower_key and upper_key. @@ -1574,7 +1667,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: If the predicate throws. + //! Throws: If `value_compare` throws. //! //! Note: This function can be more efficient than calling upper_bound //! and lower_bound for lower_value and upper_value. @@ -1597,7 +1690,7 @@ class bstree_impl //! //! Complexity: Logarithmic. //! - //! Throws: If "comp" throws. + //! Throws: If `comp` throws. //! //! Note: This function can be more efficient than calling upper_bound //! and lower_bound for lower_key and upper_key. @@ -1691,7 +1784,7 @@ class bstree_impl this->sz_traits().decrement(); if(safemode_or_autounlink)//If this is commented does not work with normal_link node_algorithms::init(to_be_disposed); - return this->get_real_value_traits().to_value_ptr(to_be_disposed); + return this->get_value_traits().to_value_ptr(to_be_disposed); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -1966,12 +2059,11 @@ class bstree public: typedef typename Base::value_compare value_compare; typedef typename Base::value_traits value_traits; - typedef typename Base::real_value_traits real_value_traits; typedef typename Base::iterator iterator; typedef typename Base::const_iterator const_iterator; //Assert if passed value traits are compatible with the type - BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_STATIC_ASSERT((detail::is_same::value)); bstree( const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index 01eae13..01e0b49 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -15,8 +15,8 @@ #define BOOST_INTRUSIVE_LIST_HPP #include -#include #include +#include #include #include #include @@ -65,37 +65,32 @@ template class list_impl : private detail::clear_on_destructor_base < list_impl - , is_safe_autounlink::type::link_mode>::value + , is_safe_autounlink::value > { template friend class detail::clear_on_destructor_base; //Public typedefs public: - typedef ValueTraits value_traits; - /// @cond - static const bool external_value_traits = - detail::external_value_traits_bool_is_true::value; - typedef typename detail::get_real_value_traits::type real_value_traits; - /// @endcond - typedef typename real_value_traits::pointer pointer; - typedef typename real_value_traits::const_pointer const_pointer; + typedef ValueTraits value_traits; + typedef typename value_traits::pointer pointer; + typedef typename value_traits::const_pointer const_pointer; typedef typename pointer_traits::element_type value_type; typedef typename pointer_traits::reference reference; typedef typename pointer_traits::reference const_reference; typedef typename pointer_traits::difference_type difference_type; typedef SizeType size_type; - typedef list_iterator iterator; - typedef list_iterator const_iterator; + typedef list_iterator iterator; + typedef list_iterator const_iterator; typedef boost::intrusive::detail::reverse_iterator reverse_iterator; typedef boost::intrusive::detail::reverse_iteratorconst_reverse_iterator; - typedef typename real_value_traits::node_traits node_traits; + typedef typename value_traits::node_traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef circular_list_algorithms node_algorithms; static const bool constant_time_size = ConstantTimeSize; - static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; /// @cond @@ -105,11 +100,11 @@ class list_impl //noncopyable BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl) - static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const bool safemode_or_autounlink = is_safe_autounlink::value; //Constant-time size is incompatible with auto-unlink hooks! BOOST_STATIC_ASSERT(!(constant_time_size && - ((int)real_value_traits::link_mode == (int)auto_unlink) + ((int)value_traits::link_mode == (int)auto_unlink) )); node_ptr get_root_node() @@ -139,54 +134,27 @@ class list_impl const size_traits &priv_size_traits() const { return data_.root_plus_size_; } - const real_value_traits &get_real_value_traits(detail::bool_) const - { return data_; } - - const real_value_traits &get_real_value_traits(detail::bool_) const - { return data_.get_value_traits(*this); } - - real_value_traits &get_real_value_traits(detail::bool_) - { return data_; } - - real_value_traits &get_real_value_traits(detail::bool_) - { return data_.get_value_traits(*this); } - const value_traits &priv_value_traits() const { return data_; } value_traits &priv_value_traits() { return data_; } - protected: - node &prot_root_node() - { return data_.root_plus_size_.root_; } + typedef typename pointer_traits::template + rebind_pointer::type const_value_traits_ptr; - node const &prot_root_node() const - { return data_.root_plus_size_.root_; } - - void prot_set_size(size_type s) - { data_.root_plus_size_.set_size(s); } + const_value_traits_ptr value_traits_ptr() const + { return pointer_traits::pointer_to(this->priv_value_traits()); } /// @endcond public: - const real_value_traits &get_real_value_traits() const - { return this->get_real_value_traits(detail::bool_()); } - - real_value_traits &get_real_value_traits() - { return this->get_real_value_traits(detail::bool_()); } - - typedef typename pointer_traits::template rebind_pointer::type const_real_value_traits_ptr; - - const_real_value_traits_ptr real_value_traits_ptr() const - { return pointer_traits::pointer_to(this->get_real_value_traits()); } - //! Effects: constructs an empty list. //! //! Complexity: Constant //! - //! Throws: If real_value_traits::node_traits::node + //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). explicit list_impl(const value_traits &v_traits = value_traits()) : data_(v_traits) @@ -201,7 +169,7 @@ class list_impl //! //! Complexity: Linear in std::distance(b, e). No copy constructors are called. //! - //! Throws: If real_value_traits::node_traits::node + //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). template list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) @@ -253,7 +221,7 @@ class list_impl //! Note: Does not affect the validity of iterators and references. void push_back(reference value) { - node_ptr to_insert = get_real_value_traits().to_node_ptr(value); + node_ptr to_insert = priv_value_traits().to_node_ptr(value); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); node_algorithms::link_before(this->get_root_node(), to_insert); @@ -272,7 +240,7 @@ class list_impl //! Note: Does not affect the validity of iterators and references. void push_front(reference value) { - node_ptr to_insert = get_real_value_traits().to_node_ptr(value); + node_ptr to_insert = priv_value_traits().to_node_ptr(value); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert); @@ -309,7 +277,7 @@ class list_impl this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); } //! Effects: Erases the first element of the list. @@ -342,7 +310,7 @@ class list_impl this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); } //! Effects: Returns a reference to the first element of the list. @@ -351,7 +319,7 @@ class list_impl //! //! Complexity: Constant. reference front() - { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } + { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! Effects: Returns a const_reference to the first element of the list. //! @@ -359,7 +327,7 @@ class list_impl //! //! Complexity: Constant. const_reference front() const - { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } + { return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } //! Effects: Returns a reference to the last element of the list. //! @@ -367,7 +335,7 @@ class list_impl //! //! Complexity: Constant. reference back() - { return *get_real_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); } + { return *priv_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); } //! Effects: Returns a const_reference to the last element of the list. //! @@ -375,7 +343,7 @@ class list_impl //! //! Complexity: Constant. const_reference back() const - { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); } + { return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); } //! Effects: Returns an iterator to the first element contained in the list. //! @@ -383,7 +351,7 @@ class list_impl //! //! Complexity: Constant. iterator begin() - { return iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); } + { return iterator(node_traits::get_next(this->get_root_node()), value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. //! @@ -399,7 +367,7 @@ class list_impl //! //! Complexity: Constant. const_iterator cbegin() const - { return const_iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); } + { return const_iterator(node_traits::get_next(this->get_root_node()), value_traits_ptr()); } //! Effects: Returns an iterator to the end of the list. //! @@ -407,7 +375,7 @@ class list_impl //! //! Complexity: Constant. iterator end() - { return iterator(this->get_root_node(), real_value_traits_ptr()); } + { return iterator(this->get_root_node(), value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. //! @@ -423,7 +391,7 @@ class list_impl //! //! Complexity: Constant. const_iterator cend() const - { return const_iterator(detail::uncast(this->get_root_node()), real_value_traits_ptr()); } + { return const_iterator(detail::uncast(this->get_root_node()), value_traits_ptr()); } //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed list. @@ -663,7 +631,7 @@ class list_impl this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(this->get_real_value_traits().to_value_ptr(to_erase)); + disposer(this->priv_value_traits().to_value_ptr(to_erase)); return i.unconst(); } @@ -697,7 +665,7 @@ class list_impl bp = node_traits::get_next(bp); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); } return e.unconst(); @@ -743,7 +711,7 @@ class list_impl ++it; if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); } node_algorithms::init_header(this->get_root_node()); this->priv_size_traits().set_size(0); @@ -789,12 +757,12 @@ class list_impl //! Note: Does not affect the validity of iterators and references. iterator insert(const_iterator p, reference value) { - node_ptr to_insert = this->get_real_value_traits().to_node_ptr(value); + node_ptr to_insert = this->priv_value_traits().to_node_ptr(value); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); node_algorithms::link_before(p.pointed_node(), to_insert); this->priv_size_traits().increment(); - return iterator(to_insert, real_value_traits_ptr()); + return iterator(to_insert, value_traits_ptr()); } //! Requires: Dereferencing iterator must yield @@ -887,7 +855,7 @@ class list_impl //! new_ele must point to an element contained in list x. //! //! Effects: Transfers the value pointed by new_ele, from list x to this list, - //! before the the element pointed by p. No destructors or copy constructors are called. + //! before the element pointed by p. No destructors or copy constructors are called. //! If p == new_ele or p == ++new_ele, this function is a null operation. //! //! Throws: Nothing. @@ -907,7 +875,7 @@ class list_impl //! f and e must point to elements contained in list x. //! //! Effects: Transfers the range pointed by f and e from list x to this list, - //! before the the element pointed by p. No destructors or copy constructors are called. + //! before the element pointed by p. No destructors or copy constructors are called. //! //! Throws: Nothing. //! @@ -929,7 +897,7 @@ class list_impl //! n == std::distance(f, e) //! //! Effects: Transfers the range pointed by f and e from list x to this list, - //! before the the element pointed by p. No destructors or copy constructors are called. + //! before the element pointed by p. No destructors or copy constructors are called. //! //! Throws: Nothing. //! @@ -957,7 +925,7 @@ class list_impl //! Effects: This function sorts the list *this according to std::less. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! - //! Throws: If real_value_traits::node_traits::node + //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or std::less throws. Basic guarantee. //! @@ -973,7 +941,7 @@ class list_impl //! Effects: This function sorts the list *this according to p. The sort is //! stable, that is, the relative order of equivalent elements is preserved. //! - //! Throws: If real_value_traits::node_traits::node + //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the predicate throws. Basic guarantee. //! @@ -1227,8 +1195,8 @@ class list_impl static iterator s_iterator_to(reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); - return iterator(real_value_traits::to_node_ptr(value), const_real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value))); + return iterator(value_traits::to_node_ptr(value), const_value_traits_ptr()); } //! Requires: value must be a const reference to a value inserted in a list. @@ -1245,8 +1213,8 @@ class list_impl static const_iterator s_iterator_to(const_reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast (value)))); - return const_iterator(real_value_traits::to_node_ptr(const_cast (value)), const_real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(const_cast (value)))); + return const_iterator(value_traits::to_node_ptr(const_cast (value)), const_value_traits_ptr()); } //! Requires: value must be a reference to a value inserted in a list. @@ -1260,8 +1228,8 @@ class list_impl //! Note: Iterators and references are not invalidated. iterator iterator_to(reference value) { - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); - return iterator(real_value_traits::to_node_ptr(value), real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value))); + return iterator(this->priv_value_traits().to_node_ptr(value), value_traits_ptr()); } //! Requires: value must be a const reference to a value inserted in a list. @@ -1275,8 +1243,8 @@ class list_impl //! Note: Iterators and references are not invalidated. const_iterator iterator_to(const_reference value) const { - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast (value)))); - return const_iterator(real_value_traits::to_node_ptr(const_cast (value)), real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(const_cast (value)))); + return const_iterator(this->priv_value_traits().to_node_ptr(const_cast (value)), value_traits_ptr()); } /// @cond @@ -1468,9 +1436,8 @@ class list Options... #endif >::type Base; - typedef typename Base::real_value_traits real_value_traits; //Assert if passed value traits are compatible with the type - BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_STATIC_ASSERT((detail::is_same::value)); BOOST_MOVABLE_BUT_NOT_COPYABLE(list) public: diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index c471826..51ab1bd 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -15,9 +15,9 @@ #define BOOST_INTRUSIVE_SLIST_HPP #include +#include #include #include -#include #include #include #include @@ -101,34 +101,29 @@ template class slist_impl : private detail::clear_on_destructor_base < slist_impl - , is_safe_autounlink::type::link_mode>::value + , is_safe_autounlink::value > { template friend class detail::clear_on_destructor_base; //Public typedefs public: typedef ValueTraits value_traits; - /// @cond - static const bool external_value_traits = - detail::external_value_traits_bool_is_true::value; - typedef typename detail::get_real_value_traits::type real_value_traits; - /// @endcond - typedef typename real_value_traits::pointer pointer; - typedef typename real_value_traits::const_pointer const_pointer; + typedef typename value_traits::pointer pointer; + typedef typename value_traits::const_pointer const_pointer; typedef typename pointer_traits::element_type value_type; typedef typename pointer_traits::reference reference; typedef typename pointer_traits::reference const_reference; typedef typename pointer_traits::difference_type difference_type; typedef SizeType size_type; - typedef slist_iterator iterator; - typedef slist_iterator const_iterator; - typedef typename real_value_traits::node_traits node_traits; + typedef slist_iterator iterator; + typedef slist_iterator const_iterator; + typedef typename value_traits::node_traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos); - static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos); static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos); @@ -145,14 +140,14 @@ class slist_impl //noncopyable BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl) - static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const bool safemode_or_autounlink = is_safe_autounlink::value; //Constant-time size is incompatible with auto-unlink hooks! - BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink))); //Linear singly linked lists are incompatible with auto-unlink hooks! - BOOST_STATIC_ASSERT(!(linear && ((int)real_value_traits::link_mode == (int)auto_unlink))); + BOOST_STATIC_ASSERT(!(linear && ((int)value_traits::link_mode == (int)auto_unlink))); //A list with cached last node is incompatible with auto-unlink hooks! - BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink))); + BOOST_STATIC_ASSERT(!(cache_last && ((int)value_traits::link_mode == (int)auto_unlink))); node_ptr get_end_node() { return node_ptr(linear ? node_ptr() : this->get_root_node()); } @@ -230,18 +225,6 @@ class slist_impl const size_traits &priv_size_traits() const { return data_.root_plus_size_; } - const real_value_traits &get_real_value_traits(detail::bool_) const - { return data_; } - - const real_value_traits &get_real_value_traits(detail::bool_) const - { return data_.get_value_traits(*this); } - - real_value_traits &get_real_value_traits(detail::bool_) - { return data_; } - - real_value_traits &get_real_value_traits(detail::bool_) - { return data_.get_value_traits(*this); } - const value_traits &priv_value_traits() const { return data_; } @@ -258,20 +241,15 @@ class slist_impl void prot_set_size(size_type s) { data_.root_plus_size_.set_size(s); } - /// @endcond - public: - const real_value_traits &get_real_value_traits() const - { return this->get_real_value_traits(detail::bool_()); } + typedef typename pointer_traits::template + rebind_pointer::type const_value_traits_ptr; - real_value_traits &get_real_value_traits() - { return this->get_real_value_traits(detail::bool_()); } + const_value_traits_ptr value_traits_ptr() const + { return pointer_traits::pointer_to(this->priv_value_traits()); } - typedef typename pointer_traits::template rebind_pointer::type const_real_value_traits_ptr; - - const_real_value_traits_ptr real_value_traits_ptr() const - { return pointer_traits::pointer_to(this->get_real_value_traits()); } + /// @endcond public: @@ -403,7 +381,7 @@ class slist_impl ++it; if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); } this->set_default_constructed_state(); } @@ -420,7 +398,7 @@ class slist_impl //! Note: Does not affect the validity of iterators and references. void push_front(reference value) { - node_ptr to_insert = get_real_value_traits().to_node_ptr(value); + node_ptr to_insert = priv_value_traits().to_node_ptr(value); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); if(cache_last){ @@ -446,7 +424,7 @@ class slist_impl void push_back(reference value) { BOOST_STATIC_ASSERT((cache_last)); - node_ptr n = get_real_value_traits().to_node_ptr(value); + node_ptr n = priv_value_traits().to_node_ptr(value); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); node_algorithms::link_after(this->get_last_node(), n); @@ -485,7 +463,7 @@ class slist_impl this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); if(cache_last){ if(this->empty()){ this->set_last_node(this->get_root_node()); @@ -499,7 +477,7 @@ class slist_impl //! //! Complexity: Constant. reference front() - { return *this->get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } + { return *this->priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! Effects: Returns a const_reference to the first element of the list. //! @@ -507,7 +485,7 @@ class slist_impl //! //! Complexity: Constant. const_reference front() const - { return *this->get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } + { return *this->priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } //! Effects: Returns a reference to the last element of the list. //! @@ -520,7 +498,7 @@ class slist_impl reference back() { BOOST_STATIC_ASSERT((cache_last)); - return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); + return *this->priv_value_traits().to_value_ptr(this->get_last_node()); } //! Effects: Returns a const_reference to the last element of the list. @@ -534,7 +512,7 @@ class slist_impl const_reference back() const { BOOST_STATIC_ASSERT((cache_last)); - return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); + return *this->priv_value_traits().to_value_ptr(this->get_last_node()); } //! Effects: Returns an iterator to the first element contained in the list. @@ -543,7 +521,7 @@ class slist_impl //! //! Complexity: Constant. iterator begin() - { return iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } + { return iterator (node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. //! @@ -551,7 +529,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator begin() const - { return const_iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } + { return const_iterator (node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. //! @@ -559,7 +537,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator cbegin() const - { return const_iterator(node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } + { return const_iterator(node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); } //! Effects: Returns an iterator to the end of the list. //! @@ -567,7 +545,7 @@ class slist_impl //! //! Complexity: Constant. iterator end() - { return iterator(this->get_end_node(), this->real_value_traits_ptr()); } + { return iterator(this->get_end_node(), this->value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. //! @@ -575,7 +553,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator end() const - { return const_iterator(detail::uncast(this->get_end_node()), this->real_value_traits_ptr()); } + { return const_iterator(detail::uncast(this->get_end_node()), this->value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. //! @@ -592,7 +570,7 @@ class slist_impl //! //! Complexity: Constant. iterator before_begin() - { return iterator(this->get_root_node(), this->real_value_traits_ptr()); } + { return iterator(this->get_root_node(), this->value_traits_ptr()); } //! Effects: Returns an iterator that points to a position //! before the first element. Equivalent to "end()" @@ -601,7 +579,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator before_begin() const - { return const_iterator(detail::uncast(this->get_root_node()), this->real_value_traits_ptr()); } + { return const_iterator(detail::uncast(this->get_root_node()), this->value_traits_ptr()); } //! Effects: Returns an iterator that points to a position //! before the first element. Equivalent to "end()" @@ -623,7 +601,7 @@ class slist_impl { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); - return iterator (this->get_last_node(), this->real_value_traits_ptr()); + return iterator (this->get_last_node(), this->value_traits_ptr()); } //! Effects: Returns a const_iterator to the last element contained in the list. @@ -637,7 +615,7 @@ class slist_impl { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); - return const_iterator (this->get_last_node(), this->real_value_traits_ptr()); + return const_iterator (this->get_last_node(), this->value_traits_ptr()); } //! Effects: Returns a const_iterator to the last element contained in the list. @@ -648,7 +626,7 @@ class slist_impl //! //! Note: This function is present only if cached_last<> option is true. const_iterator clast() const - { return const_iterator(this->get_last_node(), this->real_value_traits_ptr()); } + { return const_iterator(this->get_last_node(), this->value_traits_ptr()); } //! Precondition: end_iterator must be a valid end iterator //! of slist. @@ -788,7 +766,7 @@ class slist_impl //! Note: Does not affect the validity of iterators and references. iterator insert_after(const_iterator prev_p, reference value) { - node_ptr n = get_real_value_traits().to_node_ptr(value); + node_ptr n = priv_value_traits().to_node_ptr(value); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); node_ptr prev_n(prev_p.pointed_node()); @@ -797,7 +775,7 @@ class slist_impl this->set_last_node(n); } this->priv_size_traits().increment(); - return iterator (n, this->real_value_traits_ptr()); + return iterator (n, this->value_traits_ptr()); } //! Requires: Dereferencing iterator must yield @@ -819,7 +797,7 @@ class slist_impl size_type count = 0; node_ptr prev_n(prev_p.pointed_node()); for (; f != l; ++f, ++count){ - const node_ptr n = get_real_value_traits().to_node_ptr(*f); + const node_ptr n = priv_value_traits().to_node_ptr(*f); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); node_algorithms::link_after(prev_n, n); @@ -1026,7 +1004,7 @@ class slist_impl } if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); return it.unconst(); } @@ -1045,7 +1023,7 @@ class slist_impl node_algorithms::unlink_after(prev_n); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(real_value_traits::to_value_ptr(to_erase)); + disposer(value_traits::to_value_ptr(to_erase)); return it.unconst(); } @@ -1079,7 +1057,7 @@ class slist_impl fp = node_traits::get_next(fp); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); } if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){ @@ -1691,8 +1669,7 @@ class slist_impl static iterator s_iterator_to(reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); - return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr()); + return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr()); } //! Requires: value must be a const reference to a value inserted in a list. @@ -1709,8 +1686,7 @@ class slist_impl static const_iterator s_iterator_to(const_reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast (value)))); - return const_iterator (value_traits::to_node_ptr(const_cast (value)), const_real_value_traits_ptr()); + return const_iterator(value_traits::to_node_ptr(const_cast (value)), const_value_traits_ptr()); } //! Requires: value must be a reference to a value inserted in a list. @@ -1724,8 +1700,8 @@ class slist_impl //! Note: Iterators and references are not invalidated. iterator iterator_to(reference value) { - //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); - return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value))); + return iterator (this->priv_value_traits().to_node_ptr(value), this->value_traits_ptr()); } //! Requires: value must be a const reference to a value inserted in a list. @@ -1739,8 +1715,8 @@ class slist_impl //! Note: Iterators and references are not invalidated. const_iterator iterator_to(const_reference value) const { - //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast (value)))); - return const_iterator (value_traits::to_node_ptr(const_cast (value)), this->real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(this->priv_value_traits().to_node_ptr(const_cast (value)))); + return const_iterator(this->priv_value_traits().to_node_ptr(const_cast (value)), this->value_traits_ptr()); } //! Returns: The iterator to the element before i in the list. @@ -1789,11 +1765,11 @@ class slist_impl const_iterator previous(const_iterator prev_from, const_iterator i) const { if(cache_last && (i.pointed_node() == this->get_end_node())){ - return const_iterator(detail::uncast(this->get_last_node()), this->real_value_traits_ptr()); + return const_iterator(detail::uncast(this->get_last_node()), this->value_traits_ptr()); } return const_iterator (node_algorithms::get_previous_node - (prev_from.pointed_node(), i.pointed_node()), this->real_value_traits_ptr()); + (prev_from.pointed_node(), i.pointed_node()), this->value_traits_ptr()); } ///@cond @@ -1844,8 +1820,8 @@ class slist_impl BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0); BOOST_INTRUSIVE_INVARIANT_ASSERT (size_type(std::distance - ( iterator(f, this->real_value_traits_ptr()) - , iterator(before_l, this->real_value_traits_ptr()))) + ( iterator(f, this->value_traits_ptr()) + , iterator(before_l, this->value_traits_ptr()))) +1 == n); this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); if(constant_time_size){ @@ -2171,9 +2147,8 @@ class slist Options... #endif >::type Base; - typedef typename Base::real_value_traits real_value_traits; //Assert if passed value traits are compatible with the type - BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_STATIC_ASSERT((detail::is_same::value)); BOOST_MOVABLE_BUT_NOT_COPYABLE(slist) public: diff --git a/test/generic_set_test.hpp b/test/generic_set_test.hpp index 050d001..2a46ba9 100644 --- a/test/generic_set_test.hpp +++ b/test/generic_set_test.hpp @@ -172,6 +172,12 @@ void test_generic_set::test_insert(std::vector(values[2])); + BOOST_TEST (&*ic == &values[2]); + ic = set_type::s_iterator_to (const_cast(values[2])); + BOOST_TEST (&*ic == &values[2]); + testset.erase (i); { int init_values [] = { 1, 3, 5 }; TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } diff --git a/test/list_test.cpp b/test/list_test.cpp index 94521c5..54d3061 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -234,6 +234,13 @@ void test_list i = list_type::s_iterator_to (values[4]); BOOST_TEST (&*i == &values[4]); + typename list_type::const_iterator ic; + ic = testlist.iterator_to (const_cast(values[4])); + BOOST_TEST (&*ic == &values[4]); + + ic = list_type::s_iterator_to (const_cast(values[4])); + BOOST_TEST (&*ic == &values[4]); + i = testlist.erase (i); BOOST_TEST (i == testlist.end()); diff --git a/test/slist_test.cpp b/test/slist_test.cpp index ac9a635..0ea0c2b 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -275,6 +275,13 @@ void test_slist BOOST_TEST (&*i == &values[4]); i = list_type::s_iterator_to (values[4]); BOOST_TEST (&*i == &values[4]); + + typename list_type::const_iterator ic; + ic = testlist.iterator_to (const_cast(values[4])); + BOOST_TEST (&*ic == &values[4]); + ic = list_type::s_iterator_to (const_cast(values[4])); + BOOST_TEST (&*ic == &values[4]); + i = testlist.previous (i); BOOST_TEST (&*i == &values[0]); diff --git a/test/stateful_value_traits_test.cpp b/test/stateful_value_traits_test.cpp index c5b43ba..3386c7c 100644 --- a/test/stateful_value_traits_test.cpp +++ b/test/stateful_value_traits_test.cpp @@ -57,16 +57,16 @@ struct stateful_value_traits : values_(vals), node_array_(node_array) {} - node_ptr to_node_ptr (value_type &value) + node_ptr to_node_ptr (value_type &value) const { return node_array_ + (&value - values_); } const_node_ptr to_node_ptr (const value_type &value) const { return node_array_ + (&value - values_); } - pointer to_value_ptr(node_ptr n) + pointer to_value_ptr(const node_ptr &n) const { return values_ + (n - node_array_); } - const_pointer to_value_ptr(const_node_ptr n) const + const_pointer to_value_ptr(const const_node_ptr &n) const { return values_ + (n - node_array_); } pointer values_; @@ -123,9 +123,18 @@ int main() ; it != itend ; ++it){ my_list.push_front(*it); + if(&*my_list.iterator_to(*it) != &my_list.front()) + return 1; my_slist.push_front(*it); - my_set.insert(*it); + if(&*my_slist.iterator_to(*it) != &my_slist.front()) + return 1; + Set::iterator sit = my_set.insert(*it).first; + if(&*my_set.iterator_to(*it) != &*sit) + return 1; + Uset::iterator uit = my_uset.insert(*it).first; my_uset.insert(*it); + if(&*my_uset.iterator_to(*it) != &*uit) + return 1; } //Now test lists