mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 05:54:28 +02:00
Vector performance improvements: dispatching to memcpy when possible.
[SVN r83271]
This commit is contained in:
@@ -92,7 +92,6 @@ cpu_times time_it()
|
||||
rotateTime.resume();
|
||||
std::rotate(v.begin(), v.begin() + v.size()/2, v.end());
|
||||
rotateTime.stop();
|
||||
|
||||
destructionTime.resume();
|
||||
delete &v;
|
||||
}
|
||||
@@ -120,16 +119,16 @@ int main()
|
||||
try {
|
||||
std::cout << "N = " << N << "\n\n";
|
||||
|
||||
std::cout << "varray benchmark:\n";
|
||||
std::cout << "varray benchmark:" << std::endl;
|
||||
cpu_times time_varray = time_it<boost::container::varray<boost::container::varray<basic_type_t,N>,N > >();
|
||||
|
||||
std::cout << "boost::container::static_vector benchmark\n";
|
||||
std::cout << "boost::container::static_vector benchmark" << std::endl;
|
||||
cpu_times time_boost_static_vector = time_it<boost::container::static_vector<boost::container::static_vector<basic_type_t,N>,N > >();
|
||||
|
||||
std::cout << "boost::container::vector benchmark\n";
|
||||
std::cout << "boost::container::vector benchmark" << std::endl;
|
||||
cpu_times time_boost_vector = time_it<boost::container::vector<boost::container::vector<basic_type_t> > >();
|
||||
|
||||
std::cout << "std::vector benchmark\n";
|
||||
std::cout << "std::vector benchmark" << std::endl;
|
||||
cpu_times time_standard_vector = time_it<std::vector<std::vector<basic_type_t> > >();
|
||||
|
||||
std::cout << "varray/boost::container::vector total time comparison:";
|
||||
|
@@ -661,6 +661,7 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
[section:release_notes_boost_1_54_00 Boost 1.54 Release]
|
||||
|
||||
* Speed improvements in `vector` constructors/copy/move/swap, dispatching to memcpy when possible.
|
||||
* Support for `BOOST_NO_EXCEPTIONS` [@https://svn.boost.org/trac/boost/ticket/7227 #7227].
|
||||
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7921 #7921],
|
||||
[@https://svn.boost.org/trac/boost/ticket/7969 #7969],
|
||||
|
@@ -32,7 +32,10 @@
|
||||
#include <limits> //numeric_limits<>::max()
|
||||
#include <new> //placement new
|
||||
#include <memory> //std::allocator
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#endif
|
||||
|
||||
///@cond
|
||||
|
||||
|
@@ -830,11 +830,11 @@ class deque : protected deque_base<T, Allocator>
|
||||
if (len > size()) {
|
||||
FwdIt mid = first;
|
||||
std::advance(mid, this->size());
|
||||
boost::copy_or_move(first, mid, begin());
|
||||
boost::container::copy(first, mid, begin());
|
||||
this->insert(this->cend(), mid, last);
|
||||
}
|
||||
else{
|
||||
this->erase(boost::copy_or_move(first, last, this->begin()), cend());
|
||||
this->erase(boost::container::copy(first, last, this->begin()), cend());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1840,12 +1840,10 @@ class deque : protected deque_base<T, Allocator>
|
||||
++cur_node) {
|
||||
FwdIt mid = first;
|
||||
std::advance(mid, this->s_buffer_size());
|
||||
::boost::container::uninitialized_copy_or_move_alloc
|
||||
(this->alloc(), first, mid, *cur_node);
|
||||
::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
|
||||
first = mid;
|
||||
}
|
||||
::boost::container::uninitialized_copy_or_move_alloc
|
||||
(this->alloc(), first, last, this->members_.m_finish.m_first);
|
||||
::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
|
||||
|
@@ -65,13 +65,12 @@ struct insert_range_proxy
|
||||
|
||||
void uninitialized_copy_n_and_update(Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::uninitialized_copy_or_move_alloc_n_source
|
||||
(this->a_, this->first_, n, p);
|
||||
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(this->a_, this->first_, n, p);
|
||||
}
|
||||
|
||||
void copy_n_and_update(Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::copy_or_move_n_source(this->first_, n, p);
|
||||
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
|
||||
}
|
||||
|
||||
A &a_;
|
||||
|
@@ -157,7 +157,7 @@ class flat_tree
|
||||
void swap(Data &d)
|
||||
{
|
||||
value_compare& mycomp = *this, & othercomp = d;
|
||||
container_detail::do_swap(mycomp, othercomp);
|
||||
boost::container::swap_dispatch(mycomp, othercomp);
|
||||
this->m_vect.swap(d.m_vect);
|
||||
}
|
||||
|
||||
|
@@ -51,6 +51,12 @@
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME swap
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
@@ -19,17 +19,74 @@
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||
#include <boost/container/detail/memory_util.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <utility> //std::distance
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// swap
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace container_swap {
|
||||
|
||||
template<class T, bool IsClass = boost::is_class<T>::value >
|
||||
struct has_member_swap
|
||||
{
|
||||
static const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_swap<T, T &>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct has_member_swap<T, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
} //namespace container_swap {
|
||||
|
||||
template<class T> inline
|
||||
typename container_detail::enable_if_c
|
||||
<container_swap::has_member_swap<T>::value, void>::type
|
||||
swap_dispatch(T &left, T &right) //swap using member swap
|
||||
{
|
||||
left.swap(right); // may throw
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
typename container_detail::enable_if_c
|
||||
<!container_swap::has_member_swap<T>::value && boost::has_move_emulation_enabled<T>::value, void>::type
|
||||
swap_dispatch(T &left, T &right)
|
||||
{
|
||||
T temp(boost::move(left)); // may throw
|
||||
left = boost::move(right); // may throw
|
||||
right = boost::move(temp); // may throw
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
typename container_detail::enable_if_c
|
||||
<!container_swap::has_member_swap<T>::value && !boost::has_move_emulation_enabled<T>::value, void>::type
|
||||
swap_dispatch(T &left, T &right)
|
||||
{
|
||||
using std::swap;
|
||||
swap(left, right); // may throw
|
||||
}
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template <typename T>
|
||||
@@ -79,13 +136,6 @@ inline typename Pointer::element_type*
|
||||
to_raw_pointer(const Pointer &p)
|
||||
{ return boost::container::container_detail::to_raw_pointer(p.operator->()); }
|
||||
|
||||
//!To avoid ADL problems with swap
|
||||
template <class T>
|
||||
inline void do_swap(T& x, T& y)
|
||||
{
|
||||
using std::swap;
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
template<class AllocatorType>
|
||||
inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
|
||||
@@ -94,7 +144,7 @@ inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false
|
||||
|
||||
template<class AllocatorType>
|
||||
inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
|
||||
{ container_detail::do_swap(l, r); }
|
||||
{ boost::container::swap_dispatch(l, r); }
|
||||
|
||||
template<class AllocatorType>
|
||||
inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
|
||||
@@ -127,14 +177,121 @@ struct ct_rounded_size
|
||||
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
|
||||
};
|
||||
|
||||
template<class I>
|
||||
struct are_elements_contiguous
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct are_elements_contiguous<T*>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename I, typename O>
|
||||
struct are_contiguous_and_same
|
||||
{
|
||||
static const bool is_same_io =
|
||||
is_same< typename remove_const< typename ::std::iterator_traits<I>::value_type >::type
|
||||
, typename ::std::iterator_traits<O>::value_type
|
||||
>::value;
|
||||
static const bool value = is_same_io &&
|
||||
are_elements_contiguous<I>::value &&
|
||||
are_elements_contiguous<O>::value;
|
||||
};
|
||||
|
||||
template <typename I, typename O>
|
||||
struct is_memcpy_copy_assignable
|
||||
{
|
||||
static const bool value = are_contiguous_and_same<I, O>::value &&
|
||||
boost::has_trivial_assign< typename ::std::iterator_traits<I>::value_type >::value;
|
||||
};
|
||||
|
||||
template <typename I, typename O>
|
||||
struct is_memcpy_copy_constructible
|
||||
{
|
||||
static const bool value = are_contiguous_and_same<I, O>::value &&
|
||||
boost::has_trivial_copy< typename ::std::iterator_traits<I>::value_type >::value;
|
||||
};
|
||||
|
||||
template <typename I, typename O, typename R>
|
||||
struct enable_if_memcpy_copy_constructible
|
||||
: public enable_if_c<container_detail::is_memcpy_copy_constructible<I, O>::value, R>
|
||||
{};
|
||||
|
||||
template <typename I, typename O, typename R>
|
||||
struct disable_if_memcpy_copy_constructible
|
||||
: public enable_if_c<!container_detail::is_memcpy_copy_constructible<I, O>::value, R>
|
||||
{};
|
||||
|
||||
template <typename I, typename O, typename R>
|
||||
struct enable_if_memcpy_copy_assignable
|
||||
: public enable_if_c<container_detail::is_memcpy_copy_assignable<I, O>::value, R>
|
||||
{};
|
||||
|
||||
template <typename I, typename O, typename R>
|
||||
struct disable_if_memcpy_copy_assignable
|
||||
: public enable_if_c<!container_detail::is_memcpy_copy_assignable<I, O>::value, R>
|
||||
{};
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F memcpy(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type value_type;
|
||||
typename std::iterator_traits<I>::difference_type n = std::distance(f, l);
|
||||
::memcpy(container_detail::addressof(*r), container_detail::addressof(*f), sizeof(value_type)*n);
|
||||
std::advance(r, n);
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F memcpy_n(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type value_type;
|
||||
::memcpy(container_detail::addressof(*r), container_detail::addressof(*f), sizeof(value_type)*n);
|
||||
std::advance(r, n);
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
I memcpy_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type value_type;
|
||||
::memcpy(container_detail::addressof(*r), container_detail::addressof(*f), sizeof(value_type)*n);
|
||||
std::advance(f, n);
|
||||
return f;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
I memcpy_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type value_type;
|
||||
::memcpy(container_detail::addressof(*r), container_detail::addressof(*f), sizeof(value_type)*n);
|
||||
std::advance(f, n);
|
||||
std::advance(r, n);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_move_alloc
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! \code
|
||||
//! for (; f != l; ++r, ++f)
|
||||
@@ -146,7 +303,8 @@ template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_move_alloc(A &a, I f, I l, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_move_alloc(A &a, I f, I l, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -165,6 +323,14 @@ F uninitialized_move_alloc(A &a, I f, I l, F r)
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_move_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy(f, l, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_move_alloc_n
|
||||
@@ -182,7 +348,8 @@ template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_move_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_move_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -201,6 +368,14 @@ F uninitialized_move_alloc_n(A &a, I f, typename std::iterator_traits<I>::differ
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_move_alloc_n(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_move_alloc_n_source
|
||||
@@ -218,7 +393,8 @@ template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
I uninitialized_move_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_constructible<I, F, I>::type
|
||||
uninitialized_move_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -237,6 +413,14 @@ I uninitialized_move_alloc_n_source(A &a, I f, typename std::iterator_traits<I>:
|
||||
return f;
|
||||
}
|
||||
|
||||
template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::type
|
||||
uninitialized_move_alloc_n_source(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_alloc
|
||||
@@ -254,7 +438,8 @@ template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_copy_alloc(A &a, I f, I l, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_copy_alloc(A &a, I f, I l, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -273,6 +458,14 @@ F uninitialized_copy_alloc(A &a, I f, I l, F r)
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_copy_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy(f, l, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_alloc_n
|
||||
@@ -290,7 +483,8 @@ template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_copy_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_copy_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -309,6 +503,14 @@ F uninitialized_copy_alloc_n(A &a, I f, typename std::iterator_traits<I>::differ
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, F>::type
|
||||
uninitialized_copy_alloc_n(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_alloc_n_source
|
||||
@@ -326,7 +528,8 @@ template
|
||||
<typename A,
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
I uninitialized_copy_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_constructible<I, F, I>::type
|
||||
uninitialized_copy_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -345,131 +548,13 @@ I uninitialized_copy_alloc_n_source(A &a, I f, typename std::iterator_traits<I>:
|
||||
return f;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_alloc
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! \code
|
||||
//! for (; f != l; ++r, ++f)
|
||||
//! allocator_traits::construct(a, &*r, *f);
|
||||
//! \endcode
|
||||
//!
|
||||
//! <b>Returns</b>: r
|
||||
template
|
||||
<typename A,
|
||||
typename F, // F models ForwardIterator
|
||||
typename T>
|
||||
void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
|
||||
{
|
||||
F back = f;
|
||||
BOOST_TRY{
|
||||
while (f != l) {
|
||||
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*f), t);
|
||||
++f;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != l; ++back){
|
||||
allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_or_move_alloc
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
F uninitialized_copy_or_move_alloc
|
||||
(A &a, I f, I l, F r
|
||||
,typename boost::container::container_detail::enable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::container::uninitialized_move_alloc(a, f, l, r);
|
||||
}
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
F uninitialized_copy_or_move_alloc
|
||||
(A &a, I f, I l, F r
|
||||
,typename boost::container::container_detail::disable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_or_move_alloc_n
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
F uninitialized_copy_or_move_alloc_n
|
||||
(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::enable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::container::uninitialized_move_alloc_n(a, f, n, r);
|
||||
}
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
F uninitialized_copy_or_move_alloc_n
|
||||
(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::disable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::container::uninitialized_copy_alloc_n(a, f, n, r);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_or_move_alloc_n_source
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
I uninitialized_copy_or_move_alloc_n_source
|
||||
(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::enable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::container::uninitialized_move_alloc_n_source(a, f, n, r);
|
||||
}
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
I uninitialized_copy_or_move_alloc_n_source
|
||||
(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::disable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::container::uninitialized_copy_alloc_n_source(a, f, n, r);
|
||||
}
|
||||
typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::type
|
||||
uninitialized_copy_alloc_n_source(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -487,7 +572,7 @@ I uninitialized_copy_or_move_alloc_n_source
|
||||
template
|
||||
<typename A,
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
|
||||
inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -506,6 +591,41 @@ F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::difference_t
|
||||
return r;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_fill_alloc
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! \code
|
||||
//! for (; f != l; ++r, ++f)
|
||||
//! allocator_traits::construct(a, &*r, *f);
|
||||
//! \endcode
|
||||
//!
|
||||
//! <b>Returns</b>: r
|
||||
template
|
||||
<typename A,
|
||||
typename F, // F models ForwardIterator
|
||||
typename T>
|
||||
inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
|
||||
{
|
||||
F back = f;
|
||||
BOOST_TRY{
|
||||
while (f != l) {
|
||||
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*f), t);
|
||||
++f;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != l; ++back){
|
||||
allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -524,7 +644,7 @@ template
|
||||
<typename A,
|
||||
typename T,
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_fill_alloc_n(A &a, const T &v, typename allocator_traits<A>::difference_type n, F r)
|
||||
inline F uninitialized_fill_alloc_n(A &a, const T &v, typename allocator_traits<A>::difference_type n, F r)
|
||||
{
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
@@ -545,30 +665,15 @@ F uninitialized_fill_alloc_n(A &a, const T &v, typename allocator_traits<A>::dif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// copy_or_move
|
||||
// copy
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F copy_or_move(I f, I l, F r
|
||||
,typename boost::container::container_detail::enable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
while (f != l) {
|
||||
*r = ::boost::move(*f);
|
||||
++f; ++r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F copy_or_move(I f, I l, F r
|
||||
,typename boost::container::container_detail::disable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
copy(I f, I l, F r)
|
||||
{
|
||||
while (f != l) {
|
||||
*r = *f;
|
||||
@@ -577,32 +682,24 @@ inline F copy_or_move(I f, I l, F r
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
copy(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy(f, l, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// copy_or_move_n
|
||||
// copy_n
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F copy_or_move_n(I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::enable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
++f; ++r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F copy_or_move_n(I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::disable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
copy_n(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = *f;
|
||||
@@ -611,32 +708,24 @@ inline F copy_or_move_n(I f, typename std::iterator_traits<I>::difference_type n
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
copy_n(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// copy_or_move_n_source
|
||||
// copy_n_source
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::enable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
++f; ++r;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r
|
||||
,typename boost::container::container_detail::disable_if
|
||||
< boost::move_detail::is_move_iterator<I> >::type* = 0)
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
copy_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = *f;
|
||||
@@ -645,6 +734,39 @@ inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference
|
||||
return f;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
copy_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// copy_n_source_dest
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
copy_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = *f;
|
||||
++f; ++r;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
copy_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n_source_dest(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move
|
||||
@@ -654,7 +776,8 @@ inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F move(I f, I l, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
move(I f, I l, F r)
|
||||
{
|
||||
while (f != l) {
|
||||
*r = ::boost::move(*f);
|
||||
@@ -663,6 +786,12 @@ inline F move(I f, I l, F r)
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
move(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy(f, l, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -673,7 +802,8 @@ inline F move(I f, I l, F r)
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F move_n(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
move_n(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
@@ -682,6 +812,12 @@ inline F move_n(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
return r;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, F>::type
|
||||
move_n(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -690,9 +826,10 @@ inline F move_n(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline I move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
<typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
@@ -701,9 +838,42 @@ inline I move_n_source(I f, typename std::iterator_traits<I>::difference_type n,
|
||||
return f;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n_source(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// destroy_n
|
||||
// move_n_source_dest
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
move_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = ::boost::move(*f);
|
||||
++f; ++r;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
template
|
||||
<typename I // I models InputIterator
|
||||
,typename F> // F models ForwardIterator
|
||||
inline typename container_detail::enable_if_memcpy_copy_assignable<I, F, I>::type
|
||||
move_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r) BOOST_CONTAINER_NOEXCEPT
|
||||
{ return container_detail::memcpy_n_source_dest(f, n, r); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// destroy_n
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -734,23 +904,170 @@ inline void destroy_alloc_n(A &, I, typename std::iterator_traits<I>::difference
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename F // I models ForwardIterator
|
||||
<std::size_t MaxTmpBytes
|
||||
,typename A
|
||||
,typename F // F models ForwardIterator
|
||||
,typename G // G models ForwardIterator
|
||||
>
|
||||
void deep_swap_alloc_n(A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
|
||||
, G large_range_f, typename allocator_traits<A>::size_type n_j)
|
||||
inline typename container_detail::disable_if_memcpy_copy_assignable<F, G, void>::type
|
||||
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
|
||||
, G large_range_f, typename allocator_traits<A>::size_type n_j)
|
||||
{
|
||||
typename allocator_traits<A>::size_type n = 0;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){
|
||||
//boost::swap(*first_sm, *first_la); // may throw
|
||||
value_type temp(boost::move(*short_range_f)); // may throw
|
||||
*short_range_f = boost::move(*large_range_f); // may throw
|
||||
*large_range_f = boost::move(temp); // may throw
|
||||
boost::container::swap_dispatch(*short_range_f, *large_range_f);
|
||||
}
|
||||
boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
|
||||
boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
|
||||
}
|
||||
|
||||
static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes
|
||||
|
||||
template
|
||||
<std::size_t MaxTmpBytes
|
||||
,typename A
|
||||
,typename F // F models ForwardIterator
|
||||
,typename G // G models ForwardIterator
|
||||
>
|
||||
inline typename container_detail::enable_if_c
|
||||
< container_detail::is_memcpy_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
|
||||
, void>::type
|
||||
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
|
||||
, G large_range_f, typename allocator_traits<A>::size_type n_j)
|
||||
{
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::aligned_storage
|
||||
<MaxTmpBytes, container_detail::alignment_of<value_type>::value>::type storage_type;
|
||||
storage_type storage;
|
||||
|
||||
const std::size_t n_i_bytes = sizeof(value_type)*n_i;
|
||||
unsigned char *const large_ptr = static_cast<unsigned char*>(static_cast<void*>(container_detail::addressof(*large_range_f)));
|
||||
unsigned char *const short_ptr = static_cast<unsigned char*>(static_cast<void*>(container_detail::addressof(*short_range_f)));
|
||||
unsigned char *const stora_ptr = static_cast<unsigned char*>(static_cast<void*>(container_detail::addressof(storage)));
|
||||
::memcpy(stora_ptr, large_ptr, n_i_bytes);
|
||||
::memcpy(large_ptr, short_ptr, n_i_bytes);
|
||||
::memcpy(short_ptr, stora_ptr, n_i_bytes);
|
||||
std::advance(large_range_f, n_i);
|
||||
std::advance(short_range_f, n_i);
|
||||
boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
|
||||
boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
|
||||
}
|
||||
|
||||
template
|
||||
<std::size_t MaxTmpBytes
|
||||
,typename A
|
||||
,typename F // F models ForwardIterator
|
||||
,typename G // G models ForwardIterator
|
||||
>
|
||||
inline typename container_detail::enable_if_c
|
||||
< container_detail::is_memcpy_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
|
||||
, void>::type
|
||||
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
|
||||
, G large_range_f, typename allocator_traits<A>::size_type n_j)
|
||||
{
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::aligned_storage
|
||||
<DeepSwapAllocNMaxStorage, container_detail::alignment_of<value_type>::value>::type storage_type;
|
||||
storage_type storage;
|
||||
const std::size_t sizeof_storage = sizeof(storage);
|
||||
|
||||
std::size_t n_i_bytes = sizeof(value_type)*n_i;
|
||||
char *large_ptr = static_cast<char*>(static_cast<void*>(container_detail::addressof(*large_range_f)));
|
||||
char *short_ptr = static_cast<char*>(static_cast<void*>(container_detail::addressof(*short_range_f)));
|
||||
char *stora_ptr = static_cast<char*>(static_cast<void*>(container_detail::addressof(storage)));
|
||||
|
||||
std::size_t szt_times = n_i_bytes/sizeof_storage;
|
||||
const std::size_t szt_rem = n_i_bytes%sizeof_storage;
|
||||
|
||||
//Loop unrolling using Duff's device, as it seems it helps on some architectures
|
||||
const std::size_t Unroll = 4;
|
||||
std::size_t n = (szt_times + (Unroll-1))/Unroll;
|
||||
const std::size_t branch_number = ((!szt_times)*Unroll) + (szt_times % Unroll);
|
||||
switch(branch_number){
|
||||
case 4:
|
||||
break;
|
||||
case 0: do{
|
||||
::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
||||
::memcpy(large_ptr, short_ptr, sizeof_storage);
|
||||
::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
||||
large_ptr += sizeof_storage;
|
||||
short_ptr += sizeof_storage;
|
||||
case 3:
|
||||
::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
||||
::memcpy(large_ptr, short_ptr, sizeof_storage);
|
||||
::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
||||
large_ptr += sizeof_storage;
|
||||
short_ptr += sizeof_storage;
|
||||
case 2:
|
||||
::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
||||
::memcpy(large_ptr, short_ptr, sizeof_storage);
|
||||
::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
||||
large_ptr += sizeof_storage;
|
||||
short_ptr += sizeof_storage;
|
||||
case 1:
|
||||
::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
||||
::memcpy(large_ptr, short_ptr, sizeof_storage);
|
||||
::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
||||
large_ptr += sizeof_storage;
|
||||
short_ptr += sizeof_storage;
|
||||
} while(--n);
|
||||
}
|
||||
::memcpy(stora_ptr, large_ptr, szt_rem);
|
||||
::memcpy(large_ptr, short_ptr, szt_rem);
|
||||
::memcpy(short_ptr, stora_ptr, szt_rem);
|
||||
std::advance(large_range_f, n_i);
|
||||
std::advance(short_range_f, n_i);
|
||||
boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
|
||||
boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// copy_assign_range_alloc_n
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // F models InputIterator
|
||||
,typename O // G models OutputIterator
|
||||
>
|
||||
void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i
|
||||
, O out_start, typename allocator_traits<A>::size_type n_o )
|
||||
{
|
||||
if (n_o < n_i){
|
||||
inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw
|
||||
boost::container::uninitialized_copy_alloc_n(a, inp_start, n_i - n_o, out_start);// may throw
|
||||
}
|
||||
else{
|
||||
out_start = boost::container::copy_n(inp_start, n_i, out_start); // may throw
|
||||
boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_assign_range_alloc_n
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<typename A
|
||||
,typename I // F models InputIterator
|
||||
,typename O // G models OutputIterator
|
||||
>
|
||||
void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i
|
||||
, O out_start, typename allocator_traits<A>::size_type n_o )
|
||||
{
|
||||
if (n_o < n_i){
|
||||
inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw
|
||||
boost::container::uninitialized_move_alloc_n(a, inp_start, n_i - n_o, out_start); // may throw
|
||||
}
|
||||
else{
|
||||
out_start = boost::container::move_n(inp_start, n_i, out_start); // may throw
|
||||
boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
|
||||
}
|
||||
uninitialized_move_alloc_n(a, large_range_f, n_j - n, short_range_f); // may throw
|
||||
destroy_alloc_n(a, large_range_f, n_j - n);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
|
@@ -584,6 +584,7 @@ class scoped_allocator_adaptor_base
|
||||
|
||||
typedef OuterAlloc outer_allocator_type;
|
||||
typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef boost::integral_constant<
|
||||
bool,
|
||||
outer_traits_type::propagate_on_container_copy_assignment::value ||
|
||||
@@ -723,6 +724,7 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
|
||||
( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
|
||||
, BOOST_CONTAINER_PP_IDENTITY, nat) \
|
||||
> inner_allocator_type; \
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type; \
|
||||
typedef boost::integral_constant< \
|
||||
bool, \
|
||||
outer_traits_type::propagate_on_container_copy_assignment::value || \
|
||||
@@ -860,6 +862,7 @@ class scoped_allocator_adaptor_base
|
||||
typedef OuterAlloc outer_allocator_type;
|
||||
typedef allocator_traits<OuterAlloc> outer_traits_type;
|
||||
typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef typename outer_traits_type::
|
||||
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
|
||||
typedef typename outer_traits_type::
|
||||
@@ -1029,6 +1032,7 @@ class scoped_allocator_adaptor
|
||||
//! Type: `scoped_allocator_adaptor<OuterAlloc>` if `sizeof...(InnerAllocs)` is zero; otherwise,
|
||||
//! `scoped_allocator_adaptor<InnerAllocs...>`.
|
||||
typedef typename base_type::inner_allocator_type inner_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef typename outer_traits_type::value_type value_type;
|
||||
typedef typename outer_traits_type::size_type size_type;
|
||||
typedef typename outer_traits_type::difference_type difference_type;
|
||||
@@ -1220,7 +1224,7 @@ class scoped_allocator_adaptor
|
||||
return scoped_allocator_adaptor
|
||||
(internal_type_t()
|
||||
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
|
||||
,outer_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
||||
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
||||
);
|
||||
}
|
||||
/// @cond
|
||||
|
@@ -1714,7 +1714,7 @@ class stable_vector
|
||||
|
||||
void priv_swap_members(stable_vector &x)
|
||||
{
|
||||
container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
|
||||
boost::container::swap_dispatch(this->internal_data.pool_size, x.internal_data.pool_size);
|
||||
index_traits_type::readjust_end_node(this->index, this->internal_data.end_node);
|
||||
index_traits_type::readjust_end_node(x.index, x.internal_data.end_node);
|
||||
}
|
||||
|
@@ -426,7 +426,7 @@ class basic_string_base
|
||||
{
|
||||
if(this->is_short()){
|
||||
if(other.is_short()){
|
||||
container_detail::do_swap(this->members_.m_repr, other.members_.m_repr);
|
||||
boost::container::swap_dispatch(this->members_.m_repr, other.members_.m_repr);
|
||||
}
|
||||
else{
|
||||
short_t short_backup(this->members_.m_repr.short_repr());
|
||||
@@ -447,7 +447,7 @@ class basic_string_base
|
||||
this->members_.m_repr.short_repr() = short_backup;
|
||||
}
|
||||
else{
|
||||
container_detail::do_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
|
||||
boost::container::swap_dispatch(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -410,9 +410,9 @@ struct vector_alloc_holder
|
||||
|
||||
void swap(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
container_detail::do_swap(this->m_start, x.m_start);
|
||||
container_detail::do_swap(this->m_size, x.m_size);
|
||||
container_detail::do_swap(this->m_capacity, x.m_capacity);
|
||||
boost::container::swap_dispatch(this->m_start, x.m_start);
|
||||
boost::container::swap_dispatch(this->m_size, x.m_size);
|
||||
boost::container::swap_dispatch(this->m_capacity, x.m_capacity);
|
||||
}
|
||||
|
||||
void move_from_empty(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
|
||||
@@ -430,16 +430,6 @@ struct vector_alloc_holder
|
||||
const Allocator &alloc() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return *this; }
|
||||
|
||||
void deallocate() BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
if(this->m_capacity){
|
||||
this->alloc().deallocate(this->m_start, this->m_capacity);
|
||||
this->m_start = pointer();
|
||||
this->m_size = 0;
|
||||
this->m_capacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const pointer &start() const BOOST_CONTAINER_NOEXCEPT { return m_start; }
|
||||
const size_type &capacity() const BOOST_CONTAINER_NOEXCEPT { return m_capacity; }
|
||||
void start(const pointer &p) BOOST_CONTAINER_NOEXCEPT { m_start = p; }
|
||||
@@ -497,7 +487,7 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
||||
, m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
{
|
||||
::boost::container::uninitialized_move_alloc_n
|
||||
(this->alloc(), container_detail::to_raw_pointer(holder.start()), m_size, this->start());
|
||||
(this->alloc(), container_detail::to_raw_pointer(holder.start()), m_size, container_detail::to_raw_pointer(this->start()));
|
||||
}
|
||||
|
||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
||||
@@ -509,7 +499,7 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
||||
const size_type n = holder.m_size;
|
||||
this->first_allocation(n);
|
||||
::boost::container::uninitialized_move_alloc_n
|
||||
(this->alloc(), container_detail::to_raw_pointer(holder.start()), n, this->start());
|
||||
(this->alloc(), container_detail::to_raw_pointer(holder.start()), n, container_detail::to_raw_pointer(this->start()));
|
||||
}
|
||||
|
||||
void first_allocation(size_type cap)
|
||||
@@ -551,9 +541,6 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
||||
const Allocator &alloc() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return *this; }
|
||||
|
||||
void deallocate() BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
pointer start() const BOOST_CONTAINER_NOEXCEPT { return Allocator::internal_storage(); }
|
||||
size_type capacity() const BOOST_CONTAINER_NOEXCEPT { return Allocator::internal_capacity; }
|
||||
size_type m_size;
|
||||
@@ -563,16 +550,17 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
|
||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
||||
void priv_swap_members_impl(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
|
||||
{
|
||||
const std::size_t MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity;
|
||||
value_type *const first_this = container_detail::to_raw_pointer(this->start());
|
||||
value_type *const first_x = container_detail::to_raw_pointer(x.start());
|
||||
|
||||
if(this->m_size < x.m_size){
|
||||
deep_swap_alloc_n(this->alloc(), first_this, this->m_size, first_x, x.m_size);
|
||||
boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_this, this->m_size, first_x, x.m_size);
|
||||
}
|
||||
else{
|
||||
deep_swap_alloc_n(this->alloc(), first_x, x.m_size, first_this, this->m_size);
|
||||
boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_x, x.m_size, first_this, this->m_size);
|
||||
}
|
||||
container_detail::do_swap(this->m_size, x.m_size);
|
||||
boost::container::swap_dispatch(this->m_size, x.m_size);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -743,7 +731,7 @@ class vector
|
||||
vector(const vector &x)
|
||||
: m_holder(allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc()), x.size())
|
||||
{
|
||||
::boost::container::uninitialized_copy_or_move_alloc_n_source
|
||||
::boost::container::uninitialized_copy_alloc_n
|
||||
( this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())
|
||||
, x.size(), container_detail::to_raw_pointer(this->m_holder.start()));
|
||||
}
|
||||
@@ -784,7 +772,7 @@ class vector
|
||||
vector(const vector &x, const allocator_type &a)
|
||||
: m_holder(a, x.size())
|
||||
{
|
||||
::boost::container::uninitialized_copy_or_move_alloc_n_source
|
||||
::boost::container::uninitialized_copy_alloc_n_source
|
||||
( this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())
|
||||
, x.size(), container_detail::to_raw_pointer(this->m_holder.start()));
|
||||
}
|
||||
@@ -820,7 +808,8 @@ class vector
|
||||
//! <b>Complexity</b>: Linear to the number of elements.
|
||||
~vector() BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
destroy_alloc_n(this->get_stored_allocator(), container_detail::to_raw_pointer(this->m_holder.start()), this->m_holder.m_size);
|
||||
boost::container::destroy_alloc_n
|
||||
(this->get_stored_allocator(), container_detail::to_raw_pointer(this->m_holder.start()), this->m_holder.m_size);
|
||||
//vector_alloc_holder deallocates the data
|
||||
}
|
||||
|
||||
@@ -893,7 +882,8 @@ class vector
|
||||
{
|
||||
//Overwrite all elements we can from [first, last)
|
||||
iterator cur = this->begin();
|
||||
for ( ; first != last && cur != end(); ++cur, ++first){
|
||||
const iterator end_it = this->end();
|
||||
for ( ; first != last && cur != end_it; ++cur, ++first){
|
||||
*cur = *first;
|
||||
}
|
||||
|
||||
@@ -1507,7 +1497,7 @@ class vector
|
||||
,container_detail::to_raw_pointer(vector_iterator_get_ptr(first))
|
||||
));
|
||||
const size_type destroyed = (end_pos - ptr);
|
||||
destroy_alloc_n(this->get_stored_allocator(), ptr, destroyed);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), ptr, destroyed);
|
||||
this->m_holder.m_size -= destroyed;
|
||||
}
|
||||
return iterator(vector_iterator_get_ptr(first));
|
||||
@@ -1607,16 +1597,7 @@ class vector
|
||||
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
||||
const size_type this_sz = m_holder.m_size;
|
||||
const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
|
||||
if (this_sz < other_sz){
|
||||
move_n(other_start, this_sz, this_start); // may throw
|
||||
uninitialized_move_alloc_n( this->m_holder.alloc(), other_start + this_sz
|
||||
, other_sz - this_sz, this_start + this_sz); // may throw
|
||||
}
|
||||
else
|
||||
{
|
||||
move_n(other_start, other_sz, this_start);
|
||||
destroy_alloc_n(this->m_holder.alloc(), this_start + other_sz, this_sz - other_sz);
|
||||
}
|
||||
boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
|
||||
this->m_holder.m_size = other_sz;
|
||||
}
|
||||
|
||||
@@ -1658,16 +1639,7 @@ class vector
|
||||
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
||||
const size_type this_sz = m_holder.m_size;
|
||||
const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
|
||||
if (this_sz < other_sz){
|
||||
copy_or_move_n(other_start, this_sz, this_start); // may throw
|
||||
uninitialized_copy_or_move_alloc_n( this->m_holder.alloc(), other_start + this_sz
|
||||
, other_sz - this_sz, this_start + this_sz); // may throw
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_or_move_n(other_start, other_sz, this_start);
|
||||
destroy_alloc_n(this->m_holder.alloc(), this_start + other_sz, this_sz - other_sz);
|
||||
}
|
||||
boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
|
||||
this->m_holder.m_size = other_sz;
|
||||
}
|
||||
|
||||
@@ -1707,7 +1679,7 @@ class vector
|
||||
const size_type sz = m_holder.m_size;
|
||||
::boost::container::uninitialized_move_alloc_n_source
|
||||
( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(p) );
|
||||
destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
|
||||
boost::container::destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
|
||||
this->m_holder.start(p);
|
||||
this->m_holder.capacity(new_cap);
|
||||
}
|
||||
@@ -1741,7 +1713,7 @@ class vector
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
++this->num_expand_bwd;
|
||||
#endif
|
||||
this->priv_range_insert_expand_backwards
|
||||
this->priv_forward_range_insert_expand_backwards
|
||||
( container_detail::to_raw_pointer(ret.first)
|
||||
, real_cap
|
||||
, container_detail::to_raw_pointer(this->m_holder.start())
|
||||
@@ -1758,7 +1730,7 @@ class vector
|
||||
const size_type sz = m_holder.m_size;
|
||||
::boost::container::uninitialized_move_alloc_n_source
|
||||
( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(ret.first) );
|
||||
destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
|
||||
boost::container::destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
|
||||
this->m_holder.start(ret.first);
|
||||
this->m_holder.capacity(real_cap);
|
||||
}
|
||||
@@ -1783,13 +1755,14 @@ class vector
|
||||
void priv_destroy_last_n(size_type n) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
T* const end_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
|
||||
destroy_alloc_n(this->get_stored_allocator(), end_pos-n, n);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), end_pos-n, n);
|
||||
this->m_holder.m_size -= n;
|
||||
}
|
||||
|
||||
void priv_destroy_all() BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
destroy_alloc_n(this->get_stored_allocator(), container_detail::to_raw_pointer(this->m_holder.start()), this->m_holder.m_size);
|
||||
boost::container::destroy_alloc_n
|
||||
(this->get_stored_allocator(), container_detail::to_raw_pointer(this->m_holder.start()), this->m_holder.m_size);
|
||||
this->m_holder.m_size = 0;
|
||||
}
|
||||
|
||||
@@ -1833,7 +1806,7 @@ class vector
|
||||
}
|
||||
}
|
||||
|
||||
void priv_shrink_to_fit(allocator_v0)
|
||||
void priv_shrink_to_fit(allocator_v0) BOOST_CONTAINER_NOEXCEPT
|
||||
{}
|
||||
|
||||
void priv_shrink_to_fit(allocator_v1)
|
||||
@@ -1842,7 +1815,9 @@ class vector
|
||||
if(cp){
|
||||
const size_type sz = this->size();
|
||||
if(!sz){
|
||||
this->m_holder.deallocate();
|
||||
this->m_holder.alloc().deallocate(this->m_holder.m_start, cp);
|
||||
this->m_holder.m_start = pointer();
|
||||
this->m_holder.m_capacity = 0;
|
||||
}
|
||||
else if(sz < cp){
|
||||
//Allocate a new buffer.
|
||||
@@ -1854,7 +1829,7 @@ class vector
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
++this->num_alloc;
|
||||
#endif
|
||||
this->priv_range_insert_new_allocation
|
||||
this->priv_forward_range_insert_new_allocation
|
||||
( container_detail::to_raw_pointer(p)
|
||||
, sz
|
||||
, container_detail::to_raw_pointer(this->m_holder.start())
|
||||
@@ -1864,18 +1839,21 @@ class vector
|
||||
}
|
||||
}
|
||||
|
||||
void priv_shrink_to_fit(allocator_v2)
|
||||
void priv_shrink_to_fit(allocator_v2) BOOST_CONTAINER_NOEXCEPT
|
||||
{
|
||||
if(this->m_holder.capacity()){
|
||||
if(!size()){
|
||||
this->m_holder.deallocate();
|
||||
const size_type cp = this->m_holder.capacity();
|
||||
if(cp){
|
||||
const size_type sz = this->size();
|
||||
if(!sz){
|
||||
this->m_holder.alloc().deallocate(this->m_holder.m_start, cp);
|
||||
this->m_holder.m_start = pointer();
|
||||
this->m_holder.m_capacity = 0;
|
||||
}
|
||||
else{
|
||||
size_type received_size;
|
||||
if(this->m_holder.allocation_command
|
||||
( shrink_in_place | nothrow_allocation
|
||||
, this->capacity(), this->size()
|
||||
, received_size, this->m_holder.start()).first){
|
||||
, cp, sz, received_size, this->m_holder.start()).first){
|
||||
this->m_holder.capacity(received_size);
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
++this->num_shrink;
|
||||
@@ -1893,38 +1871,6 @@ class vector
|
||||
return iterator(pos);
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||
|
||||
if (n > remaining){
|
||||
//This will trigger an error
|
||||
throw_bad_alloc();
|
||||
}
|
||||
const size_type n_pos = pos - this->m_holder.start();
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert_at_end
|
||||
(const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||
|
||||
if (n > remaining){
|
||||
//This will trigger an error
|
||||
throw_bad_alloc();
|
||||
}
|
||||
this->priv_range_insert_at_end_expand_forward(n, insert_range_proxy);
|
||||
return this->end();
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert_no_capacity
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
||||
@@ -1938,44 +1884,19 @@ class vector
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
++this->num_alloc;
|
||||
#endif
|
||||
this->priv_range_insert_new_allocation
|
||||
this->priv_forward_range_insert_new_allocation
|
||||
( new_buf, new_cap, raw_pos, n, insert_range_proxy);
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
|
||||
if (n <= remaining){
|
||||
const size_type n_pos = pos - this->m_holder.start();
|
||||
this->priv_range_insert_expand_forward
|
||||
(raw_pos, n, insert_range_proxy);
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
}
|
||||
else{
|
||||
return this->priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version());
|
||||
}
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert_at_end
|
||||
(const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
||||
{
|
||||
return this->priv_forward_range_insert(vector_iterator_get_ptr(this->cend()), n, insert_range_proxy, allocator_v1());
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert_no_capacity
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
const size_type n_pos = pos - this->m_holder.start();
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start());
|
||||
|
||||
size_type real_cap = 0;
|
||||
//There is not enough memory, allocate a new
|
||||
@@ -1993,14 +1914,14 @@ class vector
|
||||
#endif
|
||||
this->m_holder.capacity(real_cap);
|
||||
//Expand forward
|
||||
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||
this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||
}
|
||||
//Backwards (and possibly forward) expansion
|
||||
else{
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
++this->num_expand_bwd;
|
||||
#endif
|
||||
this->priv_range_insert_expand_backwards
|
||||
this->priv_forward_range_insert_expand_backwards
|
||||
( container_detail::to_raw_pointer(ret.first)
|
||||
, real_cap, raw_pos, n, insert_range_proxy);
|
||||
}
|
||||
@@ -2010,7 +1931,7 @@ class vector
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
++this->num_alloc;
|
||||
#endif
|
||||
this->priv_range_insert_new_allocation
|
||||
this->priv_forward_range_insert_new_allocation
|
||||
( container_detail::to_raw_pointer(ret.first)
|
||||
, real_cap, raw_pos, n, insert_range_proxy);
|
||||
}
|
||||
@@ -2018,6 +1939,42 @@ class vector
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||
|
||||
if (n > remaining){
|
||||
//This will trigger an error
|
||||
throw_bad_alloc();
|
||||
}
|
||||
const size_type n_pos = pos - this->m_holder.start();
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
|
||||
if (n <= remaining){
|
||||
const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start());
|
||||
this->priv_forward_range_insert_expand_forward
|
||||
(raw_pos, n, insert_range_proxy);
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
}
|
||||
else{
|
||||
return this->priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version());
|
||||
}
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
|
||||
@@ -2031,13 +1988,35 @@ class vector
|
||||
}
|
||||
else{
|
||||
//Expand forward
|
||||
const size_type n_pos = pos - this->m_holder.start();
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||
const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start());
|
||||
this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert_at_end
|
||||
(const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
|
||||
|
||||
if (n > remaining){
|
||||
//This will trigger an error
|
||||
throw_bad_alloc();
|
||||
}
|
||||
this->priv_forward_range_insert_at_end_expand_forward(n, insert_range_proxy);
|
||||
return this->end();
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert_at_end
|
||||
(const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
|
||||
{
|
||||
return this->priv_forward_range_insert(vector_iterator_get_ptr(this->cend()), n, insert_range_proxy, allocator_v1());
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
iterator priv_forward_range_insert_at_end
|
||||
(const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
|
||||
@@ -2196,7 +2175,7 @@ class vector
|
||||
|
||||
private:
|
||||
template <class InsertionProxy>
|
||||
void priv_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy)
|
||||
void priv_forward_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy)
|
||||
{
|
||||
T* const old_finish = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
|
||||
insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n);
|
||||
@@ -2204,7 +2183,7 @@ class vector
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
void priv_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy)
|
||||
void priv_forward_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy)
|
||||
{
|
||||
//n can't be 0, because there is nothing to do in that case
|
||||
if(!n) return;
|
||||
@@ -2240,7 +2219,7 @@ class vector
|
||||
this->m_holder.m_size += n;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
destroy_alloc_n(this->get_stored_allocator(), pos + n, elems_after);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), pos + n, elems_after);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
@@ -2248,7 +2227,7 @@ class vector
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
void priv_range_insert_new_allocation
|
||||
void priv_forward_range_insert_new_allocation
|
||||
(T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy)
|
||||
{
|
||||
//n can be zero, if we want to reallocate!
|
||||
@@ -2278,7 +2257,7 @@ class vector
|
||||
//Destroy and deallocate old elements
|
||||
//If there is allocated memory, destroy and deallocate
|
||||
if(!value_traits::trivial_dctr_after_move)
|
||||
destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size);
|
||||
this->m_holder.alloc().deallocate(this->m_holder.start(), this->m_holder.capacity());
|
||||
}
|
||||
this->m_holder.start(new_start);
|
||||
@@ -2290,7 +2269,7 @@ class vector
|
||||
}
|
||||
|
||||
template <class InsertionProxy>
|
||||
void priv_range_insert_expand_backwards
|
||||
void priv_forward_range_insert_expand_backwards
|
||||
(T* const new_start, const size_type new_capacity,
|
||||
T* const pos, const size_type n, InsertionProxy insert_range_proxy)
|
||||
{
|
||||
@@ -2374,7 +2353,7 @@ class vector
|
||||
//they have trivial destructor after move
|
||||
size_type n_destroy = old_finish - to_destroy;
|
||||
if(!value_traits::trivial_dctr_after_move)
|
||||
destroy_alloc_n(this->get_stored_allocator(), to_destroy, n_destroy);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), to_destroy, n_destroy);
|
||||
this->m_holder.m_size -= n_destroy;
|
||||
}
|
||||
}
|
||||
@@ -2448,7 +2427,7 @@ class vector
|
||||
//they have trivial destructor after being moved
|
||||
const size_type n_destroy = s_before - n;
|
||||
if(!value_traits::trivial_dctr_after_move)
|
||||
destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy);
|
||||
this->m_holder.m_size -= n_destroy;
|
||||
}
|
||||
}
|
||||
@@ -2504,7 +2483,7 @@ class vector
|
||||
//have trivial destructor after being moved
|
||||
size_type n_destroy = s_before - n;
|
||||
if(!value_traits::trivial_dctr_after_move)
|
||||
destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy);
|
||||
this->m_holder.m_size -= n_destroy;
|
||||
}
|
||||
}
|
||||
@@ -2585,7 +2564,7 @@ class vector
|
||||
this->m_holder.m_size += n_after;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
destroy_alloc_n(this->get_stored_allocator(), pos, mid_last_dist);
|
||||
boost::container::destroy_alloc_n(this->get_stored_allocator(), pos, mid_last_dist);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
|
@@ -95,93 +95,6 @@
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="doc"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\doc\container.qbk">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\doc\index.idx">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\doc\Jamfile.v2">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="example"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_emplace.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\doc_move_containers.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\doc_recursive_containers.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\doc_type_erasure.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\Jamfile.v2">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="test"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\test\check_equal_containers.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\dummy_test_allocator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\emplace_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\expand_bwd_test_allocator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\expand_bwd_test_template.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\forward_to_input_iterator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\heap_allocator_v1.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\Jamfile.v2">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\list_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\map_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\movable_int.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\print_container.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\propagate_allocator_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\set_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\static_vector_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\util.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\vector_test.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="container"
|
||||
Filter="">
|
||||
@@ -331,6 +244,93 @@
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="doc"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\doc\container.qbk">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\doc\index.idx">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\doc\Jamfile.v2">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="example"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_emplace.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\doc_move_containers.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\doc_recursive_containers.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\doc_type_erasure.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\example\Jamfile.v2">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="test"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\test\check_equal_containers.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\dummy_test_allocator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\emplace_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\expand_bwd_test_allocator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\expand_bwd_test_template.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\forward_to_input_iterator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\heap_allocator_v1.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\Jamfile.v2">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\list_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\map_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\movable_int.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\print_container.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\propagate_allocator_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\set_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\static_vector_test.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\util.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\vector_test.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="bench"
|
||||
Filter="">
|
||||
|
@@ -21,7 +21,7 @@ rule test_all
|
||||
|
||||
for local fileb in [ glob *.cpp ]
|
||||
{
|
||||
all_rules += [ run $(fileb) /boost/timer//boost_timer /boost/system//boost_system /boost/thread//boost_thread
|
||||
all_rules += [ run $(fileb)
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
|
@@ -314,15 +314,20 @@ class propagation_test_allocator
|
||||
friend bool operator!=(const propagation_test_allocator &, const propagation_test_allocator &)
|
||||
{ return false; }
|
||||
|
||||
void swap(propagation_test_allocator &r)
|
||||
{
|
||||
++this->swaps_; ++r.swaps_;
|
||||
boost::container::swap_dispatch(this->id_, r.id_);
|
||||
boost::container::swap_dispatch(this->ctr_copies_, r.ctr_copies_);
|
||||
boost::container::swap_dispatch(this->ctr_moves_, r.ctr_moves_);
|
||||
boost::container::swap_dispatch(this->assign_copies_, r.assign_copies_);
|
||||
boost::container::swap_dispatch(this->assign_moves_, r.assign_moves_);
|
||||
boost::container::swap_dispatch(this->swaps_, r.swaps_);
|
||||
}
|
||||
|
||||
friend void swap(propagation_test_allocator &l, propagation_test_allocator &r)
|
||||
{
|
||||
++l.swaps_; ++r.swaps_;
|
||||
container_detail::do_swap(l.id_, r.id_);
|
||||
container_detail::do_swap(l.ctr_copies_, r.ctr_copies_);
|
||||
container_detail::do_swap(l.ctr_moves_, r.ctr_moves_);
|
||||
container_detail::do_swap(l.assign_copies_, r.assign_copies_);
|
||||
container_detail::do_swap(l.assign_moves_, r.assign_moves_);
|
||||
container_detail::do_swap(l.swaps_, r.swaps_);
|
||||
l.swap(r);
|
||||
}
|
||||
|
||||
unsigned int id_;
|
||||
|
@@ -112,9 +112,9 @@ class expand_bwd_test_allocator
|
||||
|
||||
friend void swap(self_t &alloc1, self_t &alloc2)
|
||||
{
|
||||
container_detail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
|
||||
container_detail::do_swap(alloc1.m_size, alloc2.m_size);
|
||||
container_detail::do_swap(alloc1.m_offset, alloc2.m_offset);
|
||||
boost::container::swap_dispatch(alloc1.mp_buffer, alloc2.mp_buffer);
|
||||
boost::container::swap_dispatch(alloc1.m_size, alloc2.m_size);
|
||||
boost::container::swap_dispatch(alloc1.m_offset, alloc2.m_offset);
|
||||
}
|
||||
|
||||
//Experimental version 2 expand_bwd_test_allocator functions
|
||||
|
@@ -133,7 +133,7 @@ class heap_allocator_v1
|
||||
//!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in
|
||||
//!different memory segments, the result is undefined.
|
||||
friend void swap(self_t &alloc1, self_t &alloc2)
|
||||
{ detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
|
||||
{ boost::container::boost::container::swap_dispatch(alloc1.mp_mngr, alloc2.mp_mngr); }
|
||||
};
|
||||
|
||||
//!Equality test for same type of heap_allocator_v1
|
||||
|
@@ -80,6 +80,12 @@ bool vector_copyable_only(V1 *boostvector, V2 *stdvector, boost::container::cont
|
||||
stdvector->push_back(int(3));
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
|
||||
}
|
||||
{
|
||||
V1 *pv1 = new V1(*boostvector);
|
||||
V2 *pv2 = new V2(*stdvector);
|
||||
delete pv1;
|
||||
delete pv2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user