diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 58865b4..f0d1056 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -29,12 +29,12 @@ doxygen autodoc \"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\ \"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\ \"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\ + \"BOOST_CONTAINER_NOEXCEPT=noexcept\" \\ + \"BOOST_CONTAINER_NOEXCEPT_IF(T)=noexcept(T)\" \\ \"BOOST_RV_REF(T)=T &&\" \\ \"BOOST_RV_REF_BEG=\" \\ \"BOOST_RV_REF_END=&&\" \\ \"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\ - \"BOOST_RV_REF_2_TEMPL_ARGS(T,a,b)=T &&\" \\ - \"BOOST_RV_REF_3_TEMPL_ARGS(T,a,b,c)=TT &&\" \\ \"BOOST_FWD_REF(a)=a &&\"" "boost.doxygen.reftitle=Boost.Container Header Reference" ; diff --git a/doc/container.qbk b/doc/container.qbk index 8b71c43..75f4a3f 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -623,7 +623,8 @@ use [*Boost.Container]? There are several reasons for that: [@https://svn.boost.org/trac/boost/ticket/7139 #7139], [@https://svn.boost.org/trac/boost/ticket/7215 #7215], [@https://svn.boost.org/trac/boost/ticket/7232 #7232], - [@https://svn.boost.org/trac/boost/ticket/7269 #7269]. + [@https://svn.boost.org/trac/boost/ticket/7269 #7269], + [@https://svn.boost.org/trac/boost/ticket/7439 #7439]. * Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers * Corrected aliasing errors. diff --git a/include/boost/container/container_fwd.hpp b/include/boost/container/container_fwd.hpp index c52b04a..bdefd81 100644 --- a/include/boost/container/container_fwd.hpp +++ b/include/boost/container/container_fwd.hpp @@ -49,85 +49,85 @@ namespace container { //vector class template > + ,class Allocator = std::allocator > class vector; //vector class template > + ,class Allocator = std::allocator > class stable_vector; //vector class template > + ,class Allocator = std::allocator > class deque; //list class template > + ,class Allocator = std::allocator > class list; //slist class template > + ,class Allocator = std::allocator > class slist; //set class -template - ,class A = std::allocator > +template + ,class Allocator = std::allocator > class set; //multiset class -template - ,class A = std::allocator > +template + ,class Allocator = std::allocator > class multiset; //map class template - ,class A = std::allocator > > + ,class Compare = std::less + ,class Allocator = std::allocator > > class map; //multimap class template - ,class A = std::allocator > > + ,class Compare = std::less + ,class Allocator = std::allocator > > class multimap; //flat_set class -template - ,class A = std::allocator > +template + ,class Allocator = std::allocator > class flat_set; //flat_multiset class -template - ,class A = std::allocator > +template + ,class Allocator = std::allocator > class flat_multiset; //flat_map class template - ,class A = std::allocator > > + ,class Compare = std::less + ,class Allocator = std::allocator > > class flat_map; //flat_multimap class template - ,class A = std::allocator > > + ,class Compare = std::less + ,class Allocator = std::allocator > > class flat_multimap; //basic_string class template - ,class A = std::allocator > + ,class Allocator = std::allocator > class basic_string; //! Type used to tag that the input range is diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index 52b3b68..b63dab3 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -67,17 +67,17 @@ namespace container { /// @cond #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif class deque; -template +template struct deque_value_traits { typedef T value_type; - typedef A allocator_type; + typedef Allocator allocator_type; static const bool trivial_dctr = boost::has_trivial_destructor::value; static const bool trivial_dctr_after_move = false; //::boost::has_trivial_destructor_after_move::value || trivial_dctr; @@ -96,12 +96,12 @@ inline std::size_t deque_buf_size(std::size_t size) // Deque base class. It has two purposes. First, its constructor // and destructor allocate (but don't initialize) storage. This makes // exception safety easier. -template +template class deque_base { BOOST_COPYABLE_AND_MOVABLE(deque_base) public: - typedef allocator_traits val_alloc_traits_type; + typedef allocator_traits val_alloc_traits_type; typedef typename val_alloc_traits_type::value_type val_alloc_val; typedef typename val_alloc_traits_type::pointer val_alloc_ptr; typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr; @@ -117,13 +117,13 @@ class deque_base typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr; typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref; typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref; - typedef A allocator_type; + typedef Allocator allocator_type; typedef allocator_type stored_allocator_type; typedef val_alloc_size size_type; protected: - typedef deque_value_traits traits_t; + typedef deque_value_traits traits_t; typedef ptr_alloc_t map_allocator_type; static size_type s_buffer_size() { return deque_buf_size(sizeof(T)); } @@ -163,7 +163,7 @@ class deque_base // [map, map + map_size) is a valid, non-empty range. // [start.node, finish.node] is a valid range contained within // [map, map + map_size). - // A pointer in the range [map, map + map_size) points to an allocated node + // Allocator pointer in the range [map, map + map_size) points to an allocated node // if and only if the pointer is in the range [start.node, finish.node]. class const_iterator : public std::iterator { public: - static size_type s_buffer_size() { return deque_base::s_buffer_size(); } + static size_type s_buffer_size() { return deque_base::s_buffer_size(); } typedef std::random_access_iterator_tag iterator_category; typedef val_alloc_val value_type; @@ -182,8 +182,8 @@ class deque_base typedef ptr_alloc_ptr index_pointer; typedef const_iterator self_t; - friend class deque; - friend class deque_base; + friend class deque; + friend class deque_base; protected: val_alloc_ptr m_cur; @@ -323,8 +323,8 @@ class deque_base typedef ptr_alloc_ptr index_pointer; typedef const_iterator self_t; - friend class deque; - friend class deque_base; + friend class deque; + friend class deque_base; private: explicit iterator(const const_iterator& x) : const_iterator(x){} @@ -525,15 +525,15 @@ class deque_base //! Deque class //! #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif -class deque : protected deque_base +class deque : protected deque_base { /// @cond private: - typedef deque_base Base; + typedef deque_base Base; /// @endcond public: @@ -544,19 +544,19 @@ class deque : protected deque_base // ////////////////////////////////////////////// - typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator; - typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; + typedef T value_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator; + typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; /// @cond @@ -568,7 +568,7 @@ class deque : protected deque_base typedef container_detail::advanced_insert_aux_int advanced_insert_aux_int_t; typedef repeat_iterator r_iterator; typedef boost::move_iterator move_it; - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; /// @endcond @@ -607,7 +607,7 @@ class deque : protected deque_base explicit deque(size_type n) : Base(n, allocator_type()) { - container_detail::default_construct_aux_proxy proxy(this->alloc(), n); + container_detail::default_construct_aux_proxy proxy(this->alloc(), n); proxy.uninitialized_copy_remaining_to(this->begin()); //deque_base will deallocate in case of exception... } @@ -1020,7 +1020,7 @@ class deque : protected deque_base this->priv_erase_last_n(len - new_size); else{ const size_type n = new_size - this->size(); - container_detail::default_construct_aux_proxy proxy(this->alloc(), n); + container_detail::default_construct_aux_proxy proxy(this->alloc(), n); priv_insert_back_aux_impl(n, proxy); } } @@ -1176,7 +1176,7 @@ class deque : protected deque_base this->priv_push_front_simple_commit(); } else{ - typedef container_detail::advanced_insert_aux_non_movable_emplace type; + typedef container_detail::advanced_insert_aux_non_movable_emplace type; type &&proxy = type(this->alloc(), boost::forward(args)...); this->priv_insert_front_aux_impl(1, proxy); } @@ -1199,7 +1199,7 @@ class deque : protected deque_base this->priv_push_back_simple_commit(); } else{ - typedef container_detail::advanced_insert_aux_non_movable_emplace type; + typedef container_detail::advanced_insert_aux_non_movable_emplace type; type &&proxy = type(this->alloc(), boost::forward(args)...); this->priv_insert_back_aux_impl(1, proxy); } @@ -1226,7 +1226,7 @@ class deque : protected deque_base return (this->end()-1); } else{ - typedef container_detail::advanced_insert_aux_emplace type; + typedef container_detail::advanced_insert_aux_emplace type; type &&proxy = type(this->alloc(), boost::forward(args)...); return this->priv_insert_aux_impl(p, 1, proxy); } @@ -1249,7 +1249,7 @@ class deque : protected deque_base else{ \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT \ (advanced_insert_aux_non_movable_emplace, n), arg) \ - proxy \ + proxy \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ priv_insert_front_aux_impl(1, proxy); \ } \ @@ -1268,7 +1268,7 @@ class deque : protected deque_base else{ \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT( \ advanced_insert_aux_non_movable_emplace, n), arg) \ - proxy \ + proxy \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ priv_insert_back_aux_impl(1, proxy); \ } \ @@ -1288,7 +1288,7 @@ class deque : protected deque_base } \ else{ \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ - proxy \ + proxy \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ return this->priv_insert_aux_impl(p, 1, proxy); \ } \ @@ -1424,7 +1424,7 @@ class deque : protected deque_base #endif ) { - container_detail::advanced_insert_aux_proxy proxy(this->alloc(), first, last); + container_detail::advanced_insert_aux_proxy proxy(this->alloc(), first, last); return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy); } #endif @@ -1978,36 +1978,36 @@ class deque : protected deque_base }; // Nonmember functions. -template -inline bool operator==(const deque& x, const deque& y) +template +inline bool operator==(const deque& x, const deque& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } -template -inline bool operator<(const deque& x, const deque& y) +template +inline bool operator<(const deque& x, const deque& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } -template -inline bool operator!=(const deque& x, const deque& y) +template +inline bool operator!=(const deque& x, const deque& y) { return !(x == y); } -template -inline bool operator>(const deque& x, const deque& y) +template +inline bool operator>(const deque& x, const deque& y) { return y < x; } -template -inline bool operator>=(const deque& x, const deque& y) +template +inline bool operator>=(const deque& x, const deque& y) { return !(x < y); } -template -inline bool operator<=(const deque& x, const deque& y) +template +inline bool operator<=(const deque& x, const deque& y) { return !(y < x); } -template -inline void swap(deque& x, deque& y) +template +inline void swap(deque& x, deque& y) { x.swap(y); } }} @@ -2018,10 +2018,10 @@ namespace boost { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - enum { value = has_trivial_destructor::value }; + enum { value = has_trivial_destructor::value }; }; */ } diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index 55fac62..b6f9214 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -414,7 +414,8 @@ class flat_tree void insert_equal(ordered_range_t, FwdIt first, FwdIt last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) , typename container_detail::enable_if_c - < container_detail::is_forward_iterator::value + < !container_detail::is_input_iterator::value && + container_detail::is_forward_iterator::value >::type * = 0 #endif ) @@ -491,9 +492,9 @@ class flat_tree const const_iterator beg(this->cbegin()); const_iterator pos(beg); const value_compare &value_comp = this->m_data; + skips[0u] = 0u; //Loop in burst sizes while(len){ - skips[0u] = 0u; const size_type burst = len < BurstSize ? len : BurstSize; size_type unique_burst = 0u; const const_iterator cend(this->cend()); @@ -503,20 +504,23 @@ class flat_tree --len; pos = const_cast(*this).priv_lower_bound(pos, cend, KeyOfValue()(val)); //Check if already present - if(pos != cend && !value_comp(*pos, val)){ - ++skips[unique_burst]; + if(pos != cend && !value_comp(val, *pos)){ + if(unique_burst > 0){ + ++skips[unique_burst-1]; + } continue; } //If not present, calculate position positions[unique_burst] = static_cast(pos - beg); - if(++unique_burst < burst) - skips[unique_burst] = 0u; + skips[unique_burst++] = 0u; + } + if(unique_burst){ + //Insert all in a single step in the precalculated positions + this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first); + //Next search position updated + pos += unique_burst; } - //Insert all in a single step in the precalculated positions - this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first); - //Next search position updated - pos += unique_burst; } } diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index 96db26f..12342a8 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -41,7 +41,7 @@ namespace container { namespace container_detail { template -struct value_compare_impl +struct tree_value_compare : public KeyCompare { typedef Value value_type; @@ -49,7 +49,7 @@ struct value_compare_impl typedef KeyOfValue key_of_value; typedef Key key_type; - value_compare_impl(const key_compare &kcomp) + tree_value_compare(const key_compare &kcomp) : key_compare(kcomp) {} @@ -209,13 +209,13 @@ class rbtree : protected container_detail::node_alloc_holder < A , typename container_detail::intrusive_rbtree_type - + >::type , KeyCompare > { typedef typename container_detail::intrusive_rbtree_type - < A, value_compare_impl + < A, tree_value_compare >::type Icont; typedef container_detail::node_alloc_holder @@ -315,7 +315,7 @@ class rbtree typedef Value value_type; typedef A allocator_type; typedef KeyCompare key_compare; - typedef value_compare_impl< Key, Value + typedef tree_value_compare< Key, Value , KeyCompare, KeyOfValue> value_compare; typedef typename boost::container:: allocator_traits::pointer pointer; diff --git a/include/boost/container/detail/utilities.hpp b/include/boost/container/detail/utilities.hpp index 152b5e1..ece9a2e 100644 --- a/include/boost/container/detail/utilities.hpp +++ b/include/boost/container/detail/utilities.hpp @@ -122,36 +122,6 @@ struct ct_rounded_size { enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo }; }; -/* -template -struct __rw_is_enum -{ - struct _C_no { }; - struct _C_yes { int _C_dummy [2]; }; - - struct _C_indirect { - // prevent classes with user-defined conversions from matching - - // use double to prevent float->int gcc conversion warnings - _C_indirect (double); -}; - -// nested struct gets rid of bogus gcc errors -struct _C_nest { - // supply first argument to prevent HP aCC warnings - static _C_no _C_is (int, ...); - static _C_yes _C_is (int, _C_indirect); - - static _TypeT _C_make_T (); -}; - -enum { - _C_val = sizeof (_C_yes) == sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ())) - && !::boost::is_fundamental<_TypeT>::value -}; - -}; -*/ template struct move_const_ref_type diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index 27f1074..1422d31 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -28,27 +28,23 @@ #include #include #include +#include -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { -#else -namespace boost { -namespace container { -#endif /// @cond // Forward declarations of operators == and <, needed for friend declarations. -template +template class flat_map; -template -inline bool operator==(const flat_map& x, - const flat_map& y); +template +inline bool operator==(const flat_map& x, + const flat_map& y); -template -inline bool operator<(const flat_map& x, - const flat_map& y); +template +inline bool operator<(const flat_map& x, + const flat_map& y); namespace container_detail{ @@ -78,9 +74,9 @@ static D force_copy(S s) //! flat_map the key_type is Key and the value_type is std::pair //! (unlike std::map which value_type is std::pair<const Key, T>). //! -//! Pred is the ordering function for Keys (e.g. std::less). +//! Compare is the ordering function for Keys (e.g. std::less). //! -//! A is the allocator to allocate the value_types +//! Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair >). //! //! flat_map is similar to std::map but it's implemented like an ordered vector. @@ -90,9 +86,9 @@ static D force_copy(S s) //! Erasing an element of a flat_map invalidates iterators and references //! pointing to elements that come after (their keys are bigger) the erased element. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator< std::pair< Key, T> > > +template , class Allocator = std::allocator< std::pair< Key, T> > > #else -template +template #endif class flat_map { @@ -103,72 +99,68 @@ class flat_map typedef container_detail::flat_tree, container_detail::select1st< std::pair >, - Pred, - A> tree_t; + Compare, + Allocator> tree_t; //This is the real tree stored here. It's based on a movable pair typedef container_detail::flat_tree, container_detail::select1st >, - Pred, - typename allocator_traits::template portable_rebind_alloc + Compare, + typename allocator_traits::template portable_rebind_alloc >::type> impl_tree_t; impl_tree_t m_flat_tree; // flat tree representing flat_map typedef typename impl_tree_t::value_type impl_value_type; - typedef typename impl_tree_t::pointer impl_pointer; - typedef typename impl_tree_t::const_pointer impl_const_pointer; - typedef typename impl_tree_t::reference impl_reference; - typedef typename impl_tree_t::const_reference impl_const_reference; - typedef typename impl_tree_t::value_compare impl_value_compare; - typedef typename impl_tree_t::iterator impl_iterator; typedef typename impl_tree_t::const_iterator impl_const_iterator; - typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator; - typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator; typedef typename impl_tree_t::allocator_type impl_allocator_type; - typedef allocator_traits allocator_traits_type; - - - + typedef container_detail::flat_tree_value_compare + < Compare + , container_detail::select1st< std::pair > + , std::pair > value_compare_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::iterator iterator_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::const_iterator const_iterator_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::reverse_iterator reverse_iterator_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::const_reverse_iterator const_reverse_iterator_impl; /// @endcond public: - // typedefs: - typedef Key key_type; - typedef T mapped_type; - typedef typename std::pair value_type; - typedef typename allocator_traits_type::pointer pointer; - typedef typename allocator_traits_type::const_pointer const_pointer; - typedef typename allocator_traits_type::reference reference; - typedef typename allocator_traits_type::const_reference const_reference; - typedef typename impl_tree_t::size_type size_type; - typedef typename impl_tree_t::difference_type difference_type; - - typedef container_detail::flat_tree_value_compare - < Pred - , container_detail::select1st< std::pair > - , std::pair > value_compare; - typedef Pred key_compare; - typedef typename container_detail:: - get_flat_tree_iterators::iterator iterator; - typedef typename container_detail:: - get_flat_tree_iterators::const_iterator const_iterator; - typedef typename container_detail:: - get_flat_tree_iterators - ::reverse_iterator reverse_iterator; - typedef typename container_detail:: - get_flat_tree_iterators - ::const_reverse_iterator const_reverse_iterator; - typedef A allocator_type; - - //!Standard extension - typedef A stored_allocator_type; - - //!Standard extension for C++03 compilers with non-movable std::pair - typedef impl_value_type movable_value_type; + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef Key key_type; + typedef T mapped_type; + typedef std::pair value_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_CONTAINER_IMPDEF(Allocator) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef Compare key_compare; + typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; + typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; public: + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// + //! Effects: Default constructs an empty flat_map. //! //! Complexity: Constant. @@ -179,7 +171,7 @@ class flat_map //! comparison object and allocator. //! //! Complexity: Constant. - explicit flat_map(const Pred& comp, const allocator_type& a = allocator_type()) + explicit flat_map(const Compare& comp, const allocator_type& a = allocator_type()) : m_flat_tree(comp, container_detail::force(a)) {} //! Effects: Constructs an empty flat_map using the specified comparison object and @@ -188,7 +180,7 @@ class flat_map //! Complexity: Linear in N if the range [first ,last ) is already sorted using //! comp and otherwise N logN, where N is last - first. template - flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(), + flat_map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(true, first, last, comp, container_detail::force(a)) {} @@ -205,7 +197,7 @@ class flat_map //! Note: Non-standard extension. template flat_map( ordered_unique_range_t, InputIterator first, InputIterator last - , const Pred& comp = Pred(), const allocator_type& a = allocator_type()) + , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(ordered_range, first, last, comp, a) {} @@ -255,20 +247,6 @@ class flat_map flat_map& operator=(BOOST_RV_REF(flat_map) mx) { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return container_detail::force_copy(m_flat_tree.key_comp()); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return value_compare(container_detail::force_copy(m_flat_tree.key_comp())); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -276,11 +254,31 @@ class flat_map allocator_type get_allocator() const { return container_detail::force_copy(m_flat_tree.get_allocator()); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() + { return container_detail::force(m_flat_tree.get_stored_allocator()); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return container_detail::force(m_flat_tree.get_stored_allocator()); } - stored_allocator_type &get_stored_allocator() - { return container_detail::force(m_flat_tree.get_stored_allocator()); } + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// //! Effects: Returns an iterator to the first element contained in the container. //! @@ -384,6 +382,12 @@ class flat_map const_reverse_iterator crend() const { return container_detail::force_copy(m_flat_tree.crend()); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -408,11 +412,47 @@ class flat_map size_type max_size() const { return m_flat_tree.max_size(); } + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const + { return m_flat_tree.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + //! + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } + + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } + + ////////////////////////////////////////////// + // + // element access + // + ////////////////////////////////////////////// + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: If there is no key equivalent to x in the flat_map, inserts //! value_type(x, T()) into the flat_map. //! - //! Returns: A reference to the mapped_type corresponding to x in *this. + //! Returns: Allocator reference to the mapped_type corresponding to x in *this. //! //! Complexity: Logarithmic. mapped_type &operator[](const key_type& k); @@ -420,17 +460,19 @@ class flat_map //! Effects: If there is no key equivalent to x in the flat_map, inserts //! value_type(move(x), T()) into the flat_map (the key is move-constructed) //! - //! Returns: A reference to the mapped_type corresponding to x in *this. + //! Returns: Allocator reference to the mapped_type corresponding to x in *this. //! //! Complexity: Logarithmic. mapped_type &operator[](key_type &&k) ; #else - BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, priv_subscript) + BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript) #endif - //! Returns: A reference to the element whose key is equivalent to x. + //! Returns: Allocator reference to the element whose key is equivalent to x. + //! //! Throws: An exception object of type out_of_range if no such element is present. + //! //! Complexity: logarithmic. T& at(const key_type& k) { @@ -441,8 +483,10 @@ class flat_map return i->second; } - //! Returns: A reference to the element whose key is equivalent to x. + //! Returns: Allocator reference to the element whose key is equivalent to x. + //! //! Throws: An exception object of type out_of_range if no such element is present. + //! //! Complexity: logarithmic. const T& at(const key_type& k) const { @@ -453,13 +497,69 @@ class flat_map return i->second; } - //! Effects: Swaps the contents of *this and x. + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// + + #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Inserts an object x of type T constructed with + //! std::forward(args)... if and only if there is no element in the container + //! with key equivalent to the key of x. //! - //! Throws: Nothing. + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. //! - //! Complexity: Constant. - void swap(flat_map& x) - { m_flat_tree.swap(x.m_flat_tree); } + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + template + std::pair emplace(Args&&... args) + { return container_detail::force_copy< std::pair >(m_flat_tree.emplace_unique(boost::forward(args)...)); } + + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... in the container if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + template + iterator emplace_hint(const_iterator hint, Args&&... args) + { + return container_detail::force_copy + (m_flat_tree.emplace_hint_unique( container_detail::force_copy(hint) + , boost::forward(args)...)); + } + + #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + + #define BOOST_PP_LOCAL_MACRO(n) \ + BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ + std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ + { return container_detail::force_copy< std::pair > \ + (m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ + \ + BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ + iterator emplace_hint(const_iterator hint \ + BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ + { return container_detail::force_copy(m_flat_tree.emplace_hint_unique \ + (container_detail::force_copy(hint) \ + BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ + //! + #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) + #include BOOST_PP_LOCAL_ITERATE() + + #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING //! Effects: Inserts x if and only if there is no element in the container //! with key equivalent to the key of x. @@ -587,64 +687,6 @@ class flat_map void insert(ordered_unique_range_t, InputIterator first, InputIterator last) { m_flat_tree.insert_unique(ordered_unique_range, first, last); } - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object x of type T constructed with - //! std::forward(args)... if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - std::pair emplace(Args&&... args) - { return container_detail::force_copy< std::pair >(m_flat_tree.emplace_unique(boost::forward(args)...)); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - iterator emplace_hint(const_iterator hint, Args&&... args) - { - return container_detail::force_copy - (m_flat_tree.emplace_hint_unique( container_detail::force_copy(hint) - , boost::forward(args)...)); - } - - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING - - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy< std::pair > \ - (m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy(m_flat_tree.emplace_hint_unique \ - (container_detail::force_copy(hint) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() - - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING - //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately @@ -685,6 +727,14 @@ class flat_map , container_detail::force_copy(last))); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_map& x) + { m_flat_tree.swap(x.m_flat_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -693,14 +743,31 @@ class flat_map void clear() { m_flat_tree.clear(); } - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. //! - //! Throws: If memory allocation throws, or T's copy constructor throws. + //! Complexity: Constant. + key_compare key_comp() const + { return container_detail::force_copy(m_flat_tree.key_comp()); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. //! - //! Complexity: Linear to size(). - void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(container_detail::force_copy(m_flat_tree.key_comp())); } + + ////////////////////////////////////////////// + // + // map operations + // + ////////////////////////////////////////////// //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. @@ -709,7 +776,7 @@ class flat_map iterator find(const key_type& x) { return container_detail::force_copy(m_flat_tree.find(x)); } - //! Returns: A const_iterator pointing to an element with the key + //! Returns: Allocator const_iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic.s @@ -729,7 +796,7 @@ class flat_map iterator lower_bound(const key_type& x) { return container_detail::force_copy(m_flat_tree.lower_bound(x)); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -743,7 +810,7 @@ class flat_map iterator upper_bound(const key_type& x) { return container_detail::force_copy(m_flat_tree.upper_bound(x)); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -762,27 +829,6 @@ class flat_map std::pair equal_range(const key_type& x) const { return container_detail::force_copy >(m_flat_tree.equal_range(x)); } - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type capacity() const - { return m_flat_tree.capacity(); } - - //! Effects: If n is less than or equal to capacity(), this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws or T's copy constructor throws. - //! - //! Note: If capacity() is less than "count", iterators and references to - //! to values might be invalidated. - void reserve(size_type count) - { m_flat_tree.reserve(count); } - /// @cond template friend bool operator== (const flat_map&, @@ -816,39 +862,39 @@ class flat_map /// @endcond }; -template -inline bool operator==(const flat_map& x, - const flat_map& y) +template +inline bool operator==(const flat_map& x, + const flat_map& y) { return x.m_flat_tree == y.m_flat_tree; } -template -inline bool operator<(const flat_map& x, - const flat_map& y) +template +inline bool operator<(const flat_map& x, + const flat_map& y) { return x.m_flat_tree < y.m_flat_tree; } -template -inline bool operator!=(const flat_map& x, - const flat_map& y) +template +inline bool operator!=(const flat_map& x, + const flat_map& y) { return !(x == y); } -template -inline bool operator>(const flat_map& x, - const flat_map& y) +template +inline bool operator>(const flat_map& x, + const flat_map& y) { return y < x; } -template -inline bool operator<=(const flat_map& x, - const flat_map& y) +template +inline bool operator<=(const flat_map& x, + const flat_map& y) { return !(y < x); } -template -inline bool operator>=(const flat_map& x, - const flat_map& y) +template +inline bool operator>=(const flat_map& x, + const flat_map& y) { return !(x < y); } -template -inline void swap(flat_map& x, - flat_map& y) +template +inline void swap(flat_map& x, + flat_map& y) { x.swap(y); } /// @cond @@ -857,25 +903,25 @@ inline void swap(flat_map& x, /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { // Forward declaration of operators < and ==, needed for friend declaration. -template +template class flat_multimap; -template -inline bool operator==(const flat_multimap& x, - const flat_multimap& y); +template +inline bool operator==(const flat_multimap& x, + const flat_multimap& y); -template -inline bool operator<(const flat_multimap& x, - const flat_multimap& y); +template +inline bool operator<(const flat_multimap& x, + const flat_multimap& y); /// @endcond //! A flat_multimap is a kind of associative container that supports equivalent keys @@ -888,14 +934,14 @@ inline bool operator<(const flat_multimap& x, //! flat_multimap the key_type is Key and the value_type is std::pair //! (unlike std::multimap which value_type is std::pair<const Key, T>). //! -//! Pred is the ordering function for Keys (e.g. std::less). +//! Compare is the ordering function for Keys (e.g. std::less). //! -//! A is the allocator to allocate the value_types +//! Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair >). #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator< std::pair< Key, T> > > +template , class Allocator = std::allocator< std::pair< Key, T> > > #else -template +template #endif class flat_multimap { @@ -905,65 +951,65 @@ class flat_multimap typedef container_detail::flat_tree, container_detail::select1st< std::pair >, - Pred, - A> tree_t; + Compare, + Allocator> tree_t; //This is the real tree stored here. It's based on a movable pair typedef container_detail::flat_tree, container_detail::select1st >, - Pred, - typename allocator_traits::template portable_rebind_alloc + Compare, + typename allocator_traits::template portable_rebind_alloc >::type> impl_tree_t; impl_tree_t m_flat_tree; // flat tree representing flat_map typedef typename impl_tree_t::value_type impl_value_type; - typedef typename impl_tree_t::pointer impl_pointer; - typedef typename impl_tree_t::const_pointer impl_const_pointer; - typedef typename impl_tree_t::reference impl_reference; - typedef typename impl_tree_t::const_reference impl_const_reference; - typedef typename impl_tree_t::value_compare impl_value_compare; - typedef typename impl_tree_t::iterator impl_iterator; typedef typename impl_tree_t::const_iterator impl_const_iterator; - typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator; - typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator; typedef typename impl_tree_t::allocator_type impl_allocator_type; - typedef allocator_traits allocator_traits_type; - + typedef container_detail::flat_tree_value_compare + < Compare + , container_detail::select1st< std::pair > + , std::pair > value_compare_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::iterator iterator_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::const_iterator const_iterator_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::reverse_iterator reverse_iterator_impl; + typedef typename container_detail::get_flat_tree_iterators + ::pointer>::const_reverse_iterator const_reverse_iterator_impl; /// @endcond public: - // typedefs: - typedef Key key_type; - typedef T mapped_type; - typedef Pred key_compare; - typedef typename std::pair value_type; - typedef typename allocator_traits_type::pointer pointer; - typedef typename allocator_traits_type::const_pointer const_pointer; - typedef typename allocator_traits_type::reference reference; - typedef typename allocator_traits_type::const_reference const_reference; - typedef typename impl_tree_t::size_type size_type; - typedef typename impl_tree_t::difference_type difference_type; - typedef container_detail::flat_tree_value_compare - < Pred - , container_detail::select1st< std::pair > - , std::pair > value_compare; + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef Key key_type; + typedef T mapped_type; + typedef std::pair value_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_CONTAINER_IMPDEF(Allocator) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef Compare key_compare; + typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; + typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; - typedef typename container_detail:: - get_flat_tree_iterators::iterator iterator; - typedef typename container_detail:: - get_flat_tree_iterators::const_iterator const_iterator; - typedef typename container_detail:: - get_flat_tree_iterators - ::reverse_iterator reverse_iterator; - typedef typename container_detail:: - get_flat_tree_iterators - ::const_reverse_iterator const_reverse_iterator; - typedef A allocator_type; - //Non-standard extension - typedef A stored_allocator_type; - //!Standard extension for C++03 compilers with non-movable std::pair - typedef impl_value_type movable_value_type; + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// //! Effects: Default constructs an empty flat_map. //! @@ -975,7 +1021,7 @@ class flat_multimap //! object and allocator. //! //! Complexity: Constant. - explicit flat_multimap(const Pred& comp, + explicit flat_multimap(const Compare& comp, const allocator_type& a = allocator_type()) : m_flat_tree(comp, container_detail::force(a)) { } @@ -986,7 +1032,7 @@ class flat_multimap //! comp and otherwise N logN, where N is last - first. template flat_multimap(InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(false, first, last, comp, container_detail::force(a)) {} @@ -1002,7 +1048,7 @@ class flat_multimap //! Note: Non-standard extension. template flat_multimap(ordered_range_t, InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(ordered_range, first, last, comp, a) {} @@ -1020,7 +1066,7 @@ class flat_multimap //! Postcondition: x is emptied. flat_multimap(BOOST_RV_REF(flat_multimap) x) : m_flat_tree(boost::move(x.m_flat_tree)) - { } + {} //! Effects: Copy constructs a flat_multimap using the specified allocator. //! @@ -1049,20 +1095,6 @@ class flat_multimap flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx) { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return container_detail::force_copy(m_flat_tree.key_comp()); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return value_compare(container_detail::force_copy(m_flat_tree.key_comp())); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -1070,11 +1102,31 @@ class flat_multimap allocator_type get_allocator() const { return container_detail::force_copy(m_flat_tree.get_allocator()); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() + { return container_detail::force(m_flat_tree.get_stored_allocator()); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return container_detail::force(m_flat_tree.get_stored_allocator()); } - stored_allocator_type &get_stored_allocator() - { return container_detail::force(m_flat_tree.get_stored_allocator()); } + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// //! Effects: Returns an iterator to the first element contained in the container. //! @@ -1178,6 +1230,12 @@ class flat_multimap const_reverse_iterator crend() const { return container_detail::force_copy(m_flat_tree.crend()); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -1202,13 +1260,94 @@ class flat_multimap size_type max_size() const { return m_flat_tree.max_size(); } - //! Effects: Swaps the contents of *this and x. + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). //! //! Throws: Nothing. //! //! Complexity: Constant. - void swap(flat_multimap& x) - { m_flat_tree.swap(x.m_flat_tree); } + size_type capacity() const + { return m_flat_tree.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy constructor throws. + //! + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } + + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } + + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// + + #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + template + iterator emplace(Args&&... args) + { return container_detail::force_copy(m_flat_tree.emplace_equal(boost::forward(args)...)); } + + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant time if the value + //! is to be inserted before p) plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + template + iterator emplace_hint(const_iterator hint, Args&&... args) + { + return container_detail::force_copy(m_flat_tree.emplace_hint_equal + (container_detail::force_copy(hint), boost::forward(args)...)); + } + + #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + + #define BOOST_PP_LOCAL_MACRO(n) \ + BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ + iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ + { return container_detail::force_copy(m_flat_tree.emplace_equal \ + (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ + \ + BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ + iterator emplace_hint(const_iterator hint \ + BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ + { return container_detail::force_copy(m_flat_tree.emplace_hint_equal \ + (container_detail::force_copy(hint) \ + BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ + //! + #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) + #include BOOST_PP_LOCAL_ITERATE() + + #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING //! Effects: Inserts x and returns the iterator pointing to the //! newly inserted element. @@ -1324,59 +1463,6 @@ class flat_multimap void insert(ordered_range_t, InputIterator first, InputIterator last) { m_flat_tree.insert_equal(ordered_range, first, last); } - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - iterator emplace(Args&&... args) - { return container_detail::force_copy(m_flat_tree.emplace_equal(boost::forward(args)...)); } - - //! Effects: Inserts an object of type T constructed with - //! std::forward(args)... in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant time if the value - //! is to be inserted before p) plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - template - iterator emplace_hint(const_iterator hint, Args&&... args) - { - return container_detail::force_copy(m_flat_tree.emplace_hint_equal - (container_detail::force_copy(hint), boost::forward(args)...)); - } - - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING - - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy(m_flat_tree.emplace_equal \ - (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy(m_flat_tree.emplace_hint_equal \ - (container_detail::force_copy(hint) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() - - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING - //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately @@ -1417,6 +1503,14 @@ class flat_multimap , container_detail::force_copy(last))); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_multimap& x) + { m_flat_tree.swap(x.m_flat_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -1425,14 +1519,31 @@ class flat_multimap void clear() { m_flat_tree.clear(); } - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. //! - //! Throws: If memory allocation throws, or T's copy constructor throws. + //! Complexity: Constant. + key_compare key_comp() const + { return container_detail::force_copy(m_flat_tree.key_comp()); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. //! - //! Complexity: Linear to size(). - void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(container_detail::force_copy(m_flat_tree.key_comp())); } + + ////////////////////////////////////////////// + // + // map operations + // + ////////////////////////////////////////////// //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. @@ -1459,9 +1570,9 @@ class flat_multimap //! //! Complexity: Logarithmic iterator lower_bound(const key_type& x) - {return container_detail::force_copy(m_flat_tree.lower_bound(x)); } + { return container_detail::force_copy(m_flat_tree.lower_bound(x)); } - //! Returns: A const iterator pointing to the first element with key + //! Returns: Allocator const iterator pointing to the first element with key //! not less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1475,7 +1586,7 @@ class flat_multimap iterator upper_bound(const key_type& x) {return container_detail::force_copy(m_flat_tree.upper_bound(x)); } - //! Returns: A const iterator pointing to the first element with key + //! Returns: Allocator const iterator pointing to the first element with key //! not less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1491,31 +1602,9 @@ class flat_multimap //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) const + std::pair equal_range(const key_type& x) const { return container_detail::force_copy >(m_flat_tree.equal_range(x)); } - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type capacity() const - { return m_flat_tree.capacity(); } - - //! Effects: If n is less than or equal to capacity(), this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws or T's copy constructor throws. - //! - //! Note: If capacity() is less than "count", iterators and references to - //! to values might be invalidated. - void reserve(size_type count) - { m_flat_tree.reserve(count); } - /// @cond template friend bool operator== (const flat_multimap& x, @@ -1527,38 +1616,38 @@ class flat_multimap /// @endcond }; -template -inline bool operator==(const flat_multimap& x, - const flat_multimap& y) +template +inline bool operator==(const flat_multimap& x, + const flat_multimap& y) { return x.m_flat_tree == y.m_flat_tree; } -template -inline bool operator<(const flat_multimap& x, - const flat_multimap& y) +template +inline bool operator<(const flat_multimap& x, + const flat_multimap& y) { return x.m_flat_tree < y.m_flat_tree; } -template -inline bool operator!=(const flat_multimap& x, - const flat_multimap& y) +template +inline bool operator!=(const flat_multimap& x, + const flat_multimap& y) { return !(x == y); } -template -inline bool operator>(const flat_multimap& x, - const flat_multimap& y) +template +inline bool operator>(const flat_multimap& x, + const flat_multimap& y) { return y < x; } -template -inline bool operator<=(const flat_multimap& x, - const flat_multimap& y) +template +inline bool operator<=(const flat_multimap& x, + const flat_multimap& y) { return !(y < x); } -template -inline bool operator>=(const flat_multimap& x, - const flat_multimap& y) +template +inline bool operator>=(const flat_multimap& x, + const flat_multimap& y) { return !(x < y); } -template -inline void swap(flat_multimap& x, flat_multimap& y) +template +inline void swap(flat_multimap& x, flat_multimap& y) { x.swap(y); } }} @@ -1569,10 +1658,10 @@ namespace boost { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move< boost::container::flat_multimap > +template +struct has_trivial_destructor_after_move< boost::container::flat_multimap > { - static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ } //namespace boost { diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index 513d487..a2fbae9 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -24,33 +24,30 @@ #include #include #include +#include #include +#include -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { -#else -namespace boost { -namespace container { -#endif /// @cond // Forward declarations of operators < and ==, needed for friend declaration. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = std::allocator > #else -template +template #endif class flat_set; -template -inline bool operator==(const flat_set& x, - const flat_set& y); +template +inline bool operator==(const flat_set& x, + const flat_set& y); -template -inline bool operator<(const flat_set& x, - const flat_set& y); +template +inline bool operator<(const flat_set& x, + const flat_set& y); /// @endcond //! flat_set is a Sorted Associative Container that stores objects of type Key. @@ -65,40 +62,48 @@ inline bool operator<(const flat_set& x, //! Erasing an element of a flat_set invalidates iterators and references //! pointing to elements that come after (their keys are bigger) the erased element. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = std::allocator > #else -template +template #endif class flat_set { /// @cond private: BOOST_COPYABLE_AND_MOVABLE(flat_set) - typedef container_detail::flat_tree, Pred, A> tree_t; + typedef container_detail::flat_tree, Compare, Allocator> tree_t; tree_t m_flat_tree; // flat tree representing flat_set - typedef typename container_detail:: - move_const_ref_type::type insert_const_ref_type; /// @endcond public: + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef Compare value_compare; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; - // typedefs: - typedef typename tree_t::key_type key_type; - typedef typename tree_t::value_type value_type; - typedef typename tree_t::pointer pointer; - typedef typename tree_t::const_pointer const_pointer; - typedef typename tree_t::reference reference; - typedef typename tree_t::const_reference const_reference; - typedef typename tree_t::key_compare key_compare; - typedef typename tree_t::value_compare value_compare; - typedef typename tree_t::iterator iterator; - typedef typename tree_t::const_iterator const_iterator; - typedef typename tree_t::reverse_iterator reverse_iterator; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator; - typedef typename tree_t::size_type size_type; - typedef typename tree_t::difference_type difference_type; - typedef typename tree_t::allocator_type allocator_type; - typedef typename tree_t::stored_allocator_type stored_allocator_type; + public: + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// //! Effects: Default constructs an empty flat_set. //! @@ -111,7 +116,7 @@ class flat_set //! comparison object and allocator. //! //! Complexity: Constant. - explicit flat_set(const Pred& comp, + explicit flat_set(const Compare& comp, const allocator_type& a = allocator_type()) : m_flat_tree(comp, a) {} @@ -123,7 +128,7 @@ class flat_set //! comp and otherwise N logN, where N is last - first. template flat_set(InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(true, first, last, comp, a) {} @@ -140,7 +145,7 @@ class flat_set //! Note: Non-standard extension. template flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(ordered_range, first, last, comp, a) {} @@ -188,20 +193,6 @@ class flat_set flat_set& operator=(BOOST_RV_REF(flat_set) mx) { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return m_flat_tree.key_comp(); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return m_flat_tree.key_comp(); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -209,11 +200,31 @@ class flat_set allocator_type get_allocator() const { return m_flat_tree.get_allocator(); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() + { return m_flat_tree.get_stored_allocator(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return m_flat_tree.get_stored_allocator(); } - stored_allocator_type &get_stored_allocator() - { return m_flat_tree.get_stored_allocator(); } + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// //! Effects: Returns an iterator to the first element contained in the container. //! @@ -231,14 +242,6 @@ class flat_set const_iterator begin() const { return m_flat_tree.begin(); } - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const - { return m_flat_tree.cbegin(); } - //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. @@ -255,14 +258,6 @@ class flat_set const_iterator end() const { return m_flat_tree.end(); } - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const - { return m_flat_tree.cend(); } - //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. //! @@ -281,15 +276,6 @@ class flat_set const_reverse_iterator rbegin() const { return m_flat_tree.rbegin(); } - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const - { return m_flat_tree.crbegin(); } - //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. //! @@ -308,6 +294,31 @@ class flat_set const_reverse_iterator rend() const { return m_flat_tree.rend(); } + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cbegin() const + { return m_flat_tree.cbegin(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cend() const + { return m_flat_tree.cend(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator crbegin() const + { return m_flat_tree.crbegin(); } + //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! @@ -317,6 +328,13 @@ class flat_set const_reverse_iterator crend() const { return m_flat_tree.crend(); } + + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -341,117 +359,45 @@ class flat_set size_type max_size() const { return m_flat_tree.max_size(); } - //! Effects: Swaps the contents of *this and x. + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). //! //! Throws: Nothing. //! //! Complexity: Constant. - void swap(flat_set& x) - { m_flat_tree.swap(x.m_flat_tree); } + size_type capacity() const + { return m_flat_tree.capacity(); } - //! Effects: Inserts x if and only if there is no element in the container - //! with key equivalent to the key of x. + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. + //! Throws: If memory allocation allocation throws or Key's copy constructor throws. //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - std::pair insert(insert_const_ref_type x) - { return priv_insert(x); } + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - std::pair insert(T &x) - { return this->insert(const_cast(x)); } + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or Key's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } - template - std::pair insert(const U &u, typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(u); } - #endif - - //! Effects: Inserts a new value_type move constructed from the pair if and - //! only if there is no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - std::pair insert(BOOST_RV_REF(value_type) x) - { return m_flat_tree.insert_unique(boost::move(x)); } - - //! Effects: Inserts a copy of x in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator p, insert_const_ref_type x) - { return priv_insert(p, x); } - - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - iterator insert(const_iterator position, T &x) - { return this->insert(position, const_cast(x)); } - - template - iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(position, u); } - #endif - - //! Effects: Inserts an element move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) - { return m_flat_tree.insert_unique(position, boost::move(x)); } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - //! search time plus N*size() insertion time. - //! - //! Note: If an element is inserted it might invalidate elements. - template - void insert(InputIterator first, InputIterator last) - { m_flat_tree.insert_unique(first, last); } - - //! Requires: first, last are not iterators into *this and - //! must be ordered according to the predicate and must be - //! unique values. - //! - //! Effects: inserts each element from the range [first,last) .This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - //! search time plus N*size() insertion time. - //! - //! Note: Non-standard extension. If an element is inserted it might invalidate elements. - template - void insert(ordered_unique_range_t, InputIterator first, InputIterator last) - { m_flat_tree.insert_unique(ordered_unique_range, first, last); } + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts an object x of type T constructed with + //! Effects: Inserts an object x of type Key constructed with //! std::forward(args)... if and only if there is no element in the container //! with key equivalent to the key of x. //! @@ -467,7 +413,7 @@ class flat_set std::pair emplace(Args&&... args) { return m_flat_tree.emplace_unique(boost::forward(args)...); } - //! Effects: Inserts an object of type T constructed with + //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... in the container if and only if there is //! no element in the container with key equivalent to the key of x. //! p is a hint pointing to where the insert should start to search. @@ -501,6 +447,95 @@ class flat_set #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts x if and only if there is no element in the container + //! with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + std::pair insert(const value_type &x); + + //! Effects: Inserts a new value_type move constructed from the pair if and + //! only if there is no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + std::pair insert(value_type &&x); + #else + private: + typedef std::pair insert_return_pair; + public: + BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert) + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts a copy of x in the container if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + iterator insert(const_iterator p, const value_type &x); + + //! Effects: Inserts an element move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + iterator insert(const_iterator position, value_type &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator) + #endif + + //! Requires: first, last are not iterators into *this. + //! + //! Effects: inserts each element from the range [first,last) if and only + //! if there is no element with key equivalent to the key of that element. + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + //! search time plus N*size() insertion time. + //! + //! Note: If an element is inserted it might invalidate elements. + template + void insert(InputIterator first, InputIterator last) + { m_flat_tree.insert_unique(first, last); } + + //! Requires: first, last are not iterators into *this and + //! must be ordered according to the predicate and must be + //! unique values. + //! + //! Effects: inserts each element from the range [first,last) .This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + //! search time plus N*size() insertion time. + //! + //! Note: Non-standard extension. If an element is inserted it might invalidate elements. + template + void insert(ordered_unique_range_t, InputIterator first, InputIterator last) + { m_flat_tree.insert_unique(ordered_unique_range, first, last); } + //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately @@ -534,6 +569,14 @@ class flat_set iterator erase(const_iterator first, const_iterator last) { return m_flat_tree.erase(first, last); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_set& x) + { m_flat_tree.swap(x.m_flat_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -542,14 +585,31 @@ class flat_set void clear() { m_flat_tree.clear(); } - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. //! - //! Throws: If memory allocation throws, or T's copy constructor throws. + //! Complexity: Constant. + key_compare key_comp() const + { return m_flat_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. //! - //! Complexity: Linear to size(). - void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } + //! Complexity: Constant. + value_compare value_comp() const + { return m_flat_tree.key_comp(); } + + ////////////////////////////////////////////// + // + // set operations + // + ////////////////////////////////////////////// //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. @@ -558,7 +618,7 @@ class flat_set iterator find(const key_type& x) { return m_flat_tree.find(x); } - //! Returns: A const_iterator pointing to an element with the key + //! Returns: Allocator const_iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic.s @@ -578,7 +638,7 @@ class flat_set iterator lower_bound(const key_type& x) { return m_flat_tree.lower_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -592,7 +652,7 @@ class flat_set iterator upper_bound(const key_type& x) { return m_flat_tree.upper_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -602,38 +662,15 @@ class flat_set //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) const + std::pair equal_range(const key_type& x) const { return m_flat_tree.equal_range(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) + std::pair equal_range(const key_type& x) { return m_flat_tree.equal_range(x); } - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type capacity() const - { return m_flat_tree.capacity(); } - - //! Effects: If n is less than or equal to capacity(), this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws or T's copy constructor throws. - //! - //! Note: If capacity() is less than "count", iterators and references to - //! to values might be invalidated. - void reserve(size_type count) - { m_flat_tree.reserve(count); } - /// @cond template friend bool operator== (const flat_set&, const flat_set&); @@ -642,46 +679,48 @@ class flat_set friend bool operator< (const flat_set&, const flat_set&); private: - std::pair priv_insert(const T &x) - { return m_flat_tree.insert_unique(x); } + template + std::pair priv_insert(BOOST_FWD_REF(KeyType) x) + { return m_flat_tree.insert_unique(::boost::forward(x)); } - iterator priv_insert(const_iterator p, const T &x) - { return m_flat_tree.insert_unique(p, x); } + template + iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) + { return m_flat_tree.insert_unique(p, ::boost::forward(x)); } /// @endcond }; -template -inline bool operator==(const flat_set& x, - const flat_set& y) +template +inline bool operator==(const flat_set& x, + const flat_set& y) { return x.m_flat_tree == y.m_flat_tree; } -template -inline bool operator<(const flat_set& x, - const flat_set& y) +template +inline bool operator<(const flat_set& x, + const flat_set& y) { return x.m_flat_tree < y.m_flat_tree; } -template -inline bool operator!=(const flat_set& x, - const flat_set& y) +template +inline bool operator!=(const flat_set& x, + const flat_set& y) { return !(x == y); } -template -inline bool operator>(const flat_set& x, - const flat_set& y) +template +inline bool operator>(const flat_set& x, + const flat_set& y) { return y < x; } -template -inline bool operator<=(const flat_set& x, - const flat_set& y) +template +inline bool operator<=(const flat_set& x, + const flat_set& y) { return !(y < x); } -template -inline bool operator>=(const flat_set& x, - const flat_set& y) +template +inline bool operator>=(const flat_set& x, + const flat_set& y) { return !(x < y); } -template -inline void swap(flat_set& x, flat_set& y) +template +inline void swap(flat_set& x, flat_set& y) { x.swap(y); } /// @cond @@ -690,10 +729,10 @@ inline void swap(flat_set& x, flat_set& y) /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value &&has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value &&has_trivial_destructor::value; }; */ namespace container { @@ -701,19 +740,19 @@ namespace container { // Forward declaration of operators < and ==, needed for friend declaration. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = std::allocator > #else -template +template #endif class flat_multiset; -template -inline bool operator==(const flat_multiset& x, - const flat_multiset& y); +template +inline bool operator==(const flat_multiset& x, + const flat_multiset& y); -template -inline bool operator<(const flat_multiset& x, - const flat_multiset& y); +template +inline bool operator<(const flat_multiset& x, + const flat_multiset& y); /// @endcond //! flat_multiset is a Sorted Associative Container that stores objects of type Key. @@ -728,39 +767,41 @@ inline bool operator<(const flat_multiset& x, //! Erasing an element of a flat_multiset invalidates iterators and references //! pointing to elements that come after (their keys are equal or bigger) the erased element. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = std::allocator > #else -template +template #endif class flat_multiset { /// @cond private: BOOST_COPYABLE_AND_MOVABLE(flat_multiset) - typedef container_detail::flat_tree, Pred, A> tree_t; + typedef container_detail::flat_tree, Compare, Allocator> tree_t; tree_t m_flat_tree; // flat tree representing flat_multiset - typedef typename container_detail:: - move_const_ref_type::type insert_const_ref_type; /// @endcond public: - // typedefs: - typedef typename tree_t::key_type key_type; - typedef typename tree_t::value_type value_type; - typedef typename tree_t::pointer pointer; - typedef typename tree_t::const_pointer const_pointer; - typedef typename tree_t::reference reference; - typedef typename tree_t::const_reference const_reference; - typedef typename tree_t::key_compare key_compare; - typedef typename tree_t::value_compare value_compare; - typedef typename tree_t::iterator iterator; - typedef typename tree_t::const_iterator const_iterator; - typedef typename tree_t::reverse_iterator reverse_iterator; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator; - typedef typename tree_t::size_type size_type; - typedef typename tree_t::difference_type difference_type; - typedef typename tree_t::allocator_type allocator_type; - typedef typename tree_t::stored_allocator_type stored_allocator_type; + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef Compare value_compare; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; //! Effects: Default constructs an empty flat_multiset. //! @@ -769,13 +810,13 @@ class flat_multiset : m_flat_tree() {} - explicit flat_multiset(const Pred& comp, + explicit flat_multiset(const Compare& comp, const allocator_type& a = allocator_type()) : m_flat_tree(comp, a) {} template flat_multiset(InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(false, first, last, comp, a) {} @@ -791,7 +832,7 @@ class flat_multiset //! Note: Non-standard extension. template flat_multiset(ordered_range_t, InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_flat_tree(ordered_range, first, last, comp, a) {} @@ -839,20 +880,6 @@ class flat_multiset flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx) { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return m_flat_tree.key_comp(); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return m_flat_tree.key_comp(); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -860,10 +887,24 @@ class flat_multiset allocator_type get_allocator() const { return m_flat_tree.get_allocator(); } - const stored_allocator_type &get_stored_allocator() const + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() { return m_flat_tree.get_stored_allocator(); } - stored_allocator_type &get_stored_allocator() + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + const stored_allocator_type &get_stored_allocator() const { return m_flat_tree.get_stored_allocator(); } //! Effects: Returns an iterator to the first element contained in the container. @@ -968,6 +1009,12 @@ class flat_multiset const_reverse_iterator crend() const { return m_flat_tree.crend(); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -992,108 +1039,45 @@ class flat_multiset size_type max_size() const { return m_flat_tree.max_size(); } - //! Effects: Swaps the contents of *this and x. + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). //! //! Throws: Nothing. //! //! Complexity: Constant. - void swap(flat_multiset& x) - { m_flat_tree.swap(x.m_flat_tree); } + size_type capacity() const + { return m_flat_tree.capacity(); } - //! Effects: Inserts x and returns the iterator pointing to the - //! newly inserted element. + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. + //! Throws: If memory allocation allocation throws or Key's copy constructor throws. //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(insert_const_ref_type x) - { return priv_insert(x); } + //! Note: If capacity() is less than "count", iterators and references to + //! to values might be invalidated. + void reserve(size_type count) + { m_flat_tree.reserve(count); } - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - iterator insert(T &x) - { return this->insert(const_cast(x)); } + //! Effects: Tries to deallocate the excess of memory created + // with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or Key's copy constructor throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { m_flat_tree.shrink_to_fit(); } - template - iterator insert(const U &u, typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(u); } - #endif - - //! Effects: Inserts a new value_type move constructed from x - //! and returns the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic search time plus linear insertion - //! to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(BOOST_RV_REF(value_type) x) - { return m_flat_tree.insert_equal(boost::move(x)); } - - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator p, insert_const_ref_type x) - { return priv_insert(p, x); } - - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - iterator insert(const_iterator position, T &x) - { return this->insert(position, const_cast(x)); } - - template - iterator insert( const_iterator position, const U &u - , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(position, u); } - #endif - - //! Effects: Inserts a new value move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic search time (constant if x is inserted - //! right before p) plus insertion linear to the elements with bigger keys than x. - //! - //! Note: If an element is inserted it might invalidate elements. - iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) - { return m_flat_tree.insert_equal(position, boost::move(x)); } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) . - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - //! search time plus N*size() insertion time. - //! - //! Note: If an element is inserted it might invalidate elements. - template - void insert(InputIterator first, InputIterator last) - { m_flat_tree.insert_equal(first, last); } - - //! Requires: first, last are not iterators into *this and - //! must be ordered according to the predicate. - //! - //! Effects: inserts each element from the range [first,last) .This function - //! is more efficient than the normal range creation for ordered ranges. - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - //! search time plus N*size() insertion time. - //! - //! Note: Non-standard extension. If an element is inserted it might invalidate elements. - template - void insert(ordered_range_t, InputIterator first, InputIterator last) - { m_flat_tree.insert_equal(ordered_range, first, last); } + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts an object of type T constructed with + //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... and returns the iterator pointing to the //! newly inserted element. //! @@ -1105,7 +1089,7 @@ class flat_multiset iterator emplace(Args&&... args) { return m_flat_tree.emplace_equal(boost::forward(args)...); } - //! Effects: Inserts an object of type T constructed with + //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... in the container. //! p is a hint pointing to where the insert should start to search. //! @@ -1138,6 +1122,82 @@ class flat_multiset #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts x and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + iterator insert(const value_type &x); + + //! Effects: Inserts a new value_type move constructed from x + //! and returns the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic search time plus linear insertion + //! to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + iterator insert(value_type &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert) + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + iterator insert(const_iterator p, const value_type &x); + + //! Effects: Inserts a new value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic search time (constant if x is inserted + //! right before p) plus insertion linear to the elements with bigger keys than x. + //! + //! Note: If an element is inserted it might invalidate elements. + iterator insert(const_iterator position, value_type &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator) + #endif + + //! Requires: first, last are not iterators into *this. + //! + //! Effects: inserts each element from the range [first,last) . + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + //! search time plus N*size() insertion time. + //! + //! Note: If an element is inserted it might invalidate elements. + template + void insert(InputIterator first, InputIterator last) + { m_flat_tree.insert_equal(first, last); } + + //! Requires: first, last are not iterators into *this and + //! must be ordered according to the predicate. + //! + //! Effects: inserts each element from the range [first,last) .This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + //! search time plus N*size() insertion time. + //! + //! Note: Non-standard extension. If an element is inserted it might invalidate elements. + template + void insert(ordered_range_t, InputIterator first, InputIterator last) + { m_flat_tree.insert_equal(ordered_range, first, last); } + //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately @@ -1171,6 +1231,14 @@ class flat_multiset iterator erase(const_iterator first, const_iterator last) { return m_flat_tree.erase(first, last); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(flat_multiset& x) + { m_flat_tree.swap(x.m_flat_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -1179,14 +1247,31 @@ class flat_multiset void clear() { m_flat_tree.clear(); } - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. //! - //! Throws: If memory allocation throws, or T's copy constructor throws. + //! Complexity: Constant. + key_compare key_comp() const + { return m_flat_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. //! - //! Complexity: Linear to size(). - void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } + //! Complexity: Constant. + value_compare value_comp() const + { return m_flat_tree.key_comp(); } + + ////////////////////////////////////////////// + // + // set operations + // + ////////////////////////////////////////////// //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. @@ -1195,7 +1280,7 @@ class flat_multiset iterator find(const key_type& x) { return m_flat_tree.find(x); } - //! Returns: A const_iterator pointing to an element with the key + //! Returns: Allocator const_iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic.s @@ -1215,7 +1300,7 @@ class flat_multiset iterator lower_bound(const key_type& x) { return m_flat_tree.lower_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1229,7 +1314,7 @@ class flat_multiset iterator upper_bound(const key_type& x) { return m_flat_tree.upper_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1239,38 +1324,15 @@ class flat_multiset //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) const + std::pair equal_range(const key_type& x) const { return m_flat_tree.equal_range(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) + std::pair equal_range(const key_type& x) { return m_flat_tree.equal_range(x); } - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type capacity() const - { return m_flat_tree.capacity(); } - - //! Effects: If n is less than or equal to capacity(), this call has no - //! effect. Otherwise, it is a request for allocation of additional memory. - //! If the request is successful, then capacity() is greater than or equal to - //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. - //! - //! Throws: If memory allocation allocation throws or T's copy constructor throws. - //! - //! Note: If capacity() is less than "count", iterators and references to - //! to values might be invalidated. - void reserve(size_type count) - { m_flat_tree.reserve(count); } - /// @cond template friend bool operator== (const flat_multiset&, @@ -1279,46 +1341,48 @@ class flat_multiset friend bool operator< (const flat_multiset&, const flat_multiset&); private: - iterator priv_insert(const T &x) - { return m_flat_tree.insert_equal(x); } + template + iterator priv_insert(BOOST_FWD_REF(KeyType) x) + { return m_flat_tree.insert_equal(::boost::forward(x)); } - iterator priv_insert(const_iterator p, const T &x) - { return m_flat_tree.insert_equal(p, x); } + template + iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) + { return m_flat_tree.insert_equal(p, ::boost::forward(x)); } /// @endcond }; -template -inline bool operator==(const flat_multiset& x, - const flat_multiset& y) +template +inline bool operator==(const flat_multiset& x, + const flat_multiset& y) { return x.m_flat_tree == y.m_flat_tree; } -template -inline bool operator<(const flat_multiset& x, - const flat_multiset& y) +template +inline bool operator<(const flat_multiset& x, + const flat_multiset& y) { return x.m_flat_tree < y.m_flat_tree; } -template -inline bool operator!=(const flat_multiset& x, - const flat_multiset& y) +template +inline bool operator!=(const flat_multiset& x, + const flat_multiset& y) { return !(x == y); } -template -inline bool operator>(const flat_multiset& x, - const flat_multiset& y) +template +inline bool operator>(const flat_multiset& x, + const flat_multiset& y) { return y < x; } -template -inline bool operator<=(const flat_multiset& x, - const flat_multiset& y) +template +inline bool operator<=(const flat_multiset& x, + const flat_multiset& y) { return !(y < x); } -template -inline bool operator>=(const flat_multiset& x, - const flat_multiset& y) +template +inline bool operator>=(const flat_multiset& x, + const flat_multiset& y) { return !(x < y); } -template -inline void swap(flat_multiset& x, flat_multiset& y) +template +inline void swap(flat_multiset& x, flat_multiset& y) { x.swap(y); } /// @cond @@ -1327,10 +1391,10 @@ inline void swap(flat_multiset& x, flat_multiset& y) /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp index 8f196d1..38f7c54 100644 --- a/include/boost/container/list.hpp +++ b/include/boost/container/list.hpp @@ -7,8 +7,8 @@ // See http://www.boost.org/libs/container for documentation. // -#ifndef BOOST_CONTAINER_LIST_HPP_ -#define BOOST_CONTAINER_LIST_HPP_ +#ifndef BOOST_CONTAINER_LIST_HPP +#define BOOST_CONTAINER_LIST_HPP #if (defined _MSC_VER) && (_MSC_VER >= 1200) # pragma once @@ -43,13 +43,8 @@ #include #include -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { -#else -namespace boost { -namespace container { -#endif /// @cond namespace container_detail { @@ -73,10 +68,10 @@ struct list_node T m_data; }; -template +template struct intrusive_list_type { - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef typename boost::intrusive::pointer_traits ::template @@ -213,27 +208,27 @@ class list_iterator //! not be invalidated or made to point to different elements unless that invalidation //! or mutation is explicit. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif class list : protected container_detail::node_alloc_holder - ::type> + ::type> { /// @cond typedef typename - container_detail::intrusive_list_type::type Icont; - typedef container_detail::node_alloc_holder AllocHolder; - typedef typename AllocHolder::NodePtr NodePtr; - typedef typename AllocHolder::NodeAlloc NodeAlloc; - typedef typename AllocHolder::ValAlloc ValAlloc; - typedef typename AllocHolder::Node Node; - typedef container_detail::allocator_destroyer Destroyer; - typedef typename AllocHolder::allocator_v1 allocator_v1; - typedef typename AllocHolder::allocator_v2 allocator_v2; - typedef typename AllocHolder::alloc_version alloc_version; - typedef boost::container::allocator_traits allocator_traits_type; + container_detail::intrusive_list_type::type Icont; + typedef container_detail::node_alloc_holder AllocHolder; + typedef typename AllocHolder::NodePtr NodePtr; + typedef typename AllocHolder::NodeAlloc NodeAlloc; + typedef typename AllocHolder::ValAlloc ValAlloc; + typedef typename AllocHolder::Node Node; + typedef container_detail::allocator_destroyer Destroyer; + typedef typename AllocHolder::allocator_v1 allocator_v1; + typedef typename AllocHolder::allocator_v2 allocator_v2; + typedef typename AllocHolder::alloc_version alloc_version; + typedef boost::container::allocator_traits allocator_traits_type; class equal_to_value { @@ -277,19 +272,19 @@ class list // ////////////////////////////////////////////// - typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; + typedef T value_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; + typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; ////////////////////////////////////////////// // @@ -323,7 +318,7 @@ class list //! //! Complexity: Linear to n. explicit list(size_type n) - : AllocHolder(A()) + : AllocHolder(Allocator()) { this->resize(n); } //! Effects: Constructs a list that will use a copy of allocator a @@ -333,7 +328,7 @@ class list //! throws or T's default or copy constructor throws. //! //! Complexity: Linear to n. - list(size_type n, const T& value, const A& a = A()) + list(size_type n, const T& value, const Allocator& a = Allocator()) : AllocHolder(a) { this->insert(this->cbegin(), n, value); } @@ -393,7 +388,7 @@ class list //! //! Complexity: Linear to the range [first, last). template - list(InpIt first, InpIt last, const A &a = A()) + list(InpIt first, InpIt last, const Allocator &a = Allocator()) : AllocHolder(a) { this->insert(this->cbegin(), first, last); } @@ -506,20 +501,24 @@ class list allocator_type get_allocator() const { return allocator_type(this->node_alloc()); } - //! Effects: Returns a copy of the internal allocator. + //! Effects: Returns a reference to the internal allocator. //! - //! Throws: If allocator's copy constructor throws. + //! Throws: Nothing //! //! Complexity: Constant. - const stored_allocator_type &get_stored_allocator() const + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() { return this->node_alloc(); } - //! Effects: Returns a copy of the internal allocator. + //! Effects: Returns a reference to the internal allocator. //! - //! Throws: If allocator's copy constructor throws. + //! Throws: Nothing //! //! Complexity: Constant. - stored_allocator_type &get_stored_allocator() + //! + //! Note: Non-standard extension. + const stored_allocator_type &get_stored_allocator() const { return this->node_alloc(); } ////////////////////////////////////////////// @@ -1426,13 +1425,13 @@ class list }; -template -inline bool operator==(const list& x, const list& y) +template +inline bool operator==(const list& x, const list& y) { if(x.size() != y.size()){ return false; } - typedef typename list::const_iterator const_iterator; + typedef typename list::const_iterator const_iterator; const_iterator end1 = x.end(); const_iterator i1 = x.begin(); @@ -1444,39 +1443,39 @@ inline bool operator==(const list& x, const list& y) return i1 == end1; } -template -inline bool operator<(const list& x, - const list& y) +template +inline bool operator<(const list& x, + const list& y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } -template -inline bool operator!=(const list& x, const list& y) +template +inline bool operator!=(const list& x, const list& y) { return !(x == y); } -template -inline bool operator>(const list& x, const list& y) +template +inline bool operator>(const list& x, const list& y) { return y < x; } -template -inline bool operator<=(const list& x, const list& y) +template +inline bool operator<=(const list& x, const list& y) { return !(y < x); } -template -inline bool operator>=(const list& x, const list& y) +template +inline bool operator>=(const list& x, const list& y) { return !(x < y); } -template -inline void swap(list& x, list& y) +template +inline void swap(list& x, list& y) { x.swap(y); } @@ -1487,10 +1486,10 @@ inline void swap(list& x, list& y) /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value; }; */ namespace container { @@ -1501,4 +1500,4 @@ namespace container { #include -#endif // BOOST_CONTAINER_LIST_HPP_ +#endif // BOOST_CONTAINER_LIST_HPP diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index d31122c..cde829e 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -35,24 +35,18 @@ #include #include - -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { -#else -namespace boost { -namespace container { -#endif /// @cond // Forward declarations of operators == and <, needed for friend declarations. -template -inline bool operator==(const map& x, - const map& y); +template +inline bool operator==(const map& x, + const map& y); -template -inline bool operator<(const map& x, - const map& y); +template +inline bool operator<(const map& x, + const map& y); /// @endcond //! A map is a kind of associative container that supports unique keys (contains at @@ -63,67 +57,63 @@ inline bool operator<(const map& x, //! container and of an associative container. For a //! map the key_type is Key and the value_type is std::pair. //! -//! Pred is the ordering function for Keys (e.g. std::less). +//! Compare is the ordering function for Keys (e.g. std::less). //! -//! A is the allocator to allocate the value_types +//! Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair > ). #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator< std::pair< const Key, T> > > +template , class Allocator = std::allocator< std::pair< const Key, T> > > #else -template +template #endif class map { /// @cond private: BOOST_COPYABLE_AND_MOVABLE(map) - typedef container_detail::rbtree, - container_detail::select1st< std::pair >, - Pred, - A> tree_t; - tree_t m_tree; // red-black tree representing map + typedef std::pair value_type_impl; + typedef container_detail::rbtree + , Compare, Allocator> tree_t; + typedef container_detail::pair movable_value_type_impl; + typedef container_detail::tree_value_compare + < Key, value_type_impl, Compare, container_detail::select1st + > value_compare_impl; + tree_t m_tree; // red-black tree representing map /// @endcond public: + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// - // typedefs: - typedef typename tree_t::key_type key_type; - typedef typename tree_t::value_type value_type; - typedef typename tree_t::pointer pointer; - typedef typename tree_t::const_pointer const_pointer; - typedef typename tree_t::reference reference; - typedef typename tree_t::const_reference const_reference; - typedef T mapped_type; - typedef Pred key_compare; - typedef typename tree_t::iterator iterator; - typedef typename tree_t::const_iterator const_iterator; - typedef typename tree_t::reverse_iterator reverse_iterator; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator; - typedef typename tree_t::size_type size_type; - typedef typename tree_t::difference_type difference_type; - typedef typename tree_t::allocator_type allocator_type; - typedef typename tree_t::stored_allocator_type stored_allocator_type; - typedef std::pair nonconst_value_type; - typedef container_detail::pair - nonconst_impl_value_type; + typedef Key key_type; + typedef T mapped_type; + typedef std::pair value_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef Compare key_compare; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; + typedef std::pair nonconst_value_type; + typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; - /// @cond - class value_compare_impl - : public Pred, - public std::binary_function - { - friend class map; - protected : - value_compare_impl(const Pred &c) : Pred(c) {} - public: - bool operator()(const value_type& x, const value_type& y) const { - return Pred::operator()(x.first, y.first); - } - }; - /// @endcond - typedef value_compare_impl value_compare; + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// //! Effects: Default constructs an empty map. //! @@ -132,19 +122,19 @@ class map : m_tree() { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty map using the specified comparison object //! and allocator. //! //! Complexity: Constant. - explicit map(const Pred& comp, + explicit map(const Compare& comp, const allocator_type& a = allocator_type()) : m_tree(comp, a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty map using the specified comparison object and @@ -153,12 +143,12 @@ class map //! Complexity: Linear in N if the range [first ,last ) is already sorted using //! comp and otherwise N logN, where N is last - first. template - map(InputIterator first, InputIterator last, const Pred& comp = Pred(), + map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_tree(true, first, last, comp, a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty map using the specified comparison object and @@ -171,11 +161,11 @@ class map //! Complexity: Linear in N. template map( ordered_unique_range_t, InputIterator first, InputIterator last - , const Pred& comp = Pred(), const allocator_type& a = allocator_type()) + , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_tree(ordered_range, first, last, comp, a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Copy constructs a map. @@ -185,7 +175,7 @@ class map : m_tree(x.m_tree) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a map. Constructs *this using x's resources. @@ -197,7 +187,7 @@ class map : m_tree(boost::move(x.m_tree)) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Copy constructs a map using the specified allocator. @@ -207,7 +197,7 @@ class map : m_tree(x.m_tree, a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a map using the specified allocator. @@ -220,7 +210,7 @@ class map : m_tree(boost::move(x.m_tree), a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Makes *this a copy of x. @@ -235,20 +225,6 @@ class map map& operator=(BOOST_RV_REF(map) x) { m_tree = boost::move(x.m_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return m_tree.key_comp(); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return value_compare(m_tree.key_comp()); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -256,11 +232,31 @@ class map allocator_type get_allocator() const { return m_tree.get_allocator(); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() + { return m_tree.get_stored_allocator(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return m_tree.get_stored_allocator(); } - stored_allocator_type &get_stored_allocator() - { return m_tree.get_stored_allocator(); } + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// //! Effects: Returns an iterator to the first element contained in the container. //! @@ -278,14 +274,6 @@ class map const_iterator begin() const { return this->cbegin(); } - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const - { return m_tree.begin(); } - //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. @@ -302,14 +290,6 @@ class map const_iterator end() const { return this->cend(); } - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const - { return m_tree.end(); } - //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. //! @@ -328,15 +308,6 @@ class map const_reverse_iterator rbegin() const { return this->crbegin(); } - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const - { return m_tree.rbegin(); } - //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. //! @@ -355,6 +326,31 @@ class map const_reverse_iterator rend() const { return this->crend(); } + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cbegin() const + { return m_tree.begin(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cend() const + { return m_tree.end(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator crbegin() const + { return m_tree.rbegin(); } + //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! @@ -364,6 +360,12 @@ class map const_reverse_iterator crend() const { return m_tree.rend(); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -388,11 +390,17 @@ class map size_type max_size() const { return m_tree.max_size(); } + ////////////////////////////////////////////// + // + // element access + // + ////////////////////////////////////////////// + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: If there is no key equivalent to x in the map, inserts //! value_type(x, T()) into the map. //! - //! Returns: A reference to the mapped_type corresponding to x in *this. + //! Returns: Allocator reference to the mapped_type corresponding to x in *this. //! //! Complexity: Logarithmic. mapped_type& operator[](const key_type &k); @@ -400,15 +408,15 @@ class map //! Effects: If there is no key equivalent to x in the map, inserts //! value_type(boost::move(x), T()) into the map (the key is move-constructed) //! - //! Returns: A reference to the mapped_type corresponding to x in *this. + //! Returns: Allocator reference to the mapped_type corresponding to x in *this. //! //! Complexity: Logarithmic. mapped_type& operator[](key_type &&k); #else - BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, priv_subscript) + BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript) #endif - //! Returns: A reference to the element whose key is equivalent to x. + //! Returns: Allocator reference to the element whose key is equivalent to x. //! Throws: An exception object of type out_of_range if no such element is present. //! Complexity: logarithmic. T& at(const key_type& k) @@ -420,7 +428,7 @@ class map return i->second; } - //! Returns: A reference to the element whose key is equivalent to x. + //! Returns: Allocator reference to the element whose key is equivalent to x. //! Throws: An exception object of type out_of_range if no such element is present. //! Complexity: logarithmic. const T& at(const key_type& k) const @@ -432,13 +440,11 @@ class map return i->second; } - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(map& x) - { m_tree.swap(x.m_tree); } + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// //! Effects: Inserts x if and only if there is no element in the container //! with key equivalent to the key of x. @@ -481,7 +487,7 @@ class map //! points to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. - std::pair insert(BOOST_RV_REF(nonconst_impl_value_type) x) + std::pair insert(BOOST_RV_REF(movable_value_type) x) { return m_tree.insert_unique(boost::move(x)); } //! Effects: Move constructs a new value from x if and only if there is @@ -504,7 +510,7 @@ class map //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. - iterator insert(iterator position, const value_type& x) + iterator insert(const_iterator position, const value_type& x) { return m_tree.insert_unique(position, x); } //! Effects: Move constructs a new value from x if and only if there is @@ -516,7 +522,7 @@ class map //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. - iterator insert(iterator position, BOOST_RV_REF(nonconst_value_type) x) + iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) { return m_tree.insert_unique(position, boost::move(x)); } //! Effects: Move constructs a new value from x if and only if there is @@ -528,7 +534,7 @@ class map //! //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. - iterator insert(iterator position, BOOST_RV_REF(nonconst_impl_value_type) x) + iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) { return m_tree.insert_unique(position, boost::move(x)); } //! Effects: Inserts a copy of x in the container. @@ -537,7 +543,7 @@ class map //! Returns: An iterator pointing to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. - iterator insert(iterator position, const nonconst_value_type& x) + iterator insert(const_iterator position, const nonconst_value_type& x) { return m_tree.insert_unique(position, x); } //! Effects: Inserts an element move constructed from x in the container. @@ -546,7 +552,7 @@ class map //! Returns: An iterator pointing to the element with key equivalent to the key of x. //! //! Complexity: Logarithmic. - iterator insert(iterator position, BOOST_RV_REF(value_type) x) + iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) { return m_tree.insert_unique(position, boost::move(x)); } //! Requires: first, last are not iterators into *this. @@ -634,6 +640,14 @@ class map iterator erase(const_iterator first, const_iterator last) { return m_tree.erase(first, last); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(map& x) + { m_tree.swap(x.m_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -642,6 +656,32 @@ class map void clear() { m_tree.clear(); } + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(m_tree.key_comp()); } + + ////////////////////////////////////////////// + // + // map operations + // + ////////////////////////////////////////////// + //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! @@ -649,7 +689,7 @@ class map iterator find(const key_type& x) { return m_tree.find(x); } - //! Returns: A const_iterator pointing to an element with the key + //! Returns: Allocator const_iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. @@ -669,7 +709,7 @@ class map iterator lower_bound(const key_type& x) { return m_tree.lower_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -683,7 +723,7 @@ class map iterator upper_bound(const key_type& x) { return m_tree.upper_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -717,7 +757,7 @@ class map // i->first is greater than or equivalent to k. if (i == end() || key_comp()(k, (*i).first)){ container_detail::value_init m; - nonconst_impl_value_type val(k, boost::move(m.m_t)); + movable_value_type val(k, boost::move(m.m_t)); i = insert(i, boost::move(val)); } return (*i).second; @@ -731,7 +771,7 @@ class map // i->first is greater than or equivalent to k. if (i == end() || key_comp()(k, (*i).first)){ container_detail::value_init m; - nonconst_impl_value_type val(boost::move(k), boost::move(m.m_t)); + movable_value_type val(boost::move(k), boost::move(m.m_t)); i = insert(i, boost::move(val)); } return (*i).second; @@ -740,60 +780,60 @@ class map /// @endcond }; -template -inline bool operator==(const map& x, - const map& y) +template +inline bool operator==(const map& x, + const map& y) { return x.m_tree == y.m_tree; } -template -inline bool operator<(const map& x, - const map& y) +template +inline bool operator<(const map& x, + const map& y) { return x.m_tree < y.m_tree; } -template -inline bool operator!=(const map& x, - const map& y) +template +inline bool operator!=(const map& x, + const map& y) { return !(x == y); } -template -inline bool operator>(const map& x, - const map& y) +template +inline bool operator>(const map& x, + const map& y) { return y < x; } -template -inline bool operator<=(const map& x, - const map& y) +template +inline bool operator<=(const map& x, + const map& y) { return !(y < x); } -template -inline bool operator>=(const map& x, - const map& y) +template +inline bool operator>=(const map& x, + const map& y) { return !(x < y); } -template -inline void swap(map& x, map& y) +template +inline void swap(map& x, map& y) { x.swap(y); } /// @cond // Forward declaration of operators < and ==, needed for friend declaration. -template -inline bool operator==(const multimap& x, - const multimap& y); +template +inline bool operator==(const multimap& x, + const multimap& y); -template -inline bool operator<(const multimap& x, - const multimap& y); +template +inline bool operator<(const multimap& x, + const multimap& y); } //namespace container { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { @@ -809,68 +849,63 @@ namespace container { //! container and of an associative container. For a //! map the key_type is Key and the value_type is std::pair. //! -//! Pred is the ordering function for Keys (e.g. std::less). +//! Compare is the ordering function for Keys (e.g. std::less). //! -//! A is the allocator to allocate the value_types +//! Allocator is the allocator to allocate the value_types //!(e.g. allocator< std::pair<const Key, T> >). #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator< std::pair< const Key, T> > > +template , class Allocator = std::allocator< std::pair< const Key, T> > > #else -template +template #endif class multimap { /// @cond private: BOOST_COPYABLE_AND_MOVABLE(multimap) - typedef container_detail::rbtree, - container_detail::select1st< std::pair >, - Pred, - A> tree_t; + + typedef std::pair value_type_impl; + typedef container_detail::rbtree + , Compare, Allocator> tree_t; + typedef container_detail::pair movable_value_type_impl; + typedef container_detail::tree_value_compare + < Key, value_type_impl, Compare, container_detail::select1st + > value_compare_impl; tree_t m_tree; // red-black tree representing map - typedef typename container_detail:: - move_const_ref_type::type insert_key_const_ref_type; /// @endcond public: + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// - // typedefs: - typedef typename tree_t::key_type key_type; - typedef typename tree_t::value_type value_type; - typedef typename tree_t::pointer pointer; - typedef typename tree_t::const_pointer const_pointer; - typedef typename tree_t::reference reference; - typedef typename tree_t::const_reference const_reference; - typedef T mapped_type; - typedef Pred key_compare; - typedef typename tree_t::iterator iterator; - typedef typename tree_t::const_iterator const_iterator; - typedef typename tree_t::reverse_iterator reverse_iterator; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator; - typedef typename tree_t::size_type size_type; - typedef typename tree_t::difference_type difference_type; - typedef typename tree_t::allocator_type allocator_type; - typedef typename tree_t::stored_allocator_type stored_allocator_type; - typedef std::pair nonconst_value_type; - typedef container_detail::pair - nonconst_impl_value_type; + typedef Key key_type; + typedef T mapped_type; + typedef std::pair value_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef Compare key_compare; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; + typedef std::pair nonconst_value_type; + typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; - /// @cond - class value_compare_impl - : public Pred, - public std::binary_function - { - friend class multimap; - protected : - value_compare_impl(const Pred &c) : Pred(c) {} - public: - bool operator()(const value_type& x, const value_type& y) const { - return Pred::operator()(x.first, y.first); - } - }; - /// @endcond - typedef value_compare_impl value_compare; + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// //! Effects: Default constructs an empty multimap. //! @@ -879,18 +914,18 @@ class multimap : m_tree() { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty multimap using the specified comparison //! object and allocator. //! //! Complexity: Constant. - explicit multimap(const Pred& comp, const allocator_type& a = allocator_type()) + explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) : m_tree(comp, a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty multimap using the specified comparison object @@ -900,12 +935,12 @@ class multimap //! comp and otherwise N logN, where N is last - first. template multimap(InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_tree(false, first, last, comp, a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty multimap using the specified comparison object and @@ -916,7 +951,7 @@ class multimap //! //! Complexity: Linear in N. template - multimap(ordered_range_t ordered_range, InputIterator first, InputIterator last, const Pred& comp = Pred(), + multimap(ordered_range_t ordered_range, InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_tree(ordered_range, first, last, comp, a) {} @@ -928,7 +963,7 @@ class multimap : m_tree(x.m_tree) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a multimap. Constructs *this using x's resources. @@ -940,7 +975,7 @@ class multimap : m_tree(boost::move(x.m_tree)) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Copy constructs a multimap. @@ -950,7 +985,7 @@ class multimap : m_tree(x.m_tree, a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a multimap using the specified allocator. @@ -962,7 +997,7 @@ class multimap : m_tree(boost::move(x.m_tree), a) { //Allocator type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Makes *this a copy of x. @@ -977,20 +1012,6 @@ class multimap multimap& operator=(BOOST_RV_REF(multimap) x) { m_tree = boost::move(x.m_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return m_tree.key_comp(); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return value_compare(m_tree.key_comp()); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -998,11 +1019,31 @@ class multimap allocator_type get_allocator() const { return m_tree.get_allocator(); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() + { return m_tree.get_stored_allocator(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return m_tree.get_stored_allocator(); } - stored_allocator_type &get_stored_allocator() - { return m_tree.get_stored_allocator(); } + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// //! Effects: Returns an iterator to the first element contained in the container. //! @@ -1020,14 +1061,6 @@ class multimap const_iterator begin() const { return this->cbegin(); } - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const - { return m_tree.begin(); } - //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. @@ -1044,14 +1077,6 @@ class multimap const_iterator end() const { return this->cend(); } - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const - { return m_tree.end(); } - //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. //! @@ -1070,15 +1095,6 @@ class multimap const_reverse_iterator rbegin() const { return this->crbegin(); } - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const - { return m_tree.rbegin(); } - //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. //! @@ -1097,6 +1113,31 @@ class multimap const_reverse_iterator rend() const { return this->crend(); } + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cbegin() const + { return m_tree.begin(); } + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cend() const + { return m_tree.end(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator crbegin() const + { return m_tree.rbegin(); } + //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. //! @@ -1106,6 +1147,12 @@ class multimap const_reverse_iterator crend() const { return m_tree.rend(); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -1130,94 +1177,11 @@ class multimap size_type max_size() const { return m_tree.max_size(); } - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(multimap& x) - { m_tree.swap(x.m_tree); } - - //! Effects: Inserts x and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic. - iterator insert(const value_type& x) - { return m_tree.insert_equal(x); } - - //! Effects: Inserts a new value constructed from x and returns - //! the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic. - iterator insert(const nonconst_value_type& x) - { return m_tree.insert_equal(x); } - - //! Effects: Inserts a new value move-constructed from x and returns - //! the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic. - iterator insert(BOOST_RV_REF(nonconst_value_type) x) - { return m_tree.insert_equal(boost::move(x)); } - - //! Effects: Inserts a new value move-constructed from x and returns - //! the iterator pointing to the newly inserted element. - //! - //! Complexity: Logarithmic. - iterator insert(BOOST_RV_REF(nonconst_impl_value_type) x) - { return m_tree.insert_equal(boost::move(x)); } - - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(iterator position, const value_type& x) - { return m_tree.insert_equal(position, x); } - - //! Effects: Inserts a new value constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(iterator position, const nonconst_value_type& x) - { return m_tree.insert_equal(position, x); } - - //! Effects: Inserts a new value move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(iterator position, BOOST_RV_REF(nonconst_value_type) x) - { return m_tree.insert_equal(position, boost::move(x)); } - - //! Effects: Inserts a new value move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(iterator position, BOOST_RV_REF(nonconst_impl_value_type) x) - { return m_tree.insert_equal(position, boost::move(x)); } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) . - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - template - void insert(InputIterator first, InputIterator last) - { m_tree.insert_equal(first, last); } + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1265,6 +1229,87 @@ class multimap #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + //! Effects: Inserts x and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(const value_type& x) + { return m_tree.insert_equal(x); } + + //! Effects: Inserts a new value constructed from x and returns + //! the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(const nonconst_value_type& x) + { return m_tree.insert_equal(x); } + + //! Effects: Inserts a new value move-constructed from x and returns + //! the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(BOOST_RV_REF(nonconst_value_type) x) + { return m_tree.insert_equal(boost::move(x)); } + + //! Effects: Inserts a new value move-constructed from x and returns + //! the iterator pointing to the newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(BOOST_RV_REF(movable_value_type) x) + { return m_tree.insert_equal(boost::move(x)); } + + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator position, const value_type& x) + { return m_tree.insert_equal(position, x); } + + //! Effects: Inserts a new value constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator position, const nonconst_value_type& x) + { return m_tree.insert_equal(position, x); } + + //! Effects: Inserts a new value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) + { return m_tree.insert_equal(position, boost::move(x)); } + + //! Effects: Inserts a new value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) + { return m_tree.insert_equal(position, boost::move(x)); } + + //! Requires: first, last are not iterators into *this. + //! + //! Effects: inserts each element from the range [first,last) . + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + template + void insert(InputIterator first, InputIterator last) + { m_tree.insert_equal(first, last); } + //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately @@ -1291,6 +1336,14 @@ class multimap iterator erase(const_iterator first, const_iterator last) { return m_tree.erase(first, last); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(multimap& x) + { m_tree.swap(x.m_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -1299,6 +1352,32 @@ class multimap void clear() { m_tree.clear(); } + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return value_compare(m_tree.key_comp()); } + + ////////////////////////////////////////////// + // + // map operations + // + ////////////////////////////////////////////// + //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! @@ -1306,7 +1385,7 @@ class multimap iterator find(const key_type& x) { return m_tree.find(x); } - //! Returns: A const iterator pointing to an element with the key + //! Returns: Allocator const iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. @@ -1326,7 +1405,7 @@ class multimap iterator lower_bound(const key_type& x) {return m_tree.lower_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1340,13 +1419,7 @@ class multimap iterator upper_bound(const key_type& x) { return m_tree.upper_bound(x); } - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - std::pair equal_range(const key_type& x) - { return m_tree.equal_range(x); } - - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1356,8 +1429,13 @@ class multimap //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) const + std::pair equal_range(const key_type& x) + { return m_tree.equal_range(x); } + + //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! Complexity: Logarithmic + std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } /// @cond @@ -1371,38 +1449,38 @@ class multimap /// @endcond }; -template -inline bool operator==(const multimap& x, - const multimap& y) +template +inline bool operator==(const multimap& x, + const multimap& y) { return x.m_tree == y.m_tree; } -template -inline bool operator<(const multimap& x, - const multimap& y) +template +inline bool operator<(const multimap& x, + const multimap& y) { return x.m_tree < y.m_tree; } -template -inline bool operator!=(const multimap& x, - const multimap& y) +template +inline bool operator!=(const multimap& x, + const multimap& y) { return !(x == y); } -template -inline bool operator>(const multimap& x, - const multimap& y) +template +inline bool operator>(const multimap& x, + const multimap& y) { return y < x; } -template -inline bool operator<=(const multimap& x, - const multimap& y) +template +inline bool operator<=(const multimap& x, + const multimap& y) { return !(y < x); } -template -inline bool operator>=(const multimap& x, - const multimap& y) +template +inline bool operator>=(const multimap& x, + const multimap& y) { return !(x < y); } -template -inline void swap(multimap& x, multimap& y) +template +inline void swap(multimap& x, multimap& y) { x.swap(y); } /// @cond @@ -1411,10 +1489,10 @@ inline void swap(multimap& x, multimap& y) /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { diff --git a/include/boost/container/scoped_allocator.hpp b/include/boost/container/scoped_allocator.hpp index 7da71bd..5111d37 100644 --- a/include/boost/container/scoped_allocator.hpp +++ b/include/boost/container/scoped_allocator.hpp @@ -47,10 +47,10 @@ namespace boost { namespace container { //! ill-formed. //! //! [Example: -//! template > +//! template > //! class Z { //! public: -//! typedef A allocator_type; +//! typedef Allocator allocator_type; //! //! // Default constructor with optional allocator suffix //! Z(const allocator_type& a = allocator_type()); @@ -61,8 +61,8 @@ namespace boost { namespace container { //! }; //! //! // Specialize trait for class template Z -//! template > -//! struct constructible_with_allocator_suffix > +//! template > +//! struct constructible_with_allocator_suffix > //! : ::boost::true_type { }; //! -- end example] //! @@ -91,10 +91,10 @@ struct constructible_with_allocator_suffix //! a constructor, then the program is ill-formed. //! //! [Example: -//! template > +//! template > //! class Y { //! public: -//! typedef A allocator_type; +//! typedef Allocator allocator_type; //! //! // Default constructor with and allocator-extended default constructor //! Y(); @@ -111,8 +111,8 @@ struct constructible_with_allocator_suffix //! }; //! //! // Specialize trait for class template Y -//! template > -//! struct constructible_with_allocator_prefix > +//! template > +//! struct constructible_with_allocator_prefix > //! : ::boost::true_type { }; //! //! -- end example] @@ -1036,16 +1036,16 @@ class scoped_allocator_adaptor typedef typename outer_traits_type::const_pointer const_pointer; typedef typename outer_traits_type::void_pointer void_pointer; typedef typename outer_traits_type::const_void_pointer const_void_pointer; - //! Type: `true_type` if `allocator_traits::propagate_on_container_copy_assignment::value` is - //! true for any `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. + //! Type: `true_type` if `allocator_traits::propagate_on_container_copy_assignment::value` is + //! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. typedef typename base_type:: propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - //! Type: `true_type` if `allocator_traits::propagate_on_container_move_assignment::value` is - //! true for any `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. + //! Type: `true_type` if `allocator_traits::propagate_on_container_move_assignment::value` is + //! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. typedef typename base_type:: propagate_on_container_move_assignment propagate_on_container_move_assignment; - //! Type: `true_type` if `allocator_traits::propagate_on_container_swap::value` is true for any - //! `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. + //! Type: `true_type` if `allocator_traits::propagate_on_container_swap::value` is true for any + //! `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. typedef typename base_type:: propagate_on_container_swap propagate_on_container_swap; @@ -1211,9 +1211,9 @@ class scoped_allocator_adaptor outer_traits_type::deallocate(this->outer_allocator(), p, n); } - //! Returns: A new scoped_allocator_adaptor object where each allocator + //! Returns: Allocator new scoped_allocator_adaptor object where each allocator //! A in the adaptor is initialized from the result of calling - //! `allocator_traits::select_on_container_copy_construction()` on + //! `allocator_traits::select_on_container_copy_construction()` on //! the corresponding allocator in *this. scoped_allocator_adaptor select_on_container_copy_construction() const { diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp index 44a854c..bdb89f2 100644 --- a/include/boost/container/set.hpp +++ b/include/boost/container/set.hpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -31,23 +32,18 @@ #include #endif -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { -#else -namespace boost { -namespace container { -#endif /// @cond // Forward declarations of operators < and ==, needed for friend declaration. -template -inline bool operator==(const set& x, - const set& y); +template +inline bool operator==(const set& x, + const set& y); -template -inline bool operator<(const set& x, - const set& y); +template +inline bool operator<(const set& x, + const set& y); /// @endcond //! A set is a kind of associative container that supports unique keys (contains at @@ -58,41 +54,48 @@ inline bool operator<(const set& x, //! , and of an associative container. A set also provides most operations described in //! for unique keys. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = std::allocator > #else -template +template #endif class set { /// @cond private: BOOST_COPYABLE_AND_MOVABLE(set) - typedef container_detail::rbtree, Pred, A> tree_t; + typedef container_detail::rbtree, Compare, Allocator> tree_t; tree_t m_tree; // red-black tree representing set - typedef typename container_detail:: - move_const_ref_type::type insert_const_ref_type; /// @endcond public: + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef Compare value_compare; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; - // typedefs: - typedef typename tree_t::key_type key_type; - typedef typename tree_t::value_type value_type; - typedef typename tree_t::pointer pointer; - typedef typename tree_t::const_pointer const_pointer; - typedef typename tree_t::reference reference; - typedef typename tree_t::const_reference const_reference; - typedef Pred key_compare; - typedef Pred value_compare; - typedef typename tree_t::iterator iterator; - typedef typename tree_t::const_iterator const_iterator; - typedef typename tree_t::reverse_iterator reverse_iterator; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator; - typedef typename tree_t::size_type size_type; - typedef typename tree_t::difference_type difference_type; - typedef typename tree_t::allocator_type allocator_type; - typedef typename tree_t::stored_allocator_type stored_allocator_type; + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// //! Effects: Default constructs an empty set. //! @@ -105,7 +108,7 @@ class set //! and allocator. //! //! Complexity: Constant. - explicit set(const Pred& comp, + explicit set(const Compare& comp, const allocator_type& a = allocator_type()) : m_tree(comp, a) {} @@ -116,7 +119,7 @@ class set //! Complexity: Linear in N if the range [first ,last ) is already sorted using //! comp and otherwise N logN, where N is last - first. template - set(InputIterator first, InputIterator last, const Pred& comp = Pred(), + set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_tree(true, first, last, comp, a) {} @@ -131,7 +134,7 @@ class set //! Complexity: Linear in N. template set( ordered_unique_range_t, InputIterator first, InputIterator last - , const Pred& comp = Pred(), const allocator_type& a = allocator_type()) + , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_tree(ordered_range, first, last, comp, a) {} @@ -178,20 +181,6 @@ class set set& operator=(BOOST_RV_REF(set) x) { m_tree = boost::move(x.m_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return m_tree.key_comp(); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return m_tree.key_comp(); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -199,12 +188,32 @@ class set allocator_type get_allocator() const { return m_tree.get_allocator(); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return m_tree.get_stored_allocator(); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. stored_allocator_type &get_stored_allocator() { return m_tree.get_stored_allocator(); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns an iterator to the first element contained in the container. //! //! Throws: Nothing. @@ -307,6 +316,12 @@ class set const_reverse_iterator crend() const { return m_tree.crend(); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -331,90 +346,15 @@ class set size_type max_size() const { return m_tree.max_size(); } - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(set& x) - { m_tree.swap(x.m_tree); } - - //! Effects: Inserts x if and only if there is no element in the container - //! with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - std::pair insert(insert_const_ref_type x) - { return priv_insert(x); } - - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - std::pair insert(T &x) - { return this->insert(const_cast(x)); } - - template - std::pair insert(const U &u - , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(u); } - #endif - - //! Effects: Move constructs a new value from x if and only if there is - //! no element in the container with key equivalent to the key of x. - //! - //! Returns: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - std::pair insert(BOOST_RV_REF(value_type) x) - { return m_tree.insert_unique(boost::move(x)); } - - //! Effects: Inserts a copy of x in the container if and only if there is - //! no element in the container with key equivalent to the key of x. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(const_iterator p, insert_const_ref_type x) - { return priv_insert(p, x); } - - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - iterator insert(const_iterator position, T &x) - { return this->insert(position, const_cast(x)); } - - template - iterator insert( const_iterator position, const U &u - , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(position, u); } - #endif - - //! Effects: Inserts an element move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent to the key of x. - //! - //! Complexity: Logarithmic. - iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) - { return m_tree.insert_unique(p, boost::move(x)); } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) if and only - //! if there is no element with key equivalent to the key of that element. - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - template - void insert(InputIterator first, InputIterator last) - { m_tree.insert_unique(first, last); } + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts an object x of type T constructed with + //! Effects: Inserts an object x of type Key constructed with //! std::forward(args)... if and only if there is //! no element in the container with equivalent value. //! and returns the iterator pointing to the @@ -425,14 +365,14 @@ class set //! points to the element with key equivalent to the key of x. //! //! Throws: If memory allocation throws or - //! T's in-place constructor throws. + //! Key's in-place constructor throws. //! //! Complexity: Logarithmic. template std::pair emplace(Args&&... args) { return m_tree.emplace_unique(boost::forward(args)...); } - //! Effects: Inserts an object of type T constructed with + //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... if and only if there is //! no element in the container with equivalent value. //! p is a hint pointing to where the insert @@ -463,6 +403,66 @@ class set #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts x if and only if there is no element in the container + //! with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + std::pair insert(const value_type &x); + + //! Effects: Move constructs a new value from x if and only if there is + //! no element in the container with key equivalent to the key of x. + //! + //! Returns: The bool component of the returned pair is true if and only + //! if the insertion takes place, and the iterator component of the pair + //! points to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + std::pair insert(value_type &&x); + #else + private: + typedef std::pair insert_return_pair; + public: + BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert) + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts a copy of x in the container if and only if there is + //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator p, const value_type &x); + + //! Effects: Inserts an element move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent to the key of x. + //! + //! Complexity: Logarithmic. + iterator insert(const_iterator position, value_type &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator) + #endif + + //! Requires: first, last are not iterators into *this. + //! + //! Effects: inserts each element from the range [first,last) if and only + //! if there is no element with key equivalent to the key of that element. + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + template + void insert(InputIterator first, InputIterator last) + { m_tree.insert_unique(first, last); } + //! Effects: Erases the element pointed to by p. //! //! Returns: Returns an iterator pointing to the element immediately @@ -489,6 +489,14 @@ class set iterator erase(const_iterator first, const_iterator last) { return m_tree.erase(first, last); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(set& x) + { m_tree.swap(x.m_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -497,6 +505,32 @@ class set void clear() { m_tree.clear(); } + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return m_tree.key_comp(); } + + ////////////////////////////////////////////// + // + // set operations + // + ////////////////////////////////////////////// + //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! @@ -504,7 +538,7 @@ class set iterator find(const key_type& x) { return m_tree.find(x); } - //! Returns: A const_iterator pointing to an element with the key + //! Returns: Allocator const_iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. @@ -524,7 +558,7 @@ class set iterator lower_bound(const key_type& x) { return m_tree.lower_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -538,7 +572,7 @@ class set iterator upper_bound(const key_type& x) { return m_tree.upper_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -548,15 +582,13 @@ class set //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) + std::pair equal_range(const key_type& x) { return m_tree.equal_range(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) const + std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } /// @cond @@ -567,47 +599,48 @@ class set friend bool operator< (const set&, const set&); private: - std::pair priv_insert(const T &x) - { return m_tree.insert_unique(x); } - - iterator priv_insert(const_iterator p, const T &x) - { return m_tree.insert_unique(p, x); } + template + std::pair priv_insert(BOOST_FWD_REF(KeyType) x) + { return m_tree.insert_unique(::boost::forward(x)); } + template + iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) + { return m_tree.insert_unique(p, ::boost::forward(x)); } /// @endcond }; -template -inline bool operator==(const set& x, - const set& y) +template +inline bool operator==(const set& x, + const set& y) { return x.m_tree == y.m_tree; } -template -inline bool operator<(const set& x, - const set& y) +template +inline bool operator<(const set& x, + const set& y) { return x.m_tree < y.m_tree; } -template -inline bool operator!=(const set& x, - const set& y) +template +inline bool operator!=(const set& x, + const set& y) { return !(x == y); } -template -inline bool operator>(const set& x, - const set& y) +template +inline bool operator>(const set& x, + const set& y) { return y < x; } -template -inline bool operator<=(const set& x, - const set& y) +template +inline bool operator<=(const set& x, + const set& y) { return !(y < x); } -template -inline bool operator>=(const set& x, - const set& y) +template +inline bool operator>=(const set& x, + const set& y) { return !(x < y); } -template -inline void swap(set& x, set& y) +template +inline void swap(set& x, set& y) { x.swap(y); } /// @cond @@ -616,23 +649,23 @@ inline void swap(set& x, set& y) /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { // Forward declaration of operators < and ==, needed for friend declaration. -template -inline bool operator==(const multiset& x, - const multiset& y); +template +inline bool operator==(const multiset& x, + const multiset& y); -template -inline bool operator<(const multiset& x, - const multiset& y); +template +inline bool operator<(const multiset& x, + const multiset& y); /// @endcond //! A multiset is a kind of associative container that supports equivalent keys @@ -643,41 +676,49 @@ inline bool operator<(const multiset& x, //! container, and of an associative container). multiset also provides most operations //! described for duplicate keys. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = std::allocator > #else -template +template #endif class multiset { /// @cond private: BOOST_COPYABLE_AND_MOVABLE(multiset) - typedef container_detail::rbtree, Pred, A> tree_t; + typedef container_detail::rbtree, Compare, Allocator> tree_t; tree_t m_tree; // red-black tree representing multiset - typedef typename container_detail:: - move_const_ref_type::type insert_const_ref_type; /// @endcond public: - // typedefs: - typedef typename tree_t::key_type key_type; - typedef typename tree_t::value_type value_type; - typedef typename tree_t::pointer pointer; - typedef typename tree_t::const_pointer const_pointer; - typedef typename tree_t::reference reference; - typedef typename tree_t::const_reference const_reference; - typedef Pred key_compare; - typedef Pred value_compare; - typedef typename tree_t::iterator iterator; - typedef typename tree_t::const_iterator const_iterator; - typedef typename tree_t::reverse_iterator reverse_iterator; - typedef typename tree_t::const_reverse_iterator const_reverse_iterator; - typedef typename tree_t::size_type size_type; - typedef typename tree_t::difference_type difference_type; - typedef typename tree_t::allocator_type allocator_type; - typedef typename tree_t::stored_allocator_type stored_allocator_type; + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef Compare value_compare; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; + + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// //! Effects: Constructs an empty multiset using the specified comparison //! object and allocator. @@ -691,7 +732,7 @@ class multiset //! object and allocator. //! //! Complexity: Constant. - explicit multiset(const Pred& comp, + explicit multiset(const Compare& comp, const allocator_type& a = allocator_type()) : m_tree(comp, a) {} @@ -703,7 +744,7 @@ class multiset //! comp and otherwise N logN, where N is last - first. template multiset(InputIterator first, InputIterator last, - const Pred& comp = Pred(), + const Compare& comp = Compare(), const allocator_type& a = allocator_type()) : m_tree(false, first, last, comp, a) {} @@ -717,7 +758,7 @@ class multiset //! Complexity: Linear in N. template multiset( ordered_range_t ordered_range, InputIterator first, InputIterator last - , const Pred& comp = Pred() + , const Compare& comp = Compare() , const allocator_type& a = allocator_type()) : m_tree(ordered_range, first, last, comp, a) {} @@ -767,20 +808,6 @@ class multiset multiset& operator=(BOOST_RV_REF(multiset) x) { m_tree = boost::move(x.m_tree); return *this; } - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return m_tree.key_comp(); } - - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return m_tree.key_comp(); } - //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! @@ -788,11 +815,31 @@ class multiset allocator_type get_allocator() const { return m_tree.get_allocator(); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() + { return m_tree.get_stored_allocator(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. const stored_allocator_type &get_stored_allocator() const { return m_tree.get_stored_allocator(); } - stored_allocator_type &get_stored_allocator() - { return m_tree.get_stored_allocator(); } + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// //! Effects: Returns an iterator to the first element contained in the container. //! @@ -896,6 +943,12 @@ class multiset const_reverse_iterator crend() const { return m_tree.crend(); } + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. @@ -920,85 +973,15 @@ class multiset size_type max_size() const { return m_tree.max_size(); } - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(multiset& x) - { m_tree.swap(x.m_tree); } - - //! Effects: Inserts x and returns the iterator pointing to the - //! newly inserted element. - //! - //! Complexity: Logarithmic. - iterator insert(insert_const_ref_type x) - { return priv_insert(x); } - - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - iterator insert(T &x) - { return this->insert(const_cast(x)); } - - template - iterator insert(const U &u - , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(u); } - #endif - - //! Effects: Inserts a copy of x in the container. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(BOOST_RV_REF(value_type) x) - { return m_tree.insert_equal(boost::move(x)); } - - //! Effects: Inserts a copy of x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(const_iterator p, insert_const_ref_type x) - { return priv_insert(p, x); } - - #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - iterator insert(const_iterator position, T &x) - { return this->insert(position, const_cast(x)); } - - template - iterator insert( const_iterator position, const U &u - , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0) - { return priv_insert(position, u); } - #endif - - //! Effects: Inserts a value move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! Returns: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! Complexity: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) - { return m_tree.insert_equal(p, boost::move(x)); } - - //! Requires: first, last are not iterators into *this. - //! - //! Effects: inserts each element from the range [first,last) . - //! - //! Complexity: At most N log(size()+N) (N is the distance from first to last) - template - void insert(InputIterator first, InputIterator last) - { m_tree.insert_equal(first, last); } + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Inserts an object of type T constructed with + //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... and returns the iterator pointing to the //! newly inserted element. //! @@ -1007,7 +990,7 @@ class multiset iterator emplace(Args&&... args) { return m_tree.emplace_equal(boost::forward(args)...); } - //! Effects: Inserts an object of type T constructed with + //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... //! //! Returns: An iterator pointing to the element with key equivalent @@ -1037,6 +1020,61 @@ class multiset #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + + + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts x and returns the iterator pointing to the + //! newly inserted element. + //! + //! Complexity: Logarithmic. + iterator insert(const value_type &x); + + //! Effects: Inserts a copy of x in the container. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(value_type &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert) + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts a copy of x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator p, const value_type &x); + + //! Effects: Inserts a value move constructed from x in the container. + //! p is a hint pointing to where the insert should start to search. + //! + //! Returns: An iterator pointing to the element with key equivalent + //! to the key of x. + //! + //! Complexity: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + iterator insert(const_iterator position, value_type &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator) + #endif + + //! Requires: first, last are not iterators into *this. + //! + //! Effects: inserts each element from the range [first,last) . + //! + //! Complexity: At most N log(size()+N) (N is the distance from first to last) + template + void insert(InputIterator first, InputIterator last) + { m_tree.insert_equal(first, last); } + //! Effects: Erases the element pointed to by p. //! //! Returns: Returns an iterator pointing to the element immediately @@ -1063,6 +1101,14 @@ class multiset iterator erase(const_iterator first, const_iterator last) { return m_tree.erase(first, last); } + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(multiset& x) + { m_tree.swap(x.m_tree); } + //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. @@ -1071,6 +1117,32 @@ class multiset void clear() { m_tree.clear(); } + ////////////////////////////////////////////// + // + // observers + // + ////////////////////////////////////////////// + + //! Effects: Returns the comparison object out + //! of which a was constructed. + //! + //! Complexity: Constant. + key_compare key_comp() const + { return m_tree.key_comp(); } + + //! Effects: Returns an object of value_compare constructed out + //! of the comparison object. + //! + //! Complexity: Constant. + value_compare value_comp() const + { return m_tree.key_comp(); } + + ////////////////////////////////////////////// + // + // set operations + // + ////////////////////////////////////////////// + //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! @@ -1078,7 +1150,7 @@ class multiset iterator find(const key_type& x) { return m_tree.find(x); } - //! Returns: A const iterator pointing to an element with the key + //! Returns: Allocator const iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. @@ -1098,7 +1170,7 @@ class multiset iterator lower_bound(const key_type& x) { return m_tree.lower_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1112,7 +1184,7 @@ class multiset iterator upper_bound(const key_type& x) { return m_tree.upper_bound(x); } - //! Returns: A const iterator pointing to the first element with key not + //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic @@ -1122,15 +1194,13 @@ class multiset //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) + std::pair equal_range(const key_type& x) { return m_tree.equal_range(x); } //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair - equal_range(const key_type& x) const + std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } /// @cond @@ -1141,47 +1211,49 @@ class multiset friend bool operator< (const multiset&, const multiset&); private: - iterator priv_insert(const T &x) - { return m_tree.insert_equal(x); } + template + iterator priv_insert(BOOST_FWD_REF(KeyType) x) + { return m_tree.insert_equal(::boost::forward(x)); } - iterator priv_insert(const_iterator p, const T &x) - { return m_tree.insert_equal(p, x); } + template + iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) + { return m_tree.insert_equal(p, ::boost::forward(x)); } /// @endcond }; -template -inline bool operator==(const multiset& x, - const multiset& y) +template +inline bool operator==(const multiset& x, + const multiset& y) { return x.m_tree == y.m_tree; } -template -inline bool operator<(const multiset& x, - const multiset& y) +template +inline bool operator<(const multiset& x, + const multiset& y) { return x.m_tree < y.m_tree; } -template -inline bool operator!=(const multiset& x, - const multiset& y) +template +inline bool operator!=(const multiset& x, + const multiset& y) { return !(x == y); } -template -inline bool operator>(const multiset& x, - const multiset& y) +template +inline bool operator>(const multiset& x, + const multiset& y) { return y < x; } -template -inline bool operator<=(const multiset& x, - const multiset& y) +template +inline bool operator<=(const multiset& x, + const multiset& y) { return !(y < x); } -template -inline bool operator>=(const multiset& x, - const multiset& y) +template +inline bool operator>=(const multiset& x, + const multiset& y) { return !(x < y); } -template -inline void swap(multiset& x, multiset& y) +template +inline void swap(multiset& x, multiset& y) { x.swap(y); } /// @cond @@ -1190,10 +1262,10 @@ inline void swap(multiset& x, multiset& y) /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value && has_trivial_destructor::value; }; */ namespace container { diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index c5ca7fa..c65a9a2 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -44,17 +44,12 @@ #include #include -#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { -#else -namespace boost { -namespace container { -#endif /// @cond -template +template class slist; namespace container_detail { @@ -78,10 +73,10 @@ struct slist_node T m_data; }; -template +template struct intrusive_slist_type { - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef typename boost::intrusive::pointer_traits ::template @@ -230,18 +225,18 @@ class slist_iterator //! needs, and that you often need to use insert and erase in the middle of the list, //! then you should probably use list instead of slist. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif class slist : protected container_detail::node_alloc_holder - ::type> + ::type> { /// @cond typedef typename - container_detail::intrusive_slist_type::type Icont; - typedef container_detail::node_alloc_holder AllocHolder; + container_detail::intrusive_slist_type::type Icont; + typedef container_detail::node_alloc_holder AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef typename AllocHolder::ValAlloc ValAlloc; @@ -250,7 +245,7 @@ class slist typedef typename AllocHolder::allocator_v1 allocator_v1; typedef typename AllocHolder::allocator_v2 allocator_v2; typedef typename AllocHolder::alloc_version alloc_version; - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; class equal_to_value { @@ -294,13 +289,13 @@ class slist ////////////////////////////////////////////// typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; @@ -519,12 +514,14 @@ class slist allocator_type get_allocator() const { return allocator_type(this->node_alloc()); } - //! Effects: Returns a copy of the internal allocator. + //! Effects: Returns a reference to the internal allocator. //! - //! Throws: If allocator's copy constructor throws. + //! Throws: Nothing //! //! Complexity: Constant. - const stored_allocator_type &get_stored_allocator() const + //! + //! Note: Non-standard extension. + stored_allocator_type &get_stored_allocator() { return this->node_alloc(); } //! Effects: Returns a reference to the internal allocator. @@ -534,7 +531,7 @@ class slist //! Complexity: Constant. //! //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() + const stored_allocator_type &get_stored_allocator() const { return this->node_alloc(); } ////////////////////////////////////////////// @@ -1605,14 +1602,14 @@ class slist /// @endcond }; -template +template inline bool -operator==(const slist& x, const slist& y) +operator==(const slist& x, const slist& y) { if(x.size() != y.size()){ return false; } - typedef typename slist::const_iterator const_iterator; + typedef typename slist::const_iterator const_iterator; const_iterator end1 = x.end(); const_iterator i1 = x.begin(); @@ -1624,36 +1621,36 @@ operator==(const slist& x, const slist& y) return i1 == end1; } -template +template inline bool -operator<(const slist& sL1, const slist& sL2) +operator<(const slist& sL1, const slist& sL2) { return std::lexicographical_compare (sL1.begin(), sL1.end(), sL2.begin(), sL2.end()); } -template +template inline bool -operator!=(const slist& sL1, const slist& sL2) +operator!=(const slist& sL1, const slist& sL2) { return !(sL1 == sL2); } -template +template inline bool -operator>(const slist& sL1, const slist& sL2) +operator>(const slist& sL1, const slist& sL2) { return sL2 < sL1; } -template +template inline bool -operator<=(const slist& sL1, const slist& sL2) +operator<=(const slist& sL1, const slist& sL2) { return !(sL2 < sL1); } -template +template inline bool -operator>=(const slist& sL1, const slist& sL2) +operator>=(const slist& sL1, const slist& sL2) { return !(sL1 < sL2); } -template -inline void swap(slist& x, slist& y) +template +inline void swap(slist& x, slist& y) { x.swap(y); } }} @@ -1664,10 +1661,10 @@ namespace boost { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value; }; */ namespace container { @@ -1685,11 +1682,11 @@ namespace container { //there is no other way namespace std { -template -class insert_iterator > +template +class insert_iterator > { protected: - typedef boost::container::slist Container; + typedef boost::container::slist Container; Container* container; typename Container::iterator iter; public: @@ -1722,4 +1719,4 @@ class insert_iterator > #include -#endif /* BOOST_CONTAINER_SLIST_HPP */ +#endif // BOOST_CONTAINER_SLIST_HPP diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index 3e45e7e..03f7d92 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -275,26 +275,6 @@ class iterator node_ptr pn; }; -template -struct select_multiallocation_chain -{ - typedef typename A::multiallocation_chain type; -}; - -template -struct select_multiallocation_chain -{ - typedef typename boost::intrusive::pointer_traits - ::pointer>:: - template rebind_pointer::type void_ptr; - typedef container_detail::basic_multiallocation_chain - multialloc_cached_counted; - typedef boost::container::container_detail:: - transform_multiallocation_chain - < multialloc_cached_counted - , typename allocator_traits::value_type> type; -}; - template struct index_traits { @@ -386,6 +366,89 @@ struct index_traits #endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING }; +template::value> +struct allocator_version_wrapper +{ + typedef ::boost::container::container_detail::integral_constant + alloc_version; + + typedef typename Allocator::multiallocation_chain multiallocation_chain; + + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::size_type size_type; + + static pointer allocate_one(Allocator &a) + { return a.allocate_one(); } + + static void deallocate_one(Allocator &a, const pointer &p) + { a.deallocate_one(p); } + + static multiallocation_chain allocate_individual(Allocator &a, size_type n) + { return a.allocate_individual(n); } + + static void deallocate_individual(Allocator &a, multiallocation_chain &holder) + { a.deallocate_individual(::boost::move(holder)); } +}; + +template +struct allocator_version_wrapper +{ + typedef ::boost::container::container_detail::integral_constant + alloc_version; + + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::value_type value_type; + + typedef typename boost::intrusive::pointer_traits:: + template rebind_pointer::type void_ptr; + typedef container_detail::basic_multiallocation_chain + multialloc_cached_counted; + typedef boost::container::container_detail:: + transform_multiallocation_chain + < multialloc_cached_counted, value_type> multiallocation_chain; + + static pointer allocate_one(Allocator &a) + { return a.allocate(1); } + + static void deallocate_one(Allocator &a, const pointer &p) + { a.deallocate(p, 1); } + + static void deallocate_individual(Allocator &a, multiallocation_chain &holder) + { + while(!holder.empty()){ + a.deallocate(holder.pop_front(), 1); + } + } + + struct allocate_individual_rollback + { + allocate_individual_rollback(Allocator &a, multiallocation_chain &chain) + : mr_a(a), mr_chain(chain) + {} + + ~allocate_individual_rollback() + { + allocator_version_wrapper::deallocate_individual(mr_a, mr_chain); + } + + Allocator &mr_a; + multiallocation_chain &mr_chain; + }; + + static multiallocation_chain allocate_individual(Allocator &a, size_type n) + { + multiallocation_chain m; + multiallocation_chain m_ret; + allocate_individual_rollback rollback(a, m); + while(n--){ + m.push_front(a.allocate(1)); + } + m.swap(m_ret); + return ::boost::move(m_ret); + } +}; + } //namespace stable_vector_detail #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -438,14 +501,14 @@ struct index_traits //! Exception safety: As stable_vector does not internally copy elements around, some //! operations provide stronger exception safety guarantees than in std::vector. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif class stable_vector { ///@cond - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; typedef typename boost::intrusive::pointer_traits :: template rebind_pointer::type void_ptr; @@ -487,125 +550,35 @@ class stable_vector integral_constant allocator_v2; typedef ::boost::container::container_detail::integral_constant ::value> alloc_version; + version::value> alloc_version; typedef typename allocator_traits_type:: template portable_rebind_alloc ::type node_allocator_type; - typedef typename stable_vector_detail:: - select_multiallocation_chain - < node_allocator_type - , alloc_version::value - >::type multiallocation_chain; + + typedef stable_vector_detail::allocator_version_wrapper allocator_version_wrapper_t; + typedef typename allocator_version_wrapper_t::multiallocation_chain multiallocation_chain; node_ptr allocate_one() - { return this->allocate_one(alloc_version()); } + { return allocator_version_wrapper_t::allocate_one(this->priv_node_alloc()); } - template - node_ptr allocate_one(AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { return this->priv_node_alloc().allocate(1); } - - template - node_ptr allocate_one(AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { return this->priv_node_alloc().allocate_one(); } - - void deallocate_one(node_ptr p) - { return this->deallocate_one(p, alloc_version()); } - - template - void deallocate_one(node_ptr p, AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { this->priv_node_alloc().deallocate(p, 1); } - - template - void deallocate_one(node_ptr p, AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { this->priv_node_alloc().deallocate_one(p); } + void deallocate_one(const node_ptr &p) + { allocator_version_wrapper_t::deallocate_one(this->priv_node_alloc(), p); } multiallocation_chain allocate_individual(typename allocator_traits_type::size_type n) - { return this->allocate_individual(n, alloc_version()); } - - struct allocate_individual_rollback - { - allocate_individual_rollback(stable_vector &sv, multiallocation_chain &chain) - : mr_sv(sv), mr_chain(chain) - {} - - ~allocate_individual_rollback() - { - if(!mr_chain.empty()){ - mr_sv.deallocate_individual(mr_chain); - } - } - - stable_vector &mr_sv; - multiallocation_chain &mr_chain; - }; - - template - multiallocation_chain allocate_individual - (typename allocator_traits_type::size_type n, AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { - multiallocation_chain m; - multiallocation_chain m_ret; - allocate_individual_rollback rollback(*this, m); - while(n--){ - m.push_front(this->allocate_one()); - } - m.swap(m_ret); - return ::boost::move(m_ret); - } - - template - multiallocation_chain allocate_individual - (typename allocator_traits_type::size_type n, AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { return this->priv_node_alloc().allocate_individual(n); } + { return allocator_version_wrapper_t::allocate_individual(this->priv_node_alloc(), n); } void deallocate_individual(multiallocation_chain &holder) - { this->deallocate_individual(holder, alloc_version()); } - - template - void deallocate_individual(multiallocation_chain & holder, AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { - while(!holder.empty()){ - this->deallocate_one(holder.pop_front()); - } - } - - template - void deallocate_individual(multiallocation_chain & holder, AllocatorVersion, - typename boost::container::container_detail::enable_if_c - - ::value>::type * = 0) - { this->priv_node_alloc().deallocate_individual(boost::move(holder)); } + { allocator_version_wrapper_t::deallocate_individual(this->priv_node_alloc(), holder); } friend class stable_vector_detail::clear_on_destroy; typedef stable_vector_detail::iterator < T - , typename allocator_traits::reference - , typename allocator_traits::pointer> iterator_impl; + , typename allocator_traits::reference + , typename allocator_traits::pointer> iterator_impl; typedef stable_vector_detail::iterator < T - , typename allocator_traits::const_reference - , typename allocator_traits::const_pointer> const_iterator_impl; + , typename allocator_traits::const_reference + , typename allocator_traits::const_pointer> const_iterator_impl; ///@endcond public: @@ -614,19 +587,19 @@ class stable_vector // types // ////////////////////////////////////////////// - typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef node_allocator_type stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; + typedef T value_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef node_allocator_type stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; + typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; ///@cond private: @@ -1863,46 +1836,46 @@ class stable_vector /// @endcond }; -template -bool operator==(const stable_vector& x,const stable_vector& y) +template +bool operator==(const stable_vector& x,const stable_vector& y) { return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); } -template -bool operator< (const stable_vector& x,const stable_vector& y) +template +bool operator< (const stable_vector& x,const stable_vector& y) { return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); } -template -bool operator!=(const stable_vector& x,const stable_vector& y) +template +bool operator!=(const stable_vector& x,const stable_vector& y) { return !(x==y); } -template -bool operator> (const stable_vector& x,const stable_vector& y) +template +bool operator> (const stable_vector& x,const stable_vector& y) { return y -bool operator>=(const stable_vector& x,const stable_vector& y) +template +bool operator>=(const stable_vector& x,const stable_vector& y) { return !(x -bool operator<=(const stable_vector& x,const stable_vector& y) +template +bool operator<=(const stable_vector& x,const stable_vector& y) { return !(x>y); } // specialized algorithms: -template -void swap(stable_vector& x,stable_vector& y) +template +void swap(stable_vector& x,stable_vector& y) { x.swap(y); } diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 4af2ae2..48f672a 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -84,14 +84,14 @@ namespace container_detail { // memory. The destructor assumes that the memory either is the internal buffer, // or else points to a block of memory that was allocated using _String_base's // allocator and whose size is this->m_storage. -template +template class basic_string_base { BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_string_base) - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; public: - typedef A allocator_type; + typedef Allocator allocator_type; //! The stored allocator type typedef allocator_type stored_allocator_type; typedef typename allocator_traits_type::pointer pointer; @@ -211,24 +211,24 @@ class basic_string_base }; struct members_holder - : public A + : public Allocator { members_holder() - : A() + : Allocator() {} template explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a) - : A(boost::forward(a)) + : Allocator(boost::forward(a)) {} repr_t m_repr; } members_; - const A &alloc() const + const Allocator &alloc() const { return members_; } - A &alloc() + Allocator &alloc() { return members_; } static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type); @@ -272,7 +272,7 @@ class basic_string_base typedef container_detail::integral_constant allocator_v1; typedef container_detail::integral_constant allocator_v2; typedef container_detail::integral_constant::value> alloc_version; + boost::container::container_detail::version::value> alloc_version; std::pair allocation_command(allocation_type command, @@ -521,22 +521,22 @@ class basic_string_base //! In this implementation, iterators are only invalidated by member functions that //! explicitly change the string's contents. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = std::allocator > #else -template +template #endif class basic_string - : private container_detail::basic_string_base + : private container_detail::basic_string_base { /// @cond private: - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; BOOST_COPYABLE_AND_MOVABLE(basic_string) - typedef container_detail::basic_string_base base_t; + typedef container_detail::basic_string_base base_t; static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars; protected: - // A helper class to use a char_traits as a function object. + // Allocator helper class to use a char_traits as a function object. template struct Eq_traits @@ -571,7 +571,7 @@ class basic_string public: //! The allocator type - typedef A allocator_type; + typedef Allocator allocator_type; //! The stored allocator type typedef allocator_type stored_allocator_type; //! The type of object, CharT, stored in the string @@ -932,7 +932,7 @@ class basic_string //! Complexity: Constant. //! //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT + stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT { return this->alloc(); } //! Effects: Returns a reference to the internal allocator. @@ -942,7 +942,7 @@ class basic_string //! Complexity: Constant. //! //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT + const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT { return this->alloc(); } //! Effects: Returns the number of the elements contained in the vector. @@ -1892,7 +1892,7 @@ class basic_string //! Requires: The program shall not alter any of the values stored in the character array. //! - //! Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()]. + //! Returns: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()]. //! //! Complexity: constant time. const CharT* c_str() const @@ -1900,7 +1900,7 @@ class basic_string //! Requires: The program shall not alter any of the values stored in the character array. //! - //! Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()]. + //! Returns: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()]. //! //! Complexity: constant time. const CharT* data() const @@ -2483,10 +2483,10 @@ wstring; /// @cond -template -const typename basic_string::size_type -basic_string::npos - = (typename basic_string::size_type) -1; +template +const typename basic_string::size_type +basic_string::npos + = (typename basic_string::size_type) -1; /// @endcond @@ -2495,273 +2495,212 @@ basic_string::npos // Operator+ -template -inline basic_string -operator+(const basic_string& x, - const basic_string& y) +template inline + basic_string + operator+(const basic_string& x + ,const basic_string& y) { - typedef basic_string str_t; + typedef basic_string str_t; typedef typename str_t::reserve_t reserve_t; reserve_t reserve; str_t result(reserve, x.size() + y.size(), x.get_stored_allocator()); result.append(x); result.append(y); - return boost::move(result); + return result; } -template inline -BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) - operator+( - BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx - , BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my) +template inline + basic_string operator+ + ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END mx + , BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END my) { mx += my; return boost::move(mx); } -template inline -BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) - operator+( - BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx - , const basic_string& y) +template inline + basic_string operator+ + ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END mx + , const basic_string& y) { mx += y; return boost::move(mx); } -template inline -BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) - operator+(const basic_string& x, - BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my) +template inline + basic_string operator+ + (const basic_string& x + ,BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END my) { - typedef typename basic_string::size_type size_type; - my.replace(size_type(0), size_type(0), x); + my.insert(my.begin(), x.begin(), x.end()); return boost::move(my); } -template -inline basic_string -operator+(const CharT* s, const basic_string& y) +template inline + basic_string operator+ + (const CharT* s, basic_string y) { - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - const typename str_t::size_type n = Traits::length(s); - str_t result(reserve, n + y.size()); - result.append(s, s + n); - result.append(y); - return boost::move(result); + y.insert(y.begin(), s, s + Traits::length(s)); + return y; } -template inline -BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) -operator+(const CharT* s, - BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my) +template inline + basic_string operator+ + (basic_string x, const CharT* s) { - typedef typename basic_string::size_type size_type; - return boost::move(my.replace(size_type(0), size_type(0), s)); + x += s; + return x; } -template -inline basic_string -operator+(CharT c, const basic_string& y) +template inline + basic_string operator+ + (CharT c, basic_string y) { - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - str_t result(reserve, 1 + y.size()); - result.push_back(c); - result.append(y); - return boost::move(result); + y.insert(y.begin(), c); + return y; } -template inline -BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) -operator+(CharT c, - BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my) +template inline + basic_string operator+ + (basic_string x, const CharT c) { - typedef typename basic_string::size_type size_type; - return boost::move(my.replace(size_type(0), size_type(0), &c, &c + 1)); -} - -template -inline basic_string -operator+(const basic_string& x, const CharT* s) -{ - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - const typename str_t::size_type n = Traits::length(s); - str_t result(reserve, x.size() + n, x.get_stored_allocator()); - result.append(x); - result.append(s, s + n); - return boost::move(result); -} - -template -BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) -operator+(BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx - , const CharT* s) -{ - mx += s; - return boost::move(mx); -} - -template -inline basic_string -operator+(const basic_string& x, const CharT c) -{ - typedef basic_string str_t; - typedef typename str_t::reserve_t reserve_t; - reserve_t reserve; - str_t result(reserve, x.size() + 1, x.get_stored_allocator()); - result.append(x); - result.push_back(c); - return boost::move(result); -} - -template -BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) -operator+( BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx - , const CharT c) -{ - mx += c; - return boost::move(mx); + x += c; + return x; } // Operator== and operator!= -template +template inline bool -operator==(const basic_string& x, - const basic_string& y) +operator==(const basic_string& x, + const basic_string& y) { return x.size() == y.size() && Traits::compare(x.data(), y.data(), x.size()) == 0; } -template +template inline bool -operator==(const CharT* s, const basic_string& y) +operator==(const CharT* s, const basic_string& y) { - typename basic_string::size_type n = Traits::length(s); + typename basic_string::size_type n = Traits::length(s); return n == y.size() && Traits::compare(s, y.data(), n) == 0; } -template +template inline bool -operator==(const basic_string& x, const CharT* s) +operator==(const basic_string& x, const CharT* s) { - typename basic_string::size_type n = Traits::length(s); + typename basic_string::size_type n = Traits::length(s); return x.size() == n && Traits::compare(x.data(), s, n) == 0; } -template +template inline bool -operator!=(const basic_string& x, - const basic_string& y) +operator!=(const basic_string& x, + const basic_string& y) { return !(x == y); } -template +template inline bool -operator!=(const CharT* s, const basic_string& y) +operator!=(const CharT* s, const basic_string& y) { return !(s == y); } -template +template inline bool -operator!=(const basic_string& x, const CharT* s) +operator!=(const basic_string& x, const CharT* s) { return !(x == s); } // Operator< (and also >, <=, and >=). -template +template inline bool -operator<(const basic_string& x, const basic_string& y) +operator<(const basic_string& x, const basic_string& y) { return x.compare(y) < 0; -// return basic_string +// return basic_string // ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0; } -template +template inline bool -operator<(const CharT* s, const basic_string& y) +operator<(const CharT* s, const basic_string& y) { return y.compare(s) > 0; -// basic_string::size_type n = Traits::length(s); -// return basic_string +// basic_string::size_type n = Traits::length(s); +// return basic_string // ::s_compare(s, s + n, y.begin(), y.end()) < 0; } -template +template inline bool -operator<(const basic_string& x, +operator<(const basic_string& x, const CharT* s) { return x.compare(s) < 0; -// basic_string::size_type n = Traits::length(s); -// return basic_string +// basic_string::size_type n = Traits::length(s); +// return basic_string // ::s_compare(x.begin(), x.end(), s, s + n) < 0; } -template +template inline bool -operator>(const basic_string& x, - const basic_string& y) { +operator>(const basic_string& x, + const basic_string& y) { return y < x; } -template +template inline bool -operator>(const CharT* s, const basic_string& y) { +operator>(const CharT* s, const basic_string& y) { return y < s; } -template +template inline bool -operator>(const basic_string& x, const CharT* s) +operator>(const basic_string& x, const CharT* s) { return s < x; } -template +template inline bool -operator<=(const basic_string& x, - const basic_string& y) +operator<=(const basic_string& x, + const basic_string& y) { return !(y < x); } -template +template inline bool -operator<=(const CharT* s, const basic_string& y) +operator<=(const CharT* s, const basic_string& y) { return !(y < s); } -template +template inline bool -operator<=(const basic_string& x, const CharT* s) +operator<=(const basic_string& x, const CharT* s) { return !(s < x); } -template +template inline bool -operator>=(const basic_string& x, - const basic_string& y) +operator>=(const basic_string& x, + const basic_string& y) { return !(x < y); } -template +template inline bool -operator>=(const CharT* s, const basic_string& y) +operator>=(const CharT* s, const basic_string& y) { return !(s < y); } -template +template inline bool -operator>=(const basic_string& x, const CharT* s) +operator>=(const basic_string& x, const CharT* s) { return !(x < s); } // Swap. -template -inline void swap(basic_string& x, basic_string& y) +template +inline void swap(basic_string& x, basic_string& y) { x.swap(y); } /// @cond @@ -2786,17 +2725,17 @@ string_fill(std::basic_ostream& os, } //namespace container_detail { /// @endcond -template +template std::basic_ostream& -operator<<(std::basic_ostream& os, const basic_string& s) +operator<<(std::basic_ostream& os, const basic_string& s) { typename std::basic_ostream::sentry sentry(os); bool ok = false; if (sentry) { ok = true; - typename basic_string::size_type n = s.size(); - typename basic_string::size_type pad_len = 0; + typename basic_string::size_type n = s.size(); + typename basic_string::size_type pad_len = 0; const bool left = (os.flags() & std::ios::left) != 0; const std::size_t w = os.width(0); std::basic_streambuf* buf = os.rdbuf(); @@ -2821,9 +2760,9 @@ operator<<(std::basic_ostream& os, const basic_string +template std::basic_istream& -operator>>(std::basic_istream& is, basic_string& s) +operator>>(std::basic_istream& is, basic_string& s) { typename std::basic_istream::sentry sentry(is); @@ -2868,11 +2807,11 @@ operator>>(std::basic_istream& is, basic_string& return is; } -template +template std::basic_istream& -getline(std::istream& is, basic_string& s,CharT delim) +getline(std::istream& is, basic_string& s,CharT delim) { - typename basic_string::size_type nread = 0; + typename basic_string::size_type nread = 0; typename std::basic_istream::sentry sentry(is, true); if (sentry) { std::basic_streambuf* buf = is.rdbuf(); @@ -2900,15 +2839,15 @@ getline(std::istream& is, basic_string& s,CharT delim) return is; } -template +template inline std::basic_istream& -getline(std::basic_istream& is, basic_string& s) +getline(std::basic_istream& is, basic_string& s) { return getline(is, s, '\n'); } -template -inline std::size_t hash_value(basic_string, A> const& v) +template +inline std::size_t hash_value(basic_string, Allocator> const& v) { return hash_range(v.begin(), v.end()); } @@ -2921,10 +2860,10 @@ namespace boost { /* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value; }; */ } diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index 91f4207..972db9e 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -207,11 +207,11 @@ class vector_iterator { return static_cast&>(*this) - right; } }; -template +template struct vector_value_traits { typedef T value_type; - typedef A allocator_type; + typedef Allocator allocator_type; static const bool trivial_dctr = boost::has_trivial_destructor::value; static const bool trivial_dctr_after_move = trivial_dctr; //::boost::has_trivial_destructor_after_move::value || trivial_dctr; @@ -229,37 +229,37 @@ struct vector_value_traits //to deallocate values already constructed typedef typename container_detail::if_c - ,container_detail::scoped_destructor_n + ,container_detail::null_scoped_destructor_n + ,container_detail::scoped_destructor_n >::type OldArrayDestructor; //This is the anti-exception array destructor //to destroy objects created with copy construction typedef typename container_detail::if_c - ,container_detail::scoped_destructor_n + ,container_detail::null_scoped_destructor_n + ,container_detail::scoped_destructor_n >::type ArrayDestructor; //This is the anti-exception array deallocator typedef typename container_detail::if_c - ,container_detail::scoped_array_deallocator + ,container_detail::null_scoped_array_deallocator + ,container_detail::scoped_array_deallocator >::type ArrayDeallocator; }; //!This struct deallocates and allocated memory -template +template struct vector_alloc_holder { - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::value_type value_type; - typedef vector_value_traits value_traits; + typedef vector_value_traits value_traits; //Constructor, does not throw vector_alloc_holder() - BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value) + BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value) : members_() {} @@ -279,7 +279,7 @@ struct vector_alloc_holder typedef container_detail::integral_constant allocator_v1; typedef container_detail::integral_constant allocator_v2; typedef container_detail::integral_constant::value> alloc_version; + boost::container::container_detail::version::value> alloc_version; std::pair allocation_command(allocation_type command, size_type limit_size, @@ -325,7 +325,7 @@ struct vector_alloc_holder } struct members_holder - : public A + : public Allocator { private: members_holder(const members_holder&); @@ -333,11 +333,11 @@ struct vector_alloc_holder public: template explicit members_holder(BOOST_FWD_REF(Alloc) alloc) - : A(boost::forward(alloc)), m_start(0), m_size(0), m_capacity(0) + : Allocator(boost::forward(alloc)), m_start(0), m_size(0), m_capacity(0) {} members_holder() - : A(), m_start(0), m_size(0), m_capacity(0) + : Allocator(), m_start(0), m_size(0), m_capacity(0) {} pointer m_start; @@ -352,10 +352,10 @@ struct vector_alloc_holder container_detail::do_swap(this->members_.m_capacity, x.members_.m_capacity); } - A &alloc() + Allocator &alloc() { return members_; } - const A &alloc() const + const Allocator &alloc() const { return members_; } protected: @@ -401,15 +401,15 @@ struct vector_alloc_holder //! boost::container::vector is similar to std::vector but it's compatible //! with shared memory and memory mapped files. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif -class vector : private container_detail::vector_alloc_holder +class vector : private container_detail::vector_alloc_holder { /// @cond - typedef container_detail::vector_alloc_holder base_t; - typedef allocator_traits allocator_traits_type; + typedef container_detail::vector_alloc_holder base_t; + typedef allocator_traits allocator_traits_type; /// @endcond public: ////////////////////////////////////////////// @@ -418,25 +418,25 @@ class vector : private container_detail::vector_alloc_holder // ////////////////////////////////////////////// - typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef allocator_type stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_iterator) iterator; - typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_const_iterator) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; + typedef T value_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef Allocator stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_iterator) iterator; + typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_const_iterator) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; /// @cond private: BOOST_COPYABLE_AND_MOVABLE(vector) typedef container_detail::advanced_insert_aux_int advanced_insert_aux_int_t; - typedef container_detail::vector_value_traits value_traits; + typedef container_detail::vector_value_traits value_traits; typedef typename base_t::allocator_v1 allocator_v1; typedef typename base_t::allocator_v2 allocator_v2; @@ -460,7 +460,7 @@ class vector : private container_detail::vector_alloc_holder //! //! Complexity: Constant. vector() - BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value) + BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value) : base_t() {} @@ -469,7 +469,7 @@ class vector : private container_detail::vector_alloc_holder //! Throws: Nothing //! //! Complexity: Constant. - explicit vector(const A& a) BOOST_CONTAINER_NOEXCEPT + explicit vector(const Allocator& a) BOOST_CONTAINER_NOEXCEPT : base_t(a) {} @@ -683,15 +683,6 @@ class vector : private container_detail::vector_alloc_holder allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT { return this->alloc(); } - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT - { return this->alloc(); } //! Effects: Returns a reference to the internal allocator. //! @@ -703,6 +694,16 @@ class vector : private container_detail::vector_alloc_holder stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT { return this->alloc(); } + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT + { return this->alloc(); } + ////////////////////////////////////////////// // // iterators @@ -856,7 +857,7 @@ class vector : private container_detail::vector_alloc_holder else{ const size_type n = new_size - this->size(); this->reserve(new_size); - container_detail::default_construct_aux_proxy proxy(this->alloc(), n); + container_detail::default_construct_aux_proxy proxy(this->alloc(), n); this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy); } } @@ -920,7 +921,7 @@ class vector : private container_detail::vector_alloc_holder else{ //We will reuse insert code, so create a dummy input iterator T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start)); - container_detail::advanced_insert_aux_proxy, T*> + container_detail::advanced_insert_aux_proxy, T*> proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it)); //Backwards (and possibly forward) expansion if(ret.second){ @@ -957,7 +958,7 @@ class vector : private container_detail::vector_alloc_holder //! //! Complexity: Linear to size(). void shrink_to_fit() - { priv_shrink_to_fit(alloc_version()); } + { this->priv_shrink_to_fit(alloc_version()); } ////////////////////////////////////////////// // @@ -1059,7 +1060,7 @@ class vector : private container_detail::vector_alloc_holder // ////////////////////////////////////////////// - //! Returns: A pointer such that [data(),data() + size()) is a valid range. + //! Returns: Allocator pointer such that [data(),data() + size()) is a valid range. //! For a non-empty vector, data() == &front(). //! //! Throws: Nothing. @@ -1068,7 +1069,7 @@ class vector : private container_detail::vector_alloc_holder T* data() BOOST_CONTAINER_NOEXCEPT { return container_detail::to_raw_pointer(this->members_.m_start); } - //! Returns: A pointer such that [data(),data() + size()) is a valid range. + //! Returns: Allocator pointer such that [data(),data() + size()) is a valid range. //! For a non-empty vector, data() == &front(). //! //! Throws: Nothing. @@ -1101,7 +1102,7 @@ class vector : private container_detail::vector_alloc_holder ++this->members_.m_size; } else{ - typedef container_detail::advanced_insert_aux_emplace type; + typedef container_detail::advanced_insert_aux_emplace type; type &&proxy = type(this->alloc(), ::boost::forward(args)...); this->priv_forward_range_insert(back_pos, 1, proxy); } @@ -1122,7 +1123,7 @@ class vector : private container_detail::vector_alloc_holder { //Just call more general insert(pos, size, value) and return iterator size_type pos_n = position - cbegin(); - typedef container_detail::advanced_insert_aux_emplace type; + typedef container_detail::advanced_insert_aux_emplace type; type &&proxy = type(this->alloc(), ::boost::forward(args)...); this->priv_forward_range_insert(position.get_ptr(), 1, proxy); return iterator(this->members_.m_start + pos_n); @@ -1143,7 +1144,7 @@ class vector : private container_detail::vector_alloc_holder } \ else{ \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ - proxy \ + proxy \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ this->priv_forward_range_insert(back_pos, 1, proxy); \ } \ @@ -1155,7 +1156,7 @@ class vector : private container_detail::vector_alloc_holder { \ size_type pos_n = pos - cbegin(); \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ - proxy \ + proxy \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ this->priv_forward_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1,proxy);\ return iterator(this->members_.m_start + pos_n); \ @@ -1263,7 +1264,7 @@ class vector : private container_detail::vector_alloc_holder { const size_type n_pos = pos - this->cbegin(); const size_type n = std::distance(first, last); - container_detail::advanced_insert_aux_proxy proxy(this->alloc(), first, last); + container_detail::advanced_insert_aux_proxy proxy(this->alloc(), first, last); this->priv_forward_range_insert(pos.get_ptr(), n, proxy); return this->begin() + n_pos; } @@ -1394,10 +1395,7 @@ class vector : private container_detail::vector_alloc_holder } } - template - void priv_shrink_to_fit( AllocVersion - , typename container_detail::enable_if_c< - container_detail::is_same::value >::type * = 0) + void priv_shrink_to_fit(allocator_v1) { if(this->members_.m_capacity){ if(!this->size()){ @@ -1412,7 +1410,7 @@ class vector : private container_detail::vector_alloc_holder if(real_cap < this->capacity()){ //We will reuse insert code, so create a dummy input iterator T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start)); - container_detail::advanced_insert_aux_proxy, T*> + container_detail::advanced_insert_aux_proxy, T*> proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it)); #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_alloc; @@ -1431,10 +1429,7 @@ class vector : private container_detail::vector_alloc_holder } } - template - void priv_shrink_to_fit(AllocVersion - , typename container_detail::enable_if_c< - !container_detail::is_same::value >::type * = 0) + void priv_shrink_to_fit(allocator_v2) { if(this->members_.m_capacity){ if(!size()){ @@ -1442,7 +1437,7 @@ class vector : private container_detail::vector_alloc_holder } else{ size_type received_size; - if(this->alloc().allocation_command + if(this->allocation_command ( shrink_in_place | nothrow_allocation , this->capacity(), this->size() , received_size, this->members_.m_start).first){ @@ -1535,6 +1530,10 @@ class vector : private container_detail::vector_alloc_holder //Loop for each insertion backwards, first moving the elements after the insertion point, //then inserting the element. while(insertions_left){ + if(do_skip){ + size_type n = *(--last_skip_it); + std::advance(last_value_it, -difference_type(n)); + } const size_type pos = static_cast(*(--last_position_it)); BOOST_ASSERT(pos <= old_size_pos); //If needed shift the range after the insertion point and the previous insertion point. @@ -1569,12 +1568,6 @@ class vector : private container_detail::vector_alloc_holder //Insert the new value in the already constructed range begin_ptr[pos + insertions_left - 1] = *(--last_value_it); } - if(do_skip){ - size_type n = *(--last_skip_it); - while(n--){ - --last_value_it; - } - } --insertions_left; hole_size = new_hole_size; next_pos = pos; @@ -1599,7 +1592,7 @@ class vector : private container_detail::vector_alloc_holder //| prefix | range | suffix |raw_mem ~ //|____________|_______|__________________|_____________~ // - //New situation in Case A (hole_size == 0): + //New situation in Case Allocator (hole_size == 0): // range is moved through move assignments // // first_pos last_pos limit_pos @@ -1643,7 +1636,7 @@ class vector : private container_detail::vector_alloc_holder T* const last_ptr = begin_ptr + last_pos; size_type hole_size = 0; - //Case A: + //Case Allocator: if((last_pos + shift_count) <= limit_pos){ //All move assigned boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count); @@ -2057,31 +2050,31 @@ class vector : private container_detail::vector_alloc_holder /// @endcond }; -template +template inline bool -operator==(const vector& x, const vector& y) +operator==(const vector& x, const vector& y) { //Check first size and each element if needed return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } -template +template inline bool -operator!=(const vector& x, const vector& y) +operator!=(const vector& x, const vector& y) { //Check first size and each element if needed return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin()); } -template +template inline bool -operator<(const vector& x, const vector& y) +operator<(const vector& x, const vector& y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } -template -inline void swap(vector& x, vector& y) +template +inline void swap(vector& x, vector& y) { x.swap(y); } }} @@ -2094,10 +2087,10 @@ namespace boost { //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor::value; + static const bool value = has_trivial_destructor::value; }; */ diff --git a/proj/to-do.txt b/proj/to-do.txt index b548cbc..f0c9890 100644 --- a/proj/to-do.txt +++ b/proj/to-do.txt @@ -2,6 +2,9 @@ ->Add an example with stateful allocators ->Add test to check convertible types in push_back/insert ->Add SCARY iterators. +->Align with C++11 [multi]map::insert(P &&p) overload. +->Unify all allocator version traits in one class (starting from stable_vector_detail::allocator_version_wrapper) + maybe in allocator_traits? Review allocator traits @@ -53,22 +56,10 @@ Add hash for containers Add std:: hashing support -Take out from class definition iterators in slist & list - Fix trivial destructor after move and other optimizing traits -Define typedefs exactly like the standard to generate better documentation. for implementation defined types: - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #define BOOST_CONTAINER_IMPLDEF(TYPE) TYPE - #else - #define BOOST_CONTAINER_IMPLDEF(TYPE) implementation_defined - #endif Mark previous() in slist/and forward_list as non-standard -Replace all insert_const_ref_type with BOOST_MOVE_CONVERSION_AWARE_CATCH_XXX - - - Function order: ----------type------------ diff --git a/test/string_test.cpp b/test/string_test.cpp index ce0e9c6..4b6ff25 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -85,7 +85,8 @@ struct string_literals { return "Suffix"; } static const char *LongString() { return "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } - + static char Char() + { return 'C'; } static void sprintf_number(char *buf, int number) { std::sprintf(buf, "%i", number); @@ -103,7 +104,8 @@ struct string_literals { return L"Suffix"; } static const wchar_t *LongString() { return L"LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } - + static wchar_t Char() + { return L'C'; } static void sprintf_number(wchar_t *buffer, unsigned int number) { //For compilers without wsprintf, print it backwards @@ -398,6 +400,22 @@ int string_test() if(!StringEqual()(bs4, ss4)){ return 1; } + + bs2 = string_literals::String(); + ss2 = string_literals::String(); + bs4 = string_literals::Char() + bs2; + ss4 = string_literals::Char() + ss2; + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals::String(); + ss2 = string_literals::String(); + bs4 = bs2 + string_literals::Char(); + ss4 = ss2 + string_literals::Char(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } } //When done, delete vector