mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Merge branch 'develop'
This commit is contained in:
@@ -1213,6 +1213,11 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_65_00 Boost 1.65 Release]
|
||||
|
||||
* Implemented `extract_sequence`, `adopt_sequence` functions for flat_[multi]map/set associative containers.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_64_00 Boost 1.64 Release]
|
||||
|
||||
|
@@ -347,7 +347,7 @@ struct allocator_traits
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
|
||||
//! otherwise, invokes <code>`placement new` (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
|
||||
template <class T, class ...Args>
|
||||
BOOST_CONTAINER_FORCEINLINE static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
|
@@ -31,11 +31,11 @@
|
||||
#include <boost/container/detail/alloc_helpers.hpp>
|
||||
#include <boost/container/detail/copy_move_algo.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/min_max.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
// move
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
@@ -1649,7 +1649,7 @@ class deque : protected deque_base<Allocator>
|
||||
if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
, container_detail::to_raw_pointer(this->members_.m_start.m_cur)
|
||||
, boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
|
||||
);
|
||||
++this->members_.m_start.m_cur;
|
||||
}
|
||||
@@ -1669,7 +1669,7 @@ class deque : protected deque_base<Allocator>
|
||||
--this->members_.m_finish.m_cur;
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
, container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
|
||||
, boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
|
||||
);
|
||||
}
|
||||
else
|
||||
@@ -1916,7 +1916,7 @@ class deque : protected deque_base<Allocator>
|
||||
|
||||
T *priv_push_back_simple_pos() const
|
||||
{
|
||||
return container_detail::to_raw_pointer(this->members_.m_finish.m_cur);
|
||||
return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur);
|
||||
}
|
||||
|
||||
void priv_push_back_simple_commit()
|
||||
@@ -1931,7 +1931,7 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
|
||||
T *priv_push_front_simple_pos() const
|
||||
{ return container_detail::to_raw_pointer(this->members_.m_start.m_cur) - 1; }
|
||||
{ return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1; }
|
||||
|
||||
void priv_push_front_simple_commit()
|
||||
{ --this->members_.m_start.m_cur; }
|
||||
@@ -1940,7 +1940,7 @@ class deque : protected deque_base<Allocator>
|
||||
{
|
||||
if(!Base::traits_t::trivial_dctr){
|
||||
for(;p != p2; ++p){
|
||||
allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
|
||||
allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1949,7 +1949,7 @@ class deque : protected deque_base<Allocator>
|
||||
{
|
||||
if(!Base::traits_t::trivial_dctr){
|
||||
for(;p != p2; ++p){
|
||||
allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
|
||||
allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2133,7 +2133,7 @@ class deque : protected deque_base<Allocator>
|
||||
this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
, container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
|
||||
, boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2145,7 +2145,7 @@ class deque : protected deque_base<Allocator>
|
||||
{
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
, container_detail::to_raw_pointer(this->members_.m_start.m_cur)
|
||||
, boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
|
||||
);
|
||||
this->priv_deallocate_node(this->members_.m_start.m_first);
|
||||
this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
|
||||
|
@@ -28,10 +28,10 @@
|
||||
// container/detail
|
||||
#include <boost/container/detail/pool_common.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/math_functions.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
// intrusive
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
@@ -378,7 +378,7 @@ class private_adaptive_node_pool_impl
|
||||
|
||||
//!Returns the segment manager. Never throws
|
||||
segment_manager_base_type* get_segment_manager_base()const
|
||||
{ return container_detail::to_raw_pointer(mp_segment_mngr_base); }
|
||||
{ return boost::movelib::to_raw_pointer(mp_segment_mngr_base); }
|
||||
|
||||
//!Allocates array of count elements. Can throw
|
||||
void *allocate_node()
|
||||
@@ -390,7 +390,7 @@ class private_adaptive_node_pool_impl
|
||||
free_nodes_t &free_nodes = m_block_container.begin()->free_nodes;
|
||||
BOOST_ASSERT(!free_nodes.empty());
|
||||
const size_type free_nodes_count = free_nodes.size();
|
||||
void *first_node = container_detail::to_raw_pointer(free_nodes.pop_front());
|
||||
void *first_node = boost::movelib::to_raw_pointer(free_nodes.pop_front());
|
||||
if(free_nodes.empty()){
|
||||
block_container_traits_t::erase_first(m_block_container);
|
||||
}
|
||||
@@ -401,7 +401,7 @@ class private_adaptive_node_pool_impl
|
||||
else{
|
||||
multiallocation_chain chain;
|
||||
this->priv_append_from_new_blocks(1, chain, IsAlignOnly());
|
||||
return container_detail::to_raw_pointer(chain.pop_front());
|
||||
return boost::movelib::to_raw_pointer(chain.pop_front());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,7 +492,7 @@ class private_adaptive_node_pool_impl
|
||||
free_nodes_iterator itf(nodes.begin()), itbf(itbb);
|
||||
size_type splice_node_count = size_type(-1);
|
||||
while(itf != ite){
|
||||
void *pElem = container_detail::to_raw_pointer(container_detail::iterator_to_raw_pointer(itf));
|
||||
void *pElem = boost::movelib::to_raw_pointer(boost::movelib::iterator_to_raw_pointer(itf));
|
||||
block_info_t &block_info = *this->priv_block_from_node(pElem);
|
||||
BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node);
|
||||
++splice_node_count;
|
||||
@@ -631,7 +631,7 @@ class private_adaptive_node_pool_impl
|
||||
BOOST_ASSERT(to_deallocate->free_nodes.size() == mp_impl->m_real_num_node);
|
||||
BOOST_ASSERT(0 == to_deallocate->hdr_offset);
|
||||
hdr_offset_holder *hdr_off_holder =
|
||||
mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate));
|
||||
mp_impl->priv_first_subblock_from_block(boost::movelib::to_raw_pointer(to_deallocate));
|
||||
m_chain.push_back(hdr_off_holder);
|
||||
}
|
||||
|
||||
@@ -763,7 +763,7 @@ class private_adaptive_node_pool_impl
|
||||
//First add all possible nodes to the chain
|
||||
const size_type left = total_elements - chain.size();
|
||||
const size_type max_chain = (num_node < left) ? num_node : left;
|
||||
mem_address = static_cast<char *>(container_detail::to_raw_pointer
|
||||
mem_address = static_cast<char *>(boost::movelib::to_raw_pointer
|
||||
(chain.incorporate_after(chain.last(), void_pointer(mem_address), m_real_node_size, max_chain)));
|
||||
//Now store remaining nodes in the free list
|
||||
if(const size_type max_free = num_node - max_chain){
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
@@ -157,7 +157,7 @@ struct insert_copy_proxy
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, iterator_to_raw_pointer(p), v_);
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_);
|
||||
}
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
|
||||
@@ -184,7 +184,7 @@ struct insert_move_proxy
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) );
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) );
|
||||
}
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
|
||||
@@ -240,7 +240,7 @@ struct insert_nonmovable_emplace_proxy
|
||||
void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -354,7 +354,7 @@ struct insert_nonmovable_emplace_proxy##N\
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
|
||||
{\
|
||||
BOOST_ASSERT(n == 1); (void)n;\
|
||||
alloc_traits::construct(a, iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
|
||||
alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
|
||||
}\
|
||||
\
|
||||
void copy_n_and_update(Allocator &, Iterator, size_type)\
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/construct_in_place.hpp>
|
||||
@@ -178,7 +178,7 @@ inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
|
||||
if(n){
|
||||
std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
||||
std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
|
||||
boost::container::iterator_advance(r, n);
|
||||
}
|
||||
return r;
|
||||
@@ -192,7 +192,7 @@ F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
if(n){
|
||||
std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
||||
std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
|
||||
boost::container::iterator_advance(r, n);
|
||||
}
|
||||
return r;
|
||||
@@ -206,7 +206,7 @@ I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
if(n){
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
||||
std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
|
||||
boost::container::iterator_advance(f, n);
|
||||
}
|
||||
return f;
|
||||
@@ -220,7 +220,7 @@ I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
if(n){
|
||||
std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
||||
std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
|
||||
boost::container::iterator_advance(f, n);
|
||||
boost::container::iterator_advance(r, n);
|
||||
}
|
||||
@@ -295,13 +295,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (f != l) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -340,13 +340,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -385,13 +385,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -430,13 +430,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (f != l) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -475,13 +475,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -520,13 +520,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
boost::container::construct_in_place(a, container_detail::iterator_to_raw_pointer(r), f);
|
||||
boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f);
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -564,13 +564,13 @@ inline typename container_detail::disable_if_memzero_initializable<F, F>::type
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r));
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r));
|
||||
++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -585,7 +585,7 @@ inline typename container_detail::enable_if_memzero_initializable<F, F>::type
|
||||
uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<F>::value_type value_type;
|
||||
std::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
|
||||
std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
|
||||
boost::container::iterator_advance(r, n);
|
||||
return r;
|
||||
}
|
||||
@@ -611,13 +611,13 @@ inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::contai
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init);
|
||||
++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -647,13 +647,13 @@ inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t)
|
||||
F back = f;
|
||||
BOOST_TRY{
|
||||
while (f != l) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(f), t);
|
||||
++f;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != l; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -683,13 +683,13 @@ inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::co
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (n--) {
|
||||
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
|
||||
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), v);
|
||||
++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
@@ -890,7 +890,7 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>
|
||||
typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
||||
const typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
|
||||
r -= n;
|
||||
std::memmove((container_detail::iterator_to_raw_pointer)(r), (container_detail::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
||||
std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -964,7 +964,7 @@ inline typename container_detail::disable_if_trivially_destructible<I, void>::ty
|
||||
destroy_alloc_n(Allocator &a, I f, U n)
|
||||
{
|
||||
while(n--){
|
||||
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(f));
|
||||
allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(f));
|
||||
++f;
|
||||
}
|
||||
}
|
||||
@@ -1021,9 +1021,9 @@ inline typename container_detail::enable_if_c
|
||||
storage_type storage;
|
||||
|
||||
const std::size_t n_i_bytes = sizeof(value_type)*n_i;
|
||||
void *const large_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(large_range_f));
|
||||
void *const short_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f));
|
||||
void *const stora_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(storage));
|
||||
void *const large_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(large_range_f));
|
||||
void *const short_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(short_range_f));
|
||||
void *const stora_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(storage));
|
||||
std::memcpy(stora_ptr, large_ptr, n_i_bytes);
|
||||
std::memcpy(large_ptr, short_ptr, n_i_bytes);
|
||||
std::memcpy(short_ptr, stora_ptr, n_i_bytes);
|
||||
@@ -1052,8 +1052,8 @@ inline typename container_detail::enable_if_c
|
||||
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::iterator_to_raw_pointer(large_range_f)));
|
||||
char *short_ptr = static_cast<char*>(static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f)));
|
||||
char *large_ptr = static_cast<char*>(static_cast<void*>(boost::movelib::iterator_to_raw_pointer(large_range_f)));
|
||||
char *short_ptr = static_cast<char*>(static_cast<void*>(boost::movelib::iterator_to_raw_pointer(short_range_f)));
|
||||
char *stora_ptr = static_cast<char*>(static_cast<void*>(&storage));
|
||||
|
||||
std::size_t szt_times = n_i_bytes/sizeof_storage;
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -152,7 +152,7 @@ struct scoped_destroy_deallocator
|
||||
~scoped_destroy_deallocator()
|
||||
{
|
||||
if(m_ptr){
|
||||
AllocTraits::destroy(m_alloc, container_detail::to_raw_pointer(m_ptr));
|
||||
AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr));
|
||||
priv_deallocate(m_ptr, alloc_version());
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ struct scoped_destructor_n
|
||||
~scoped_destructor_n()
|
||||
{
|
||||
if(!m_p) return;
|
||||
value_type *raw_ptr = container_detail::to_raw_pointer(m_p);
|
||||
value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
|
||||
while(m_n--){
|
||||
AllocTraits::destroy(m_a, raw_ptr++);
|
||||
}
|
||||
@@ -317,7 +317,7 @@ class allocator_destroyer
|
||||
|
||||
void operator()(const pointer &p)
|
||||
{
|
||||
AllocTraits::destroy(a_, container_detail::to_raw_pointer(p));
|
||||
AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p));
|
||||
this->priv_deallocate(p, alloc_version());
|
||||
}
|
||||
};
|
||||
@@ -339,7 +339,7 @@ class allocator_destroyer_and_chain_builder
|
||||
|
||||
void operator()(const typename Allocator::pointer &p)
|
||||
{
|
||||
allocator_traits<Allocator>::destroy(a_, container_detail::to_raw_pointer(p));
|
||||
allocator_traits<Allocator>::destroy(a_, boost::movelib::to_raw_pointer(p));
|
||||
c_.push_back(p);
|
||||
}
|
||||
};
|
||||
|
@@ -28,25 +28,30 @@
|
||||
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/is_sorted.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#endif
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
|
||||
#include <boost/move/make_unique.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/move/algo/adaptive_sort.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
#include <boost/move/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -105,14 +110,17 @@ template <class Value, class KeyOfValue,
|
||||
class Compare, class Allocator>
|
||||
class flat_tree
|
||||
{
|
||||
typedef boost::container::vector<Value, Allocator> vector_t;
|
||||
public:
|
||||
typedef boost::container::vector<Value, Allocator> sequence_type;
|
||||
|
||||
private:
|
||||
typedef Allocator allocator_t;
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
|
||||
public:
|
||||
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Data
|
||||
//Inherit from value_compare to do EBO
|
||||
: public value_compare
|
||||
@@ -121,48 +129,48 @@ class flat_tree
|
||||
|
||||
public:
|
||||
Data()
|
||||
: value_compare(), m_vect()
|
||||
: value_compare(), m_seq()
|
||||
{}
|
||||
|
||||
explicit Data(const Data &d)
|
||||
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect)
|
||||
: value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq)
|
||||
{}
|
||||
|
||||
Data(BOOST_RV_REF(Data) d)
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq))
|
||||
{}
|
||||
|
||||
Data(const Data &d, const Allocator &a)
|
||||
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
|
||||
: value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq, a)
|
||||
{}
|
||||
|
||||
Data(BOOST_RV_REF(Data) d, const Allocator &a)
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect), a)
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq), a)
|
||||
{}
|
||||
|
||||
explicit Data(const Compare &comp)
|
||||
: value_compare(comp), m_vect()
|
||||
: value_compare(comp), m_seq()
|
||||
{}
|
||||
|
||||
Data(const Compare &comp, const allocator_t &alloc)
|
||||
: value_compare(comp), m_vect(alloc)
|
||||
: value_compare(comp), m_seq(alloc)
|
||||
{}
|
||||
|
||||
explicit Data(const allocator_t &alloc)
|
||||
: value_compare(), m_vect(alloc)
|
||||
: value_compare(), m_seq(alloc)
|
||||
{}
|
||||
|
||||
Data& operator=(BOOST_COPY_ASSIGN_REF(Data) d)
|
||||
{
|
||||
this->value_compare::operator=(d);
|
||||
m_vect = d.m_vect;
|
||||
m_seq = d.m_seq;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data& operator=(BOOST_RV_REF(Data) d)
|
||||
{
|
||||
this->value_compare::operator=(boost::move(static_cast<value_compare &>(d)));
|
||||
m_vect = boost::move(d.m_vect);
|
||||
m_seq = boost::move(d.m_seq);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -170,10 +178,10 @@ class flat_tree
|
||||
{
|
||||
value_compare& mycomp = *this, & othercomp = d;
|
||||
boost::adl_move_swap(mycomp, othercomp);
|
||||
this->m_vect.swap(d.m_vect);
|
||||
this->m_seq.swap(d.m_seq);
|
||||
}
|
||||
|
||||
vector_t m_vect;
|
||||
sequence_type m_seq;
|
||||
};
|
||||
|
||||
Data m_data;
|
||||
@@ -181,23 +189,23 @@ class flat_tree
|
||||
|
||||
public:
|
||||
|
||||
typedef typename vector_t::value_type value_type;
|
||||
typedef typename vector_t::pointer pointer;
|
||||
typedef typename vector_t::const_pointer const_pointer;
|
||||
typedef typename vector_t::reference reference;
|
||||
typedef typename vector_t::const_reference const_reference;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef typename vector_t::allocator_type allocator_type;
|
||||
typedef typename vector_t::size_type size_type;
|
||||
typedef typename vector_t::difference_type difference_type;
|
||||
typedef typename vector_t::iterator iterator;
|
||||
typedef typename vector_t::const_iterator const_iterator;
|
||||
typedef typename vector_t::reverse_iterator reverse_iterator;
|
||||
typedef typename vector_t::const_reverse_iterator const_reverse_iterator;
|
||||
typedef typename sequence_type::value_type value_type;
|
||||
typedef typename sequence_type::pointer pointer;
|
||||
typedef typename sequence_type::const_pointer const_pointer;
|
||||
typedef typename sequence_type::reference reference;
|
||||
typedef typename sequence_type::const_reference const_reference;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef typename sequence_type::allocator_type allocator_type;
|
||||
typedef typename sequence_type::size_type size_type;
|
||||
typedef typename sequence_type::difference_type difference_type;
|
||||
typedef typename sequence_type::iterator iterator;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
typedef typename sequence_type::reverse_iterator reverse_iterator;
|
||||
typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//!Standard extension
|
||||
typedef allocator_type stored_allocator_type;
|
||||
typedef allocator_type stored_allocator_type;
|
||||
|
||||
private:
|
||||
typedef allocator_traits<stored_allocator_type> stored_allocator_traits;
|
||||
@@ -242,8 +250,8 @@ class flat_tree
|
||||
, const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{
|
||||
this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last);
|
||||
BOOST_ASSERT((is_sorted)(this->m_data.m_vect.cbegin(), this->m_data.m_vect.cend(), this->priv_value_comp()));
|
||||
this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
|
||||
BOOST_ASSERT((is_sorted)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
@@ -252,8 +260,8 @@ class flat_tree
|
||||
, const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{
|
||||
this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last);
|
||||
BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_vect.cbegin(), this->m_data.m_vect.cend(), this->priv_value_comp()));
|
||||
this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
|
||||
BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
@@ -312,31 +320,31 @@ class flat_tree
|
||||
{ return this->m_data; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
|
||||
{ return this->m_data.m_vect.get_allocator(); }
|
||||
{ return this->m_data.m_seq.get_allocator(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
{ return this->m_data.m_seq.get_stored_allocator(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator()
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
{ return this->m_data.m_seq.get_stored_allocator(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator begin()
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
{ return this->m_data.m_seq.begin(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator begin() const
|
||||
{ return this->cbegin(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
{ return this->m_data.m_seq.begin(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator end()
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
{ return this->m_data.m_seq.end(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator end() const
|
||||
{ return this->cend(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cend() const
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
{ return this->m_data.m_seq.end(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin()
|
||||
{ return reverse_iterator(this->end()); }
|
||||
@@ -357,13 +365,13 @@ class flat_tree
|
||||
{ return const_reverse_iterator(this->cbegin()); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool empty() const
|
||||
{ return this->m_data.m_vect.empty(); }
|
||||
{ return this->m_data.m_seq.empty(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type size() const
|
||||
{ return this->m_data.m_vect.size(); }
|
||||
{ return this->m_data.m_seq.size(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type max_size() const
|
||||
{ return this->m_data.m_vect.max_size(); }
|
||||
{ return this->m_data.m_seq.max_size(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void swap(flat_tree& other)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
@@ -395,14 +403,14 @@ class flat_tree
|
||||
iterator insert_equal(const value_type& val)
|
||||
{
|
||||
iterator i = this->upper_bound(KeyOfValue()(val));
|
||||
i = this->m_data.m_vect.insert(i, val);
|
||||
i = this->m_data.m_seq.insert(i, val);
|
||||
return i;
|
||||
}
|
||||
|
||||
iterator insert_equal(BOOST_RV_REF(value_type) mval)
|
||||
{
|
||||
iterator i = this->upper_bound(KeyOfValue()(mval));
|
||||
i = this->m_data.m_vect.insert(i, boost::move(mval));
|
||||
i = this->m_data.m_seq.insert(i, boost::move(mval));
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -509,7 +517,7 @@ class flat_tree
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->m_data.m_vect.merge(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
{ this->m_data.m_seq.merge(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(ordered_unique_range_t, InIt first, InIt last
|
||||
@@ -538,7 +546,7 @@ class flat_tree
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->m_data.m_vect.merge_unique(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
{ this->m_data.m_seq.merge_unique(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
@@ -606,7 +614,7 @@ class flat_tree
|
||||
typedef typename emplace_functor_type<try_emplace_t, KeyType, Args...>::type func_t;
|
||||
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
|
||||
func_t func(try_emplace_t(), ::boost::forward<KeyType>(key), ::boost::forward<Args>(args)...);
|
||||
ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t());
|
||||
ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -675,7 +683,7 @@ class flat_tree
|
||||
typedef typename emplace_functor_type<try_emplace_t, KeyType BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::type func_t;\
|
||||
typedef emplace_iterator<value_type, func_t, difference_type> it_t;\
|
||||
func_t func(try_emplace_t(), ::boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t());\
|
||||
ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());\
|
||||
}\
|
||||
return ret;\
|
||||
}\
|
||||
@@ -702,29 +710,29 @@ class flat_tree
|
||||
typedef typename emplace_functor_type<KeyType, M>::type func_t;
|
||||
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
|
||||
func_t func(boost::forward<KeyType>(key), boost::forward<M>(obj));
|
||||
ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t());
|
||||
ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator position)
|
||||
{ return this->m_data.m_vect.erase(position); }
|
||||
{ return this->m_data.m_seq.erase(position); }
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
std::pair<iterator,iterator > itp = this->equal_range(k);
|
||||
size_type ret = static_cast<size_type>(itp.second-itp.first);
|
||||
if (ret){
|
||||
this->m_data.m_vect.erase(itp.first, itp.second);
|
||||
this->m_data.m_seq.erase(itp.first, itp.second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
|
||||
{ return this->m_data.m_vect.erase(first, last); }
|
||||
{ return this->m_data.m_seq.erase(first, last); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void clear()
|
||||
{ this->m_data.m_vect.clear(); }
|
||||
{ this->m_data.m_seq.clear(); }
|
||||
|
||||
//! <b>Effects</b>: Tries to deallocate the excess of memory created
|
||||
// with previous allocations. The size of the vector is unchanged
|
||||
@@ -733,19 +741,19 @@ class flat_tree
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to size().
|
||||
BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
|
||||
{ this->m_data.m_vect.shrink_to_fit(); }
|
||||
{ this->m_data.m_seq.shrink_to_fit(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.nth(n); }
|
||||
{ return this->m_data.m_seq.nth(n); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.nth(n); }
|
||||
{ return this->m_data.m_seq.nth(n); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.index_of(p); }
|
||||
{ return this->m_data.m_seq.index_of(p); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.index_of(p); }
|
||||
{ return this->m_data.m_seq.index_of(p); }
|
||||
|
||||
// set operations:
|
||||
iterator find(const key_type& k)
|
||||
@@ -793,7 +801,7 @@ class flat_tree
|
||||
|
||||
void merge_unique(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_vect.merge_unique
|
||||
this->m_data.m_seq.merge_unique
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
@@ -801,7 +809,7 @@ class flat_tree
|
||||
|
||||
void merge_equal(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_vect.merge
|
||||
this->m_data.m_seq.merge
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
@@ -832,10 +840,61 @@ class flat_tree
|
||||
{ return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type capacity() const
|
||||
{ return this->m_data.m_vect.capacity(); }
|
||||
{ return this->m_data.m_seq.capacity(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
|
||||
{ this->m_data.m_vect.reserve(cnt); }
|
||||
{ this->m_data.m_seq.reserve(cnt); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
|
||||
{
|
||||
return boost::move(m_data.m_seq);
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE sequence_type &get_sequence_ref()
|
||||
{
|
||||
return m_data.m_seq;
|
||||
}
|
||||
|
||||
void adopt_sequence_equal(BOOST_RV_REF(sequence_type) seq)
|
||||
{
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
boost::movelib::adaptive_sort
|
||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||
, this->priv_value_comp()
|
||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||
, tseq.capacity() - tseq.size());
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
void adopt_sequence_equal(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{
|
||||
BOOST_ASSERT((is_sorted)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
void adopt_sequence_unique(BOOST_RV_REF(sequence_type) seq)
|
||||
{
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
boost::movelib::adaptive_sort
|
||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||
, this->priv_value_comp()
|
||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||
, tseq.capacity() - tseq.size());
|
||||
seq.erase( boost::movelib::unique
|
||||
(seq.begin(), seq.end(), boost::movelib::negate<value_compare>(this->m_data.get_comp()))
|
||||
, seq.cend());
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
void adopt_sequence_unique(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{
|
||||
BOOST_ASSERT((is_sorted_and_unique)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_tree& x, const flat_tree& y)
|
||||
{
|
||||
@@ -963,7 +1022,7 @@ class flat_tree
|
||||
BOOST_CONTAINER_FORCEINLINE iterator priv_insert_commit
|
||||
(insert_commit_data &commit_data, BOOST_FWD_REF(Convertible) convertible)
|
||||
{
|
||||
return this->m_data.m_vect.insert
|
||||
return this->m_data.m_seq.insert
|
||||
( commit_data.position
|
||||
, boost::forward<Convertible>(convertible));
|
||||
}
|
||||
|
@@ -18,38 +18,13 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <class T>
|
||||
inline T* iterator_to_pointer(T* i)
|
||||
{ return i; }
|
||||
|
||||
template <class Iterator>
|
||||
inline typename boost::container::iterator_traits<Iterator>::pointer
|
||||
iterator_to_pointer(const Iterator &i)
|
||||
{ return i.operator->(); }
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_to_element_ptr
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<Iterator>::pointer pointer;
|
||||
typedef typename boost::intrusive::pointer_traits<pointer>::element_type element_type;
|
||||
typedef element_type* type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
inline typename iterator_to_element_ptr<Iterator>::type
|
||||
iterator_to_raw_pointer(const Iterator &i)
|
||||
{
|
||||
return ::boost::intrusive::detail::to_raw_pointer
|
||||
( ::boost::container::container_detail::iterator_to_pointer(i) );
|
||||
}
|
||||
using ::boost::movelib::iterator_to_raw_pointer;
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
|
@@ -24,7 +24,7 @@
|
||||
// container
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/transform_iterator.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
// intrusive
|
||||
@@ -63,7 +63,7 @@ class basic_multiallocation_chain
|
||||
pointer_traits<node_ptr> node_ptr_traits;
|
||||
|
||||
static node & to_node(const VoidPointer &p)
|
||||
{ return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
|
||||
{ return *static_cast<node*>(static_cast<void*>(boost::movelib::to_raw_pointer(p))); }
|
||||
|
||||
static VoidPointer from_node(node &n)
|
||||
{ return node_ptr_traits::pointer_to(n); }
|
||||
@@ -152,7 +152,7 @@ class basic_multiallocation_chain
|
||||
char_ptr prev_elem = elem;
|
||||
elem += unit_bytes;
|
||||
for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){
|
||||
::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem);
|
||||
::new (boost::movelib::to_raw_pointer(prev_elem)) void_pointer(elem);
|
||||
prev_elem = elem;
|
||||
}
|
||||
slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
|
||||
|
@@ -30,10 +30,10 @@
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/container/detail/construct_in_place.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
// intrusive
|
||||
@@ -171,7 +171,7 @@ struct node_alloc_holder
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ struct node_alloc_holder
|
||||
BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
node_deallocator.release();\
|
||||
typedef typename Node::hook_type hook_type;\
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
|
||||
::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
|
||||
return (p);\
|
||||
}\
|
||||
//
|
||||
@@ -207,7 +207,7 @@ struct node_alloc_holder
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
@@ -230,13 +230,13 @@ struct node_alloc_holder
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
void destroy_node(const NodePtr &nodep)
|
||||
{
|
||||
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
|
||||
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(nodep));
|
||||
this->deallocate_one(nodep);
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ struct node_alloc_holder
|
||||
Deallocator node_deallocator(NodePtr(), nalloc);
|
||||
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
|
||||
while(n--){
|
||||
p = container_detail::iterator_to_raw_pointer(itbeg);
|
||||
p = boost::movelib::iterator_to_raw_pointer(itbeg);
|
||||
node_deallocator.set(p);
|
||||
++itbeg;
|
||||
//This can throw
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include <boost/container/detail/math_functions.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/pool_common.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
@@ -92,7 +92,7 @@ class private_node_pool_impl
|
||||
|
||||
//!Returns the segment manager. Never throws
|
||||
segment_manager_base_type* get_segment_manager_base()const
|
||||
{ return container_detail::to_raw_pointer(mp_segment_mngr_base); }
|
||||
{ return boost::movelib::to_raw_pointer(mp_segment_mngr_base); }
|
||||
|
||||
void *allocate_node()
|
||||
{ return this->priv_alloc_node(); }
|
||||
|
@@ -35,16 +35,62 @@
|
||||
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include<boost/move/detail/fwd_macros.hpp>
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace tuples {
|
||||
|
||||
struct null_type;
|
||||
|
||||
template <
|
||||
class T0, class T1, class T2,
|
||||
class T3, class T4, class T5,
|
||||
class T6, class T7, class T8,
|
||||
class T9>
|
||||
class tuple;
|
||||
|
||||
} //namespace tuples {
|
||||
} //namespace boost {
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace pair_impl {
|
||||
|
||||
template <class TupleClass>
|
||||
struct is_boost_tuple
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <
|
||||
class T0, class T1, class T2,
|
||||
class T3, class T4, class T5,
|
||||
class T6, class T7, class T8,
|
||||
class T9>
|
||||
struct is_boost_tuple< boost::tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class Tuple>
|
||||
struct disable_if_boost_tuple
|
||||
: boost::container::container_detail::disable_if< is_boost_tuple<Tuple> >
|
||||
{};
|
||||
|
||||
template<class T>
|
||||
struct is_tuple_null
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_tuple_null<boost::tuples::null_type>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
//MSVC 2010 tuple marker
|
||||
namespace std { namespace tr1 { struct _Nil; }}
|
||||
@@ -236,7 +282,12 @@ struct pair
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
pair( piecewise_construct_t\
|
||||
, BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q\
|
||||
, typename container_detail::enable_if_c\
|
||||
< pair_impl::is_boost_tuple< BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> >::value &&\
|
||||
!(pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARG##N>::value || pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARGQ##M>::value) \
|
||||
>::type* = 0\
|
||||
)\
|
||||
: first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
|
||||
{ (void)p; (void)q; }\
|
||||
//
|
||||
@@ -254,7 +305,8 @@ struct pair
|
||||
{ (void) t1; (void)t2; }
|
||||
|
||||
public:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
template< template<class ...> class Tuple, class... Args1, class... Args2
|
||||
, class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
: pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
|
||||
{}
|
||||
@@ -270,7 +322,8 @@ struct pair
|
||||
{ (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...); }
|
||||
|
||||
public:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
template< template<class ...> class Tuple, class... Args1, class... Args2
|
||||
, class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
: first (build_from_args<first_type> (::boost::move(t1)))
|
||||
, second (build_from_args<second_type>(::boost::move(t2)))
|
||||
|
55
include/boost/container/detail/pair_key_mapped_of_value.hpp
Normal file
55
include/boost/container/detail/pair_key_mapped_of_value.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
||||
#define BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<class Key, class Mapped>
|
||||
struct pair_key_mapped_of_value
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef Mapped mapped_type;
|
||||
|
||||
template<class Pair>
|
||||
const key_type & key_of_value(const Pair &p) const
|
||||
{ return p.first; }
|
||||
|
||||
template<class Pair>
|
||||
const mapped_type & mapped_of_value(const Pair &p) const
|
||||
{ return p.second; }
|
||||
|
||||
template<class Pair>
|
||||
key_type & key_of_value(Pair &p) const
|
||||
{ return const_cast<key_type&>(p.first); }
|
||||
|
||||
template<class Pair>
|
||||
mapped_type & mapped_of_value(Pair &p) const
|
||||
{ return p.second; }
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
@@ -493,7 +493,7 @@ class tree
|
||||
typedef boost::container::reverse_iterator
|
||||
<const_iterator> const_reverse_iterator;
|
||||
typedef node_handle
|
||||
< Node, value_type, allocator_type, void> node_type;
|
||||
< NodeAlloc, void> node_type;
|
||||
typedef insert_return_type_base
|
||||
<iterator, node_type> insert_return_type;
|
||||
|
||||
@@ -1142,7 +1142,7 @@ class tree
|
||||
this->insert_unique_check(hint, KeyOfValue()(nh.value()), data);
|
||||
if(ret.second){
|
||||
irt.inserted = true;
|
||||
irt.position = iterator(this->icont().insert_unique_commit(*nh.get_node_pointer(), data));
|
||||
irt.position = iterator(this->icont().insert_unique_commit(*nh.get(), data));
|
||||
nh.release();
|
||||
}
|
||||
else{
|
||||
|
@@ -144,8 +144,10 @@ class flat_map
|
||||
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
typedef typename impl_tree_t::sequence_type impl_sequence_type;
|
||||
|
||||
impl_tree_t &tree()
|
||||
{ return m_flat_tree; }
|
||||
@@ -182,6 +184,7 @@ class flat_map
|
||||
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 BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -1243,6 +1246,39 @@ class flat_map
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
|
||||
|
||||
//! <b>Effects</b>: Extracts the internal sequence container.
|
||||
//!
|
||||
//! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
//!
|
||||
//! <b>Throws</b>: If secuence_type's move constructor throws
|
||||
sequence_type extract_sequence()
|
||||
{
|
||||
return boost::move(container_detail::force<sequence_type>(m_flat_tree.get_sequence_ref()));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment. Erases non-unique elements.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
|
||||
//!
|
||||
//! <b>Throws</b>: If the comparison or the move constructor throws
|
||||
void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->m_flat_tree.adopt_sequence_unique(boost::move(container_detail::force<impl_sequence_type>(seq))); }
|
||||
|
||||
//! <b>Requires</b>: seq shall be ordered according to this->compare()
|
||||
//! and shall contain unique elements.
|
||||
//!
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
|
||||
//!
|
||||
//! <b>Throws</b>: If the move assignment throws
|
||||
void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->m_flat_tree.adopt_sequence_unique(ordered_unique_range_t(), boost::move(container_detail::force<impl_sequence_type>(seq))); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
@@ -1401,6 +1437,7 @@ class flat_multimap
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
typedef typename impl_tree_t::sequence_type impl_sequence_type;
|
||||
|
||||
impl_tree_t &tree()
|
||||
{ return m_flat_tree; }
|
||||
@@ -1437,6 +1474,7 @@ class flat_multimap
|
||||
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 BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
@@ -2070,7 +2108,7 @@ class flat_multimap
|
||||
void merge(flat_map<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_map<Key, T, C2, Allocator>&>(source)); }
|
||||
@@ -2219,6 +2257,38 @@ class flat_multimap
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
|
||||
|
||||
//! <b>Effects</b>: Extracts the internal sequence container.
|
||||
//!
|
||||
//! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
//!
|
||||
//! <b>Throws</b>: If secuence_type's move constructor throws
|
||||
sequence_type extract_sequence()
|
||||
{
|
||||
return boost::move(container_detail::force<sequence_type>(m_flat_tree.get_sequence_ref()));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
|
||||
//!
|
||||
//! <b>Throws</b>: If the comparison or the move constructor throws
|
||||
void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->m_flat_tree.adopt_sequence_equal(boost::move(container_detail::force<impl_sequence_type>(seq))); }
|
||||
|
||||
//! <b>Requires</b>: seq shall be ordered according to this->compare().
|
||||
//!
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
|
||||
//!
|
||||
//! <b>Throws</b>: If the move assignment throws
|
||||
void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->m_flat_tree.adopt_sequence_equal(ordered_range_t(), boost::move(container_detail::force<impl_sequence_type>(seq))); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
|
@@ -114,6 +114,7 @@ class flat_set
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::sequence_type) sequence_type;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -623,7 +624,7 @@ class flat_set
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_set<Key, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_set::merge(flat_set<Key, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_set<Key, C2, Allocator>&>(source)); }
|
||||
@@ -633,7 +634,7 @@ class flat_set
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_set::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multiset<Key, C2, Allocator>&>(source)); }
|
||||
@@ -844,8 +845,38 @@ class flat_set
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(flat_set& x, flat_set& y);
|
||||
|
||||
//! <b>Effects</b>: Extracts the internal sequence container.
|
||||
//!
|
||||
//! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
//!
|
||||
//! <b>Throws</b>: If secuence_type's move constructor throws
|
||||
sequence_type extract_sequence();
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment. Erases non-unique elements.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
|
||||
//!
|
||||
//! <b>Throws</b>: If the comparison or the move constructor throws
|
||||
void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_unique(boost::move(seq)); }
|
||||
|
||||
//! <b>Requires</b>: seq shall be ordered according to this->compare()
|
||||
//! and shall contain unique elements.
|
||||
//!
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
|
||||
//!
|
||||
//! <b>Throws</b>: If the move assignment throws
|
||||
void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_unique(ordered_unique_range_t(), boost::move(seq)); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
template<class KeyType>
|
||||
@@ -939,6 +970,7 @@ class flat_multiset
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::sequence_type) sequence_type;
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set()
|
||||
explicit flat_multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
@@ -1392,8 +1424,37 @@ class flat_multiset
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(flat_multiset& x, flat_multiset& y);
|
||||
|
||||
//! <b>Effects</b>: Extracts the internal sequence container.
|
||||
//!
|
||||
//! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
//!
|
||||
//! <b>Throws</b>: If secuence_type's move constructor throws
|
||||
sequence_type extract_sequence();
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
|
||||
//!
|
||||
//! <b>Throws</b>: If the comparison or the move constructor throws
|
||||
void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_equal(boost::move(seq)); }
|
||||
|
||||
//! <b>Requires</b>: seq shall be ordered according to this->compare()
|
||||
//!
|
||||
//! <b>Effects</b>: Discards the internally hold sequence container and adopts the
|
||||
//! one passed externally using the move assignment.
|
||||
//!
|
||||
//! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
|
||||
//!
|
||||
//! <b>Throws</b>: If the move assignment throws
|
||||
void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_equal(ordered_range_t(), boost::move(seq)); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
template <class KeyType>
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/pair_key_mapped_of_value.hpp>
|
||||
|
||||
// move
|
||||
#include <boost/move/traits.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
@@ -53,34 +55,6 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
///@cond
|
||||
|
||||
template<class Key, class Mapped>
|
||||
struct pair_key_mapped_of_value
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef Mapped mapped_type;
|
||||
|
||||
template<class Pair>
|
||||
const key_type & key_of_value(const Pair &p) const
|
||||
{ return p.first; }
|
||||
|
||||
template<class Pair>
|
||||
const mapped_type & mapped_of_value(const Pair &p) const
|
||||
{ return p.second; }
|
||||
|
||||
template<class Pair>
|
||||
key_type & key_of_value(Pair &p) const
|
||||
{ return const_cast<key_type&>(p.first); }
|
||||
|
||||
template<class Pair>
|
||||
mapped_type & mapped_of_value(Pair &p) const
|
||||
{ return p.second; }
|
||||
|
||||
};
|
||||
|
||||
///@endcond
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A map is a kind of associative container that supports unique keys (contains at
|
||||
@@ -150,9 +124,7 @@ class map
|
||||
typedef std::pair<key_type, mapped_type> nonconst_value_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(node_handle<
|
||||
typename base_t::node_type::container_node_type
|
||||
BOOST_MOVE_I value_type
|
||||
BOOST_MOVE_I allocator_type
|
||||
typename base_t::stored_allocator_type
|
||||
BOOST_MOVE_I pair_key_mapped_of_value
|
||||
<key_type BOOST_MOVE_I mapped_type> >) node_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF
|
||||
@@ -1243,9 +1215,7 @@ class multimap
|
||||
typedef std::pair<key_type, mapped_type> nonconst_value_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(node_handle<
|
||||
typename base_t::node_type::container_node_type
|
||||
BOOST_MOVE_I value_type
|
||||
BOOST_MOVE_I allocator_type
|
||||
typename base_t::stored_allocator_type
|
||||
BOOST_MOVE_I pair_key_mapped_of_value
|
||||
<key_type BOOST_MOVE_I mapped_type> >) node_type;
|
||||
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
|
||||
@@ -40,20 +40,34 @@ namespace container {
|
||||
|
||||
///@cond
|
||||
|
||||
template<class Value, class KeyMapped, bool keymapped_is_void = container_detail::is_same<KeyMapped, void>::value>
|
||||
template<class Value, class KeyMapped>
|
||||
struct node_handle_keymapped_traits
|
||||
{
|
||||
typedef typename KeyMapped::key_type key_type;
|
||||
typedef typename KeyMapped::mapped_type mapped_type;
|
||||
};
|
||||
|
||||
template<class Value>
|
||||
struct node_handle_keymapped_traits<Value, void>
|
||||
{
|
||||
typedef Value key_type;
|
||||
typedef Value mapped_type;
|
||||
};
|
||||
|
||||
template<class Value, class KeyMapped>
|
||||
struct node_handle_keymapped_traits<Value, KeyMapped, false>
|
||||
class node_handle_friend
|
||||
{
|
||||
typedef typename KeyMapped::key_type key_type;
|
||||
typedef typename KeyMapped::mapped_type mapped_type;
|
||||
public:
|
||||
|
||||
template<class NH>
|
||||
BOOST_CONTAINER_FORCEINLINE static void destroy_alloc(NH &nh) BOOST_NOEXCEPT
|
||||
{ nh.destroy_alloc(); }
|
||||
|
||||
template<class NH>
|
||||
BOOST_CONTAINER_FORCEINLINE static typename NH::node_pointer &get_node_pointer(NH &nh) BOOST_NOEXCEPT
|
||||
{ return nh.get_node_pointer(); }
|
||||
};
|
||||
|
||||
|
||||
///@endcond
|
||||
|
||||
//! A node_handle is an object that accepts ownership of a single element from an associative container.
|
||||
@@ -73,76 +87,63 @@ struct node_handle_keymapped_traits<Value, KeyMapped, false>
|
||||
//!
|
||||
//! If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container
|
||||
//! when the element was extracted. If a node handle is empty, it contains no allocator.
|
||||
template <class NodeType, class Value, class Allocator, class KeyMapped = void>
|
||||
template <class NodeAllocator, class KeyMapped = void>
|
||||
class node_handle
|
||||
{
|
||||
typedef node_handle_keymapped_traits<Value, KeyMapped> keymapped_t;
|
||||
typedef NodeAllocator nallocator_type;
|
||||
typedef allocator_traits<NodeAllocator> nator_traits;
|
||||
typedef typename nator_traits::value_type priv_node_t;
|
||||
typedef typename priv_node_t::value_type priv_value_t;
|
||||
typedef node_handle_keymapped_traits<priv_value_t, KeyMapped> keymapped_t;
|
||||
|
||||
public:
|
||||
typedef Value value_type;
|
||||
typedef priv_value_t value_type;
|
||||
typedef typename keymapped_t::key_type key_type;
|
||||
typedef typename keymapped_t::mapped_type mapped_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef NodeType container_node_type;
|
||||
typedef typename nator_traits::template portable_rebind_alloc
|
||||
<value_type>::type allocator_type;
|
||||
|
||||
typedef priv_node_t container_node_type;
|
||||
friend class node_handle_friend;
|
||||
|
||||
///@cond
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle)
|
||||
|
||||
typedef allocator_traits<allocator_type> ator_traits;
|
||||
typedef typename ator_traits::template portable_rebind_alloc
|
||||
<container_node_type>::type nallocator_type;
|
||||
typedef allocator_traits<nallocator_type> node_ator_traits;
|
||||
typedef typename node_ator_traits::pointer node_pointer;
|
||||
typedef typename nator_traits::pointer node_pointer;
|
||||
typedef ::boost::aligned_storage
|
||||
<sizeof(allocator_type), boost::alignment_of<nallocator_type>::value> nalloc_storage_t;
|
||||
< sizeof(nallocator_type)
|
||||
, boost::alignment_of<nallocator_type>::value> nalloc_storage_t;
|
||||
|
||||
node_pointer m_ptr;
|
||||
nalloc_storage_t m_nalloc_storage;
|
||||
|
||||
void move_construct_alloc(nallocator_type &al)
|
||||
{ ::new(m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(al)); }
|
||||
{ ::new(m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(::boost::move(al)); }
|
||||
|
||||
void destroy_node()
|
||||
void destroy_deallocate_node()
|
||||
{
|
||||
node_ator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(m_ptr));
|
||||
node_ator_traits::deallocate(this->node_alloc(), m_ptr, 1u);
|
||||
nator_traits::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(m_ptr));
|
||||
nator_traits::deallocate(this->node_alloc(), m_ptr, 1u);
|
||||
}
|
||||
|
||||
template<class OtherNodeHandle>
|
||||
void move_construct_end(OtherNodeHandle &nh)
|
||||
{
|
||||
if(m_ptr){
|
||||
::new (m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(nh.node_alloc()));
|
||||
nh.destroy_alloc();
|
||||
nh.get_node_pointer() = node_pointer();
|
||||
::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(::boost::move(nh.node_alloc()));
|
||||
node_handle_friend::destroy_alloc(nh);
|
||||
node_handle_friend::get_node_pointer(nh) = node_pointer();
|
||||
}
|
||||
BOOST_ASSERT(nh.empty());
|
||||
}
|
||||
|
||||
public:
|
||||
void destroy_alloc() BOOST_NOEXCEPT
|
||||
{ static_cast<nallocator_type*>(m_nalloc_storage.address())->~nallocator_type(); }
|
||||
|
||||
void destroy_alloc()
|
||||
{ static_cast<allocator_type*>(m_nalloc_storage.address())->~allocator_type(); }
|
||||
|
||||
node_pointer &get_node_pointer()
|
||||
node_pointer &get_node_pointer() BOOST_NOEXCEPT
|
||||
{ return m_ptr; }
|
||||
|
||||
nallocator_type &node_alloc()
|
||||
{ return *static_cast<nallocator_type*>(m_nalloc_storage.address()); }
|
||||
|
||||
const nallocator_type &node_alloc() const
|
||||
{ return *static_cast<const nallocator_type*>(m_nalloc_storage.address()); }
|
||||
|
||||
node_pointer release()
|
||||
{
|
||||
node_pointer p(m_ptr);
|
||||
m_ptr = node_pointer();
|
||||
if(p)
|
||||
this->destroy_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
///@endcond
|
||||
|
||||
public:
|
||||
@@ -150,13 +151,13 @@ class node_handle
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT
|
||||
: m_ptr(), m_nalloc_storage()
|
||||
{ BOOST_ASSERT(this->empty()); }
|
||||
: m_ptr()
|
||||
{ }
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with p.
|
||||
//! If p != nullptr copy constructs internal allocator al.
|
||||
//! If p != nullptr copy constructs internal allocator from al.
|
||||
node_handle(node_pointer p, const nallocator_type &al) BOOST_NOEXCEPT
|
||||
: m_ptr(p), m_nalloc_storage()
|
||||
: m_ptr(p)
|
||||
{
|
||||
if(m_ptr){
|
||||
::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(al);
|
||||
@@ -172,12 +173,12 @@ class node_handle
|
||||
//! <b>Note</b>: Two node_handle's are related if only one of KeyMapped template parameter
|
||||
//! of a node handle is void.
|
||||
template<class KeyMapped2>
|
||||
node_handle( BOOST_RV_REF_BEG node_handle<NodeType, Value, Allocator, KeyMapped2> BOOST_RV_REF_END nh
|
||||
node_handle( BOOST_RV_REF_BEG node_handle<NodeAllocator, KeyMapped2> BOOST_RV_REF_END nh
|
||||
, typename container_detail::enable_if_c
|
||||
< ((unsigned)container_detail::is_same<KeyMapped, void>::value +
|
||||
(unsigned)container_detail::is_same<KeyMapped2, void>::value) == 1u
|
||||
>::type* = 0)
|
||||
: m_ptr(nh.get_node_pointer()), m_nalloc_storage()
|
||||
>::type* = 0) BOOST_NOEXCEPT
|
||||
: m_ptr(nh.get())
|
||||
{ this->move_construct_end(nh); }
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with nh's internal pointer
|
||||
@@ -186,43 +187,44 @@ class node_handle
|
||||
//!
|
||||
//! <b>Postcondition</b>: nh.empty()
|
||||
node_handle (BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT
|
||||
: m_ptr(nh.m_ptr), m_nalloc_storage()
|
||||
: m_ptr(nh.m_ptr)
|
||||
{ this->move_construct_end(nh); }
|
||||
|
||||
//! <b>Effects</b>: If !this->empty(), destroys the value_type subobject in the container_node_type object
|
||||
//! pointed to by c by calling allocator_traits<impl_defined>::destroy, then deallocates m_ptr by calling
|
||||
//! ator_traits::rebind_traits<container_node_type>::deallocate.
|
||||
~node_handle () BOOST_NOEXCEPT
|
||||
//! nator_traits::rebind_traits<container_node_type>::deallocate.
|
||||
~node_handle() BOOST_NOEXCEPT
|
||||
{
|
||||
if(!this->empty()){
|
||||
this->destroy_node();
|
||||
this->destroy_deallocate_node();
|
||||
this->destroy_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: Either this->empty(), or ator_traits::propagate_on_container_move_assignment is true, or
|
||||
//! <b>Requires</b>: Either this->empty(), or nator_traits::propagate_on_container_move_assignment is true, or
|
||||
//! node_alloc() == nh.node_alloc().
|
||||
//!
|
||||
//! <b>Effects</b>: If m_ptr != nullptr, destroys the value_type subobject in the container_node_type object
|
||||
//! pointed to by m_ptr by calling ator_traits::destroy, then deallocates m_ptr by calling ator_-
|
||||
//! traits::rebind_traits<container_node_type>::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty()
|
||||
//! or ator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to
|
||||
//! pointed to by m_ptr by calling nator_traits::destroy, then deallocates m_ptr by calling
|
||||
//! nator_traits::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty()
|
||||
//! or nator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to
|
||||
//! node_alloc(). Assigns nullptr to nh.m_ptr and assigns nullopt to nh.node_alloc().
|
||||
//!
|
||||
//! <b>Returns</b>: *this.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
node_handle & operator=(BOOST_RV_REF(node_handle) nh)
|
||||
node_handle & operator=(BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_move_assignment::value
|
||||
|| ator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
BOOST_ASSERT(this->empty() || nator_traits::propagate_on_container_move_assignment::value
|
||||
|| nator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
|
||||
bool const was_this_non_null = !this->empty();
|
||||
bool const was_nh_non_null = !nh.empty();
|
||||
|
||||
if(was_nh_non_null){
|
||||
if(was_this_non_null){
|
||||
this->destroy_node();
|
||||
if(ator_traits::propagate_on_container_move_assignment::value){
|
||||
this->destroy_deallocate_node();
|
||||
if(nator_traits::propagate_on_container_move_assignment::value){
|
||||
this->node_alloc() = ::boost::move(nh.node_alloc());
|
||||
}
|
||||
}
|
||||
@@ -234,7 +236,7 @@ class node_handle
|
||||
nh.destroy_alloc();
|
||||
}
|
||||
else if(was_this_non_null){
|
||||
this->destroy_node();
|
||||
this->destroy_deallocate_node();
|
||||
this->destroy_alloc();
|
||||
m_ptr = node_pointer();
|
||||
}
|
||||
@@ -310,23 +312,23 @@ class node_handle
|
||||
return !this->m_ptr;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: this->empty(), or nh.empty(), or ator_traits::propagate_on_container_swap is true, or
|
||||
//! <b>Requires</b>: this->empty(), or nh.empty(), or nator_traits::propagate_on_container_swap is true, or
|
||||
//! node_alloc() == nh.node_alloc().
|
||||
//!
|
||||
//! <b>Effects</b>: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or ator_traits::propagate_on_-
|
||||
//! <b>Effects</b>: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or nator_traits::propagate_on_-
|
||||
//! container_swap is true calls swap(node_alloc(), nh.node_alloc()).
|
||||
void swap(node_handle &nh)
|
||||
BOOST_NOEXCEPT_IF(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value)
|
||||
BOOST_NOEXCEPT_IF(nator_traits::propagate_on_container_swap::value || nator_traits::is_always_equal::value)
|
||||
{
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_swap::value
|
||||
|| ator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || nator_traits::propagate_on_container_swap::value
|
||||
|| nator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
|
||||
bool const was_this_non_null = !this->empty();
|
||||
bool const was_nh_non_null = !nh.empty();
|
||||
|
||||
if(was_nh_non_null){
|
||||
if(was_this_non_null){
|
||||
if(ator_traits::propagate_on_container_swap::value){
|
||||
if(nator_traits::propagate_on_container_swap::value){
|
||||
::boost::adl_move_swap(this->node_alloc(), nh.node_alloc());
|
||||
}
|
||||
}
|
||||
@@ -337,11 +339,53 @@ class node_handle
|
||||
}
|
||||
else if(was_this_non_null){
|
||||
nh.move_construct_alloc(this->node_alloc());
|
||||
nh.destroy_alloc();
|
||||
this->destroy_alloc();
|
||||
}
|
||||
::boost::adl_move_swap(m_ptr, nh.m_ptr);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: If this->empty() returns nullptr, otherwise returns m_ptr
|
||||
//! resets m_ptr to nullptr and destroys the internal allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extensions
|
||||
node_pointer release() BOOST_NOEXCEPT
|
||||
{
|
||||
node_pointer p(m_ptr);
|
||||
m_ptr = node_pointer();
|
||||
if(p)
|
||||
this->destroy_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns m_ptr.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extensions
|
||||
node_pointer get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns a reference to the internal node allocator.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extensions
|
||||
nallocator_type &node_alloc() BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
return *static_cast<nallocator_type*>(m_nalloc_storage.address());
|
||||
}
|
||||
|
||||
|
||||
//! <b>Effects</b>: Returns a reference to the internal node allocator.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extensions
|
||||
const nallocator_type &node_alloc() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
return *static_cast<const nallocator_type*>(m_nalloc_storage.address());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: x.swap(y).
|
||||
//!
|
||||
friend void swap(node_handle & x, node_handle & y) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
|
||||
|
@@ -387,8 +387,8 @@ class small_vector_base
|
||||
this->steal_resources(x);
|
||||
}
|
||||
else{
|
||||
this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin()))
|
||||
, boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end ()))
|
||||
this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
|
||||
, boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end ()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
// intrusive
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
@@ -1975,7 +1975,7 @@ class stable_vector
|
||||
, container_detail::addressof(p->value)
|
||||
, it);
|
||||
//This does not throw
|
||||
::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t())
|
||||
::new(static_cast<node_base_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t())
|
||||
node_base_type(index_traits_type::ptr_to_node_base_ptr(*up_index));
|
||||
}
|
||||
|
||||
@@ -1988,7 +1988,7 @@ class stable_vector
|
||||
, container_detail::addressof(p->value)
|
||||
, ::boost::forward<ValueConvertible>(value_convertible));
|
||||
//This does not throw
|
||||
::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) node_base_type;
|
||||
::new(static_cast<node_base_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) node_base_type;
|
||||
}
|
||||
|
||||
void priv_swap_members(stable_vector &x)
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include <boost/container/detail/min_max.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/next_capacity.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/minimal_char_traits_header.hpp>
|
||||
@@ -308,14 +308,14 @@ class basic_string_base
|
||||
{
|
||||
allocator_traits_type::construct
|
||||
( this->alloc()
|
||||
, container_detail::to_raw_pointer(p)
|
||||
, boost::movelib::to_raw_pointer(p)
|
||||
, value
|
||||
);
|
||||
}
|
||||
|
||||
void destroy(pointer p, size_type n)
|
||||
{
|
||||
value_type *raw_p = container_detail::to_raw_pointer(p);
|
||||
value_type *raw_p = boost::movelib::to_raw_pointer(p);
|
||||
for(; n--; ++raw_p){
|
||||
allocator_traits_type::destroy( this->alloc(), raw_p);
|
||||
}
|
||||
@@ -325,7 +325,7 @@ class basic_string_base
|
||||
{
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
, container_detail::to_raw_pointer(p)
|
||||
, boost::movelib::to_raw_pointer(p)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1158,8 +1158,8 @@ class basic_string
|
||||
size_type long_storage = this->priv_long_storage();
|
||||
size_type long_size = this->priv_long_size();
|
||||
//Shrink from allocated buffer to the internal one, including trailing null
|
||||
Traits::copy( container_detail::to_raw_pointer(this->priv_short_addr())
|
||||
, container_detail::to_raw_pointer(long_addr)
|
||||
Traits::copy( boost::movelib::to_raw_pointer(this->priv_short_addr())
|
||||
, boost::movelib::to_raw_pointer(long_addr)
|
||||
, long_size+1);
|
||||
this->is_short(true);
|
||||
this->alloc().deallocate(long_addr, long_storage);
|
||||
@@ -1492,7 +1492,7 @@ class basic_string
|
||||
{
|
||||
size_type n = static_cast<size_type>(last - first);
|
||||
this->reserve(n);
|
||||
CharT* ptr = container_detail::to_raw_pointer(this->priv_addr());
|
||||
CharT* ptr = boost::movelib::to_raw_pointer(this->priv_addr());
|
||||
Traits::copy(ptr, first, n);
|
||||
this->priv_construct_null(ptr + n);
|
||||
this->priv_size(n);
|
||||
@@ -1511,7 +1511,7 @@ class basic_string
|
||||
{
|
||||
size_type cur = 0;
|
||||
const pointer addr = this->priv_addr();
|
||||
CharT *ptr = container_detail::to_raw_pointer(addr);
|
||||
CharT *ptr = boost::movelib::to_raw_pointer(addr);
|
||||
const size_type old_size = this->priv_size();
|
||||
while (first != last && cur != old_size) {
|
||||
Traits::assign(*ptr, *first);
|
||||
@@ -1570,7 +1570,7 @@ class basic_string
|
||||
size_type len = container_detail::min_value(n, str_size - pos2);
|
||||
if (sz > this->max_size() - len)
|
||||
throw_length_error("basic_string::insert max_size() exceeded");
|
||||
const CharT *beg_ptr = container_detail::to_raw_pointer(s.begin()) + pos2;
|
||||
const CharT *beg_ptr = boost::movelib::to_raw_pointer(s.begin()) + pos2;
|
||||
const CharT *end_ptr = beg_ptr + len;
|
||||
this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr);
|
||||
return *this;
|
||||
@@ -1730,10 +1730,10 @@ class basic_string
|
||||
pointer_past_last, pointer_past_last);
|
||||
|
||||
this->priv_size(old_size+n);
|
||||
Traits::move(const_cast<CharT*>(container_detail::to_raw_pointer(p + n)),
|
||||
container_detail::to_raw_pointer(p),
|
||||
Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + n)),
|
||||
boost::movelib::to_raw_pointer(p),
|
||||
(elems_after - n) + 1);
|
||||
this->priv_copy(first, last, const_cast<CharT*>(container_detail::to_raw_pointer(p)));
|
||||
this->priv_copy(first, last, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
|
||||
}
|
||||
else {
|
||||
ForwardIter mid = first;
|
||||
@@ -1746,7 +1746,7 @@ class basic_string
|
||||
(p, const_iterator(old_start + old_length + 1),
|
||||
old_start + newer_size);
|
||||
this->priv_size(newer_size + elems_after);
|
||||
this->priv_copy(first, mid, const_cast<CharT*>(container_detail::to_raw_pointer(p)));
|
||||
this->priv_copy(first, mid, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -1773,9 +1773,9 @@ class basic_string
|
||||
else{
|
||||
//value_type is POD, so backwards expansion is much easier
|
||||
//than with vector<T>
|
||||
value_type * const oldbuf = container_detail::to_raw_pointer(old_start);
|
||||
value_type * const newbuf = container_detail::to_raw_pointer(new_start);
|
||||
const value_type *const pos = container_detail::to_raw_pointer(p);
|
||||
value_type * const oldbuf = boost::movelib::to_raw_pointer(old_start);
|
||||
value_type * const newbuf = boost::movelib::to_raw_pointer(new_start);
|
||||
const value_type *const pos = boost::movelib::to_raw_pointer(p);
|
||||
const size_type before = pos - oldbuf;
|
||||
|
||||
//First move old data
|
||||
@@ -1847,10 +1847,10 @@ class basic_string
|
||||
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
// The move includes the terminating null.
|
||||
CharT * const ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p));
|
||||
CharT * const ptr = const_cast<CharT*>(boost::movelib::to_raw_pointer(p));
|
||||
const size_type old_size = this->priv_size();
|
||||
Traits::move(ptr,
|
||||
container_detail::to_raw_pointer(p + 1),
|
||||
boost::movelib::to_raw_pointer(p + 1),
|
||||
old_size - (p - this->priv_addr()));
|
||||
this->priv_size(old_size-1);
|
||||
return iterator(ptr);
|
||||
@@ -1866,12 +1866,12 @@ class basic_string
|
||||
//! the other elements being erased. If no such element exists, end() is returned.
|
||||
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first));
|
||||
CharT * f = const_cast<CharT*>(boost::movelib::to_raw_pointer(first));
|
||||
if (first != last) { // The move includes the terminating null.
|
||||
const size_type num_erased = last - first;
|
||||
const size_type old_size = this->priv_size();
|
||||
Traits::move(f,
|
||||
container_detail::to_raw_pointer(last),
|
||||
boost::movelib::to_raw_pointer(last),
|
||||
(old_size + 1)-(last - this->priv_addr()));
|
||||
const size_type new_length = old_size - num_erased;
|
||||
this->priv_size(new_length);
|
||||
@@ -2059,11 +2059,11 @@ class basic_string
|
||||
{
|
||||
const size_type len = static_cast<size_type>(i2 - i1);
|
||||
if (len >= n) {
|
||||
Traits::assign(const_cast<CharT*>(container_detail::to_raw_pointer(i1)), n, c);
|
||||
Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), n, c);
|
||||
erase(i1 + n, i2);
|
||||
}
|
||||
else {
|
||||
Traits::assign(const_cast<CharT*>(container_detail::to_raw_pointer(i1)), len, c);
|
||||
Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), len, c);
|
||||
insert(i2, n - len, c);
|
||||
}
|
||||
return *this;
|
||||
@@ -2088,7 +2088,7 @@ class basic_string
|
||||
)
|
||||
{
|
||||
for ( ; i1 != i2 && j1 != j2; ++i1, ++j1){
|
||||
Traits::assign(*const_cast<CharT*>(container_detail::to_raw_pointer(i1)), *j1);
|
||||
Traits::assign(*const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), *j1);
|
||||
}
|
||||
|
||||
if (j1 == j2)
|
||||
@@ -2111,13 +2111,13 @@ class basic_string
|
||||
difference_type n = boost::container::iterator_distance(j1, j2);
|
||||
const difference_type len = i2 - i1;
|
||||
if (len >= n) {
|
||||
this->priv_copy(j1, j2, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
|
||||
this->priv_copy(j1, j2, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)));
|
||||
this->erase(i1 + n, i2);
|
||||
}
|
||||
else {
|
||||
ForwardIter m = j1;
|
||||
boost::container::iterator_advance(m, len);
|
||||
this->priv_copy(j1, m, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
|
||||
this->priv_copy(j1, m, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)));
|
||||
this->insert(i2, m, j2);
|
||||
}
|
||||
return *this;
|
||||
@@ -2128,7 +2128,7 @@ class basic_string
|
||||
//!
|
||||
//! <b>Effects</b>: Calls `replace(i1 - begin(), i2 - i1, sv).`.
|
||||
//!
|
||||
//! <bReturns</b>: *this.
|
||||
//! <b>Returns</b>: *this.
|
||||
template<template <class, class> class BasicStringView>
|
||||
basic_string& replace(const_iterator i1, const_iterator i2, BasicStringView<CharT, Traits> sv)
|
||||
{
|
||||
@@ -2141,7 +2141,7 @@ class basic_string
|
||||
//!
|
||||
//! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()).
|
||||
//!
|
||||
//! <bReturns</b>: *this.
|
||||
//! <b>Returns</b>: *this.
|
||||
basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il)
|
||||
{
|
||||
return this->replace( static_cast<size_type>(i1 - this->cbegin())
|
||||
@@ -2166,7 +2166,7 @@ class basic_string
|
||||
if (pos > this->size())
|
||||
throw_out_of_range("basic_string::copy out of range position");
|
||||
const size_type len = container_detail::min_value(n, this->size() - pos);
|
||||
Traits::copy(s, container_detail::to_raw_pointer(this->priv_addr() + pos), len);
|
||||
Traits::copy(s, boost::movelib::to_raw_pointer(this->priv_addr() + pos), len);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -2195,7 +2195,7 @@ class basic_string
|
||||
//!
|
||||
//! <b>Complexity</b>: constant time.
|
||||
const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::to_raw_pointer(this->priv_addr()); }
|
||||
{ return boost::movelib::to_raw_pointer(this->priv_addr()); }
|
||||
|
||||
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
|
||||
//!
|
||||
@@ -2203,13 +2203,13 @@ class basic_string
|
||||
//!
|
||||
//! <b>Complexity</b>: constant time.
|
||||
const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::to_raw_pointer(this->priv_addr()); }
|
||||
{ return boost::movelib::to_raw_pointer(this->priv_addr()); }
|
||||
|
||||
//! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
|
||||
//!
|
||||
//! <b>Complexity</b>: constant time.
|
||||
CharT* data() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::to_raw_pointer(this->priv_addr()); }
|
||||
{ return boost::movelib::to_raw_pointer(this->priv_addr()); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
|
||||
//! <b>Returns</b>: a string_view to the characters in the string.
|
||||
@@ -2272,8 +2272,8 @@ class basic_string
|
||||
const pointer addr = this->priv_addr();
|
||||
pointer finish = addr + this->priv_size();
|
||||
const const_iterator result =
|
||||
std::search(container_detail::to_raw_pointer(addr + pos),
|
||||
container_detail::to_raw_pointer(finish),
|
||||
std::search(boost::movelib::to_raw_pointer(addr + pos),
|
||||
boost::movelib::to_raw_pointer(finish),
|
||||
s, s + n, Eq_traits<Traits>());
|
||||
return result != finish ? result - begin() : npos;
|
||||
}
|
||||
@@ -2804,8 +2804,8 @@ class basic_string
|
||||
{
|
||||
const difference_type n1 = l1 - f1;
|
||||
const difference_type n2 = l2 - f2;
|
||||
const int cmp = Traits::compare(container_detail::to_raw_pointer(f1),
|
||||
container_detail::to_raw_pointer(f2),
|
||||
const int cmp = Traits::compare(boost::movelib::to_raw_pointer(f1),
|
||||
boost::movelib::to_raw_pointer(f2),
|
||||
container_detail::min_value(n1, n2));
|
||||
return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
|
||||
}
|
||||
@@ -2826,8 +2826,8 @@ class basic_string
|
||||
real_cap = long_size+1;
|
||||
const pointer ret = this->allocation_command(allocate_new, long_size+1, real_cap, reuse);
|
||||
//Copy and update
|
||||
Traits::copy( container_detail::to_raw_pointer(ret)
|
||||
, container_detail::to_raw_pointer(this->priv_long_addr())
|
||||
Traits::copy( boost::movelib::to_raw_pointer(ret)
|
||||
, boost::movelib::to_raw_pointer(this->priv_long_addr())
|
||||
, long_size+1);
|
||||
this->priv_long_addr(ret);
|
||||
this->priv_storage(real_cap);
|
||||
|
@@ -36,10 +36,10 @@
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/next_capacity.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
// intrusive
|
||||
@@ -54,6 +54,10 @@
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
#include <boost/move/detail/move_helpers.hpp>
|
||||
// move/algo
|
||||
#include <boost/move/algo/adaptive_merge.hpp>
|
||||
#include <boost/move/algo/unique.hpp>
|
||||
#include <boost/move/algo/predicate.hpp>
|
||||
// other
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@@ -609,7 +613,7 @@ struct vector_alloc_holder<Allocator, version_0>
|
||||
, 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, container_detail::to_raw_pointer(this->start()));
|
||||
(this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start()));
|
||||
}
|
||||
|
||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
||||
@@ -621,7 +625,7 @@ struct vector_alloc_holder<Allocator, version_0>
|
||||
const size_type n = holder.m_size;
|
||||
this->priv_first_allocation(n);
|
||||
::boost::container::uninitialized_move_alloc_n
|
||||
(this->alloc(), container_detail::to_raw_pointer(holder.start()), n, container_detail::to_raw_pointer(this->start()));
|
||||
(this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start()));
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_first_allocation(size_type cap)
|
||||
@@ -675,8 +679,8 @@ struct vector_alloc_holder<Allocator, version_0>
|
||||
void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
|
||||
{
|
||||
const size_type 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());
|
||||
value_type *const first_this = boost::movelib::to_raw_pointer(this->start());
|
||||
value_type *const first_x = boost::movelib::to_raw_pointer(x.start());
|
||||
|
||||
if(this->m_size < x.m_size){
|
||||
boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_this, this->m_size, first_x, x.m_size);
|
||||
@@ -1186,7 +1190,7 @@ class vector
|
||||
if (first == last){
|
||||
//There are no more elements in the sequence, erase remaining
|
||||
T* const end_pos = this->priv_raw_end();
|
||||
const size_type n = static_cast<size_type>(end_pos - container_detail::iterator_to_raw_pointer(cur));
|
||||
const size_type n = static_cast<size_type>(end_pos - boost::movelib::iterator_to_raw_pointer(cur));
|
||||
this->priv_destroy_last_n(n);
|
||||
}
|
||||
else{
|
||||
@@ -2005,7 +2009,7 @@ class vector
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range(position));
|
||||
const pointer p = vector_iterator_get_ptr(position);
|
||||
T *const pos_ptr = container_detail::to_raw_pointer(p);
|
||||
T *const pos_ptr = boost::movelib::to_raw_pointer(p);
|
||||
T *const beg_ptr = this->priv_raw_begin();
|
||||
T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr);
|
||||
//Move elements forward and destroy last
|
||||
@@ -2025,9 +2029,9 @@ class vector
|
||||
(first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
|
||||
if (first != last){
|
||||
T* const old_end_ptr = this->priv_raw_end();
|
||||
T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first));
|
||||
T* const last_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(last));
|
||||
T* const ptr = container_detail::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
|
||||
T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first));
|
||||
T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last));
|
||||
T* const ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
|
||||
this->priv_destroy_last_n(old_end_ptr - ptr);
|
||||
}
|
||||
return iterator(vector_iterator_get_ptr(first));
|
||||
@@ -2240,37 +2244,15 @@ class vector
|
||||
p = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p);
|
||||
this->priv_merge_in_new_buffer(UniqueBool(), first, n, comp, p, new_cap);
|
||||
}
|
||||
else if(!UniqueBool::value && free_c >= n){
|
||||
typedef container_detail::vector_merge_cursor<T, size_type, BidirIt, Compare> inserter_t;
|
||||
T* const pbeg = this->priv_raw_begin();
|
||||
return this->priv_insert_ordered_at(n, inserter_t(pbeg, pbeg + s, last, comp));
|
||||
}
|
||||
else{ //UniqueBool::value == true and free_c >= n
|
||||
std::size_t remaining = n;
|
||||
static const std::size_t PosCount = 64u;
|
||||
size_type positions[PosCount];
|
||||
size_type *indexes = 0;
|
||||
while(remaining){
|
||||
//Query for room to store indexes in the remaining buffer
|
||||
boost::uintptr_t const szt_align_mask = container_detail::alignment_of<size_type>::value - 1;
|
||||
boost::uintptr_t const addr = boost::uintptr_t(this->priv_raw_begin() + s + n);
|
||||
boost::uintptr_t const capaddr = boost::uintptr_t(this->priv_raw_begin() + c);
|
||||
boost::uintptr_t const aligned_addr = (addr + szt_align_mask) & ~szt_align_mask;
|
||||
indexes = reinterpret_cast<size_type *>(aligned_addr);
|
||||
std::size_t index_capacity = (aligned_addr >= capaddr) ? 0u : (capaddr - aligned_addr)/sizeof(size_type);
|
||||
|
||||
//Capacity is constant, we're not going to change it
|
||||
if(index_capacity < PosCount){
|
||||
indexes = positions;
|
||||
index_capacity = PosCount;
|
||||
}
|
||||
if(index_capacity > remaining)
|
||||
index_capacity = remaining;
|
||||
BidirIt limit = first;
|
||||
boost::container::iterator_advance(limit, index_capacity);
|
||||
this->priv_insert_ordered_range(UniqueBool(), index_capacity, first, limit, indexes, comp);
|
||||
first = limit;
|
||||
remaining -= index_capacity;
|
||||
else{
|
||||
T *raw_pos = boost::movelib::iterator_to_raw_pointer(this->insert(this->cend(), first, last));
|
||||
T *raw_beg = this->priv_raw_begin();
|
||||
T *raw_end = this->priv_raw_end();
|
||||
boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_c - n);
|
||||
if(UniqueBool::value){
|
||||
size_type const count =
|
||||
static_cast<size_type>(raw_end - boost::movelib::unique(raw_beg, raw_end, boost::movelib::negate<Compare>(comp)));
|
||||
this->priv_destroy_last_n(count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2279,53 +2261,6 @@ class vector
|
||||
}
|
||||
}
|
||||
|
||||
template <class UniqueBool, class BidirIt, class Compare>
|
||||
void priv_insert_ordered_range
|
||||
(UniqueBool, size_type const n, BidirIt first, BidirIt const last, size_type positions[], Compare comp)
|
||||
{
|
||||
//Linear: at most N + M -1 comparisons
|
||||
//Log: MlogN
|
||||
//Average
|
||||
//Linear: N + M - 2
|
||||
//Log: MlogN
|
||||
//N+M - 2
|
||||
//N
|
||||
//(N+M)/2 < MlogN
|
||||
//(N/M+1)/2 <= logN
|
||||
//bool const linear = !s || !n || (s <= n) || ((s+n)/n/2 < logN);
|
||||
size_type const s = this->size();
|
||||
size_type remaining = n;
|
||||
T* const pbeg = this->priv_raw_begin();
|
||||
T* const pend = pbeg + s;
|
||||
T* pcur = pbeg;
|
||||
size_type *position = positions;
|
||||
size_type added_in_middle = 0;
|
||||
if(first != last && pcur != pend){
|
||||
while(1){
|
||||
//maintain stability moving external values only if they are strictly less
|
||||
if(comp(*first, *pcur)) {
|
||||
*position = static_cast<size_type>(pcur - pbeg);
|
||||
BOOST_ASSERT((position == positions) || (*(position-1) == size_type(-1)) || (*(position-1) <= *position));
|
||||
++position;
|
||||
++added_in_middle;
|
||||
--remaining;
|
||||
if(++first == last) break;
|
||||
}
|
||||
else if(UniqueBool::value && !comp(*pcur, *first)){
|
||||
*position = size_type(-1);
|
||||
++position;
|
||||
--remaining;
|
||||
if(++first == last) break;
|
||||
}
|
||||
else{
|
||||
if(++pcur == pend) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->insert_ordered_at(added_in_middle, position, first);
|
||||
this->insert(this->cend(), remaining, first, last);
|
||||
}
|
||||
|
||||
template<class UniqueBool, class FwdIt, class Compare>
|
||||
void priv_merge_in_new_buffer
|
||||
(UniqueBool, FwdIt first, size_type n, Compare comp, pointer new_storage, size_type const new_cap)
|
||||
@@ -2337,7 +2272,7 @@ class vector
|
||||
T* pbeg = this->priv_raw_begin();
|
||||
size_type const old_size = this->size();
|
||||
T* const pend = pbeg + old_size;
|
||||
T* d_first = container_detail::to_raw_pointer(new_storage);
|
||||
T* d_first = boost::movelib::to_raw_pointer(new_storage);
|
||||
size_type added = n;
|
||||
//Merge in new buffer loop
|
||||
while(1){
|
||||
@@ -2373,7 +2308,7 @@ class vector
|
||||
//Nothrow operations
|
||||
pointer const old_p = this->m_holder.start();
|
||||
size_type const old_cap = this->m_holder.capacity();
|
||||
boost::container::destroy_alloc_n(a, container_detail::to_raw_pointer(old_p), old_size);
|
||||
boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size);
|
||||
a.deallocate(old_p, old_cap);
|
||||
this->m_holder.m_size = old_size + added;
|
||||
this->m_holder.start(new_storage);
|
||||
@@ -2444,8 +2379,8 @@ class vector
|
||||
}
|
||||
//Else do a one by one move
|
||||
else{
|
||||
this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin()))
|
||||
, boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end() ))
|
||||
this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
|
||||
, boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end() ))
|
||||
);
|
||||
}
|
||||
//Move allocator if needed
|
||||
@@ -2514,8 +2449,8 @@ class vector
|
||||
}
|
||||
//... and move-insert the remaining range
|
||||
sml.insert( sml.cend()
|
||||
, boost::make_move_iterator(container_detail::iterator_to_raw_pointer(big.nth(common_elements)))
|
||||
, boost::make_move_iterator(container_detail::iterator_to_raw_pointer(big.end()))
|
||||
, boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements)))
|
||||
, boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end()))
|
||||
);
|
||||
//Destroy remaining elements
|
||||
big.erase(big.nth(common_elements), big.cend());
|
||||
@@ -2540,7 +2475,7 @@ class vector
|
||||
pointer const p = allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start);
|
||||
//We will reuse insert code, so create a dummy input iterator
|
||||
this->priv_forward_range_insert_new_allocation
|
||||
( container_detail::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
|
||||
( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
|
||||
}
|
||||
|
||||
void priv_reserve_no_capacity(size_type new_cap, version_2)
|
||||
@@ -2561,7 +2496,7 @@ class vector
|
||||
this->m_holder.capacity(real_cap);
|
||||
}
|
||||
else{ //If there is no forward expansion, move objects, we will reuse insertion code
|
||||
T * const new_mem = container_detail::to_raw_pointer(ret);
|
||||
T * const new_mem = boost::movelib::to_raw_pointer(ret);
|
||||
T * const ins_pos = this->priv_raw_end();
|
||||
if(reuse){ //Backwards (and possibly forward) expansion
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
@@ -2691,7 +2626,7 @@ class vector
|
||||
++this->num_alloc;
|
||||
#endif
|
||||
this->priv_forward_range_insert_new_allocation
|
||||
( container_detail::to_raw_pointer(p), sz
|
||||
( boost::movelib::to_raw_pointer(p), sz
|
||||
, this->priv_raw_begin(), 0, this->priv_dummy_empty_proxy());
|
||||
}
|
||||
}
|
||||
@@ -2735,11 +2670,11 @@ class vector
|
||||
{
|
||||
//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);
|
||||
T *const raw_pos = boost::movelib::to_raw_pointer(pos);
|
||||
|
||||
const size_type new_cap = this->m_holder.next_capacity(n);
|
||||
//Pass the hint so that allocators can take advantage of this.
|
||||
T * const new_buf = container_detail::to_raw_pointer
|
||||
T * const new_buf = boost::movelib::to_raw_pointer
|
||||
(allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start));
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
++this->num_alloc;
|
||||
@@ -2754,7 +2689,7 @@ class vector
|
||||
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2)
|
||||
{
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
T *const raw_pos = boost::movelib::to_raw_pointer(pos);
|
||||
const size_type n_pos = raw_pos - this->priv_raw_begin();
|
||||
|
||||
//There is not enough memory, allocate a new
|
||||
@@ -2781,7 +2716,7 @@ class vector
|
||||
++this->num_expand_bwd;
|
||||
#endif
|
||||
this->priv_forward_range_insert_expand_backwards
|
||||
(container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
|
||||
(boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
|
||||
}
|
||||
}
|
||||
//New buffer
|
||||
@@ -2790,7 +2725,7 @@ class vector
|
||||
++this->num_alloc;
|
||||
#endif
|
||||
this->priv_forward_range_insert_new_allocation
|
||||
( container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
|
||||
( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
|
||||
}
|
||||
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
@@ -2810,7 +2745,7 @@ class vector
|
||||
}
|
||||
else{
|
||||
//Expand forward
|
||||
T *const raw_pos = container_detail::to_raw_pointer(pos);
|
||||
T *const raw_pos = boost::movelib::to_raw_pointer(pos);
|
||||
const size_type n_pos = raw_pos - this->priv_raw_begin();
|
||||
this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
|
||||
return iterator(this->m_holder.start() + n_pos);
|
||||
@@ -2926,10 +2861,10 @@ class vector
|
||||
}
|
||||
|
||||
private:
|
||||
T *priv_raw_begin() const
|
||||
{ return container_detail::to_raw_pointer(m_holder.start()); }
|
||||
BOOST_CONTAINER_FORCEINLINE T *priv_raw_begin() const
|
||||
{ return boost::movelib::to_raw_pointer(m_holder.start()); }
|
||||
|
||||
T* priv_raw_end() const
|
||||
BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() const
|
||||
{ return this->priv_raw_begin() + this->m_holder.m_size; }
|
||||
|
||||
template <class InsertionProxy>
|
||||
|
@@ -311,6 +311,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "string_view_compat_test", "
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tree_test", "tree_test.vcproj", "{5CE185C3-2609-4FA5-FE38-792BA0D3A606}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -629,6 +633,10 @@ Global
|
||||
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.Build.0 = Release|Win32
|
||||
{5CE185C3-2609-4FA5-FE38-792BA0D3A606}.Debug.ActiveCfg = Debug|Win32
|
||||
{5CE185C3-2609-4FA5-FE38-792BA0D3A606}.Debug.Build.0 = Debug|Win32
|
||||
{5CE185C3-2609-4FA5-FE38-792BA0D3A606}.Release.ActiveCfg = Release|Win32
|
||||
{5CE185C3-2609-4FA5-FE38-792BA0D3A606}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
135
proj/vc7ide/tree_test.vcproj
Normal file
135
proj/vc7ide/tree_test.vcproj
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="tree_test"
|
||||
ProjectGUID="{5CE185C3-2609-4FA5-FE38-792BA0D3A606}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/tree_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/tree_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/tree_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/tree_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/tree_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{F737FB31-066C-4617-A7A5-23F0B5212FB7}">
|
||||
<File
|
||||
RelativePath="..\..\test\tree_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@@ -224,6 +224,116 @@ bool flat_tree_ordered_insertion_test()
|
||||
return true;
|
||||
}
|
||||
|
||||
template< class RandomIt >
|
||||
void random_shuffle( RandomIt first, RandomIt last )
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<RandomIt>::difference_type difference_type;
|
||||
difference_type n = last - first;
|
||||
for (difference_type i = n-1; i > 0; --i) {
|
||||
difference_type j = std::rand() % (i+1);
|
||||
if(j != i) {
|
||||
boost::adl_move_swap(first[i], first[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool flat_tree_extract_adopt_test()
|
||||
{
|
||||
using namespace boost::container;
|
||||
const std::size_t NumElements = 100;
|
||||
|
||||
//extract/adopt map
|
||||
{
|
||||
//Construction insertion
|
||||
flat_map<int, int> fmap;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fmap.emplace(static_cast<int>(i), -static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_map<int, int> fmap_copy(fmap);
|
||||
flat_map<int, int>::sequence_type seq(fmap.extract_sequence());
|
||||
if(!fmap.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fmap_copy))
|
||||
return false;
|
||||
|
||||
seq.insert(seq.end(), fmap_copy.begin(), fmap_copy.end());
|
||||
boost::container::test::random_shuffle(seq.begin(), seq.end());
|
||||
fmap.adopt_sequence(boost::move(seq));
|
||||
if(!CheckEqualContainers(fmap, fmap_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
//extract/adopt map, ordered_unique_range
|
||||
{
|
||||
//Construction insertion
|
||||
flat_map<int, int> fmap;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fmap.emplace(static_cast<int>(i), -static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_map<int, int> fmap_copy(fmap);
|
||||
flat_map<int, int>::sequence_type seq(fmap.extract_sequence());
|
||||
if(!fmap.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fmap_copy))
|
||||
return false;
|
||||
|
||||
fmap.adopt_sequence(ordered_unique_range, boost::move(seq));
|
||||
if(!CheckEqualContainers(fmap, fmap_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
//extract/adopt multimap
|
||||
{
|
||||
//Construction insertion
|
||||
flat_multimap<int, int> fmmap;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fmmap.emplace(static_cast<int>(i), -static_cast<int>(i));
|
||||
fmmap.emplace(static_cast<int>(i), -static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_multimap<int, int> fmmap_copy(fmmap);
|
||||
flat_multimap<int, int>::sequence_type seq(fmmap.extract_sequence());
|
||||
if(!fmmap.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fmmap_copy))
|
||||
return false;
|
||||
|
||||
boost::container::test::random_shuffle(seq.begin(), seq.end());
|
||||
fmmap.adopt_sequence(boost::move(seq));
|
||||
if(!CheckEqualContainers(fmmap, fmmap_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
//extract/adopt multimap, ordered_range
|
||||
{
|
||||
//Construction insertion
|
||||
flat_multimap<int, int> fmmap;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fmmap.emplace(static_cast<int>(i), -static_cast<int>(i));
|
||||
fmmap.emplace(static_cast<int>(i), -static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_multimap<int, int> fmmap_copy(fmmap);
|
||||
flat_multimap<int, int>::sequence_type seq(fmmap.extract_sequence());
|
||||
if(!fmmap.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fmmap_copy))
|
||||
return false;
|
||||
|
||||
fmmap.adopt_sequence(ordered_range, boost::move(seq));
|
||||
if(!CheckEqualContainers(fmmap, fmmap_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
@@ -385,6 +495,13 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Extract/Adopt test
|
||||
////////////////////////////////////
|
||||
if(!flat_tree_extract_adopt_test()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
|
@@ -312,6 +312,116 @@ bool flat_tree_ordered_insertion_test()
|
||||
return true;
|
||||
}
|
||||
|
||||
template< class RandomIt >
|
||||
void random_shuffle( RandomIt first, RandomIt last )
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<RandomIt>::difference_type difference_type;
|
||||
difference_type n = last - first;
|
||||
for (difference_type i = n-1; i > 0; --i) {
|
||||
difference_type j = std::rand() % (i+1);
|
||||
if(j != i) {
|
||||
boost::adl_move_swap(first[i], first[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool flat_tree_extract_adopt_test()
|
||||
{
|
||||
using namespace boost::container;
|
||||
const std::size_t NumElements = 100;
|
||||
|
||||
//extract/adopt set
|
||||
{
|
||||
//Construction insertion
|
||||
flat_set<int> fset;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fset.insert(static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_set<int> fset_copy(fset);
|
||||
flat_set<int>::sequence_type seq(fset.extract_sequence());
|
||||
if(!fset.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fset_copy))
|
||||
return false;
|
||||
|
||||
seq.insert(seq.end(), fset_copy.begin(), fset_copy.end());
|
||||
boost::container::test::random_shuffle(seq.begin(), seq.end());
|
||||
fset.adopt_sequence(boost::move(seq));
|
||||
if(!CheckEqualContainers(fset, fset_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
//extract/adopt set, ordered_unique_range
|
||||
{
|
||||
//Construction insertion
|
||||
flat_set<int> fset;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fset.insert(static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_set<int> fset_copy(fset);
|
||||
flat_set<int>::sequence_type seq(fset.extract_sequence());
|
||||
if(!fset.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fset_copy))
|
||||
return false;
|
||||
|
||||
fset.adopt_sequence(ordered_unique_range, boost::move(seq));
|
||||
if(!CheckEqualContainers(fset, fset_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
//extract/adopt multiset
|
||||
{
|
||||
//Construction insertion
|
||||
flat_multiset<int> fmset;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fmset.insert(static_cast<int>(i));
|
||||
fmset.insert(static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_multiset<int> fmset_copy(fmset);
|
||||
flat_multiset<int>::sequence_type seq(fmset.extract_sequence());
|
||||
if(!fmset.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fmset_copy))
|
||||
return false;
|
||||
|
||||
boost::container::test::random_shuffle(seq.begin(), seq.end());
|
||||
fmset.adopt_sequence(boost::move(seq));
|
||||
if(!CheckEqualContainers(fmset, fmset_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
//extract/adopt multiset, ordered_range
|
||||
{
|
||||
//Construction insertion
|
||||
flat_multiset<int> fmset;
|
||||
|
||||
for(std::size_t i = 0; i != NumElements; ++i){
|
||||
fmset.insert(static_cast<int>(i));
|
||||
fmset.insert(static_cast<int>(i));
|
||||
}
|
||||
|
||||
flat_multiset<int> fmset_copy(fmset);
|
||||
flat_multiset<int>::sequence_type seq(fmset.extract_sequence());
|
||||
if(!fmset.empty())
|
||||
return false;
|
||||
if(!CheckEqualContainers(seq, fmset_copy))
|
||||
return false;
|
||||
|
||||
fmset.adopt_sequence(ordered_range, boost::move(seq));
|
||||
if(!CheckEqualContainers(fmset, fmset_copy))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
@@ -491,6 +601,13 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Extract/Adopt test
|
||||
////////////////////////////////////
|
||||
if(!flat_tree_extract_adopt_test()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
|
@@ -38,13 +38,6 @@ template class map
|
||||
, test::simple_allocator< pair_t >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator< pair_t >
|
||||
>;
|
||||
|
||||
template class map
|
||||
< test::movable_and_copyable_int
|
||||
, test::movable_and_copyable_int
|
||||
@@ -58,36 +51,6 @@ template class multimap
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator< pair_t >
|
||||
>;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<pair_t>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<pair_t>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<pair_t>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
|
||||
}} //boost::container
|
||||
|
||||
class recursive_map
|
||||
@@ -282,12 +245,10 @@ int test_map_variants()
|
||||
{
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<int>::map_type MyMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_int>::map_type MyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::map_type MyCopyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::map_type MyCopyMap;
|
||||
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<int>::multimap_type MyMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_int>::multimap_type MyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::multimap_type MyCopyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::multimap_type MyCopyMultiMap;
|
||||
|
||||
typedef std::map<int, int> MyStdMap;
|
||||
@@ -311,15 +272,6 @@ int test_map_variants()
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyCopyMoveMap
|
||||
,MyStdMap
|
||||
,MyCopyMoveMultiMap
|
||||
,MyStdMultiMap>()){
|
||||
std::cout << "Error in map_test<MyBoostMap>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test<
|
||||
MyCopyMap
|
||||
,MyStdMap
|
||||
@@ -490,29 +442,19 @@ int main ()
|
||||
//
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmap_size_optimized_no;
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmap_size_optimized_yes) < sizeof(rbmap_size_optimized_no));
|
||||
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmap_size_optimized_no;
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmap_size_optimized_yes) < sizeof(avlmap_size_optimized_no));
|
||||
//
|
||||
// multimap
|
||||
//
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmmap_size_optimized_no;
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmmap_size_optimized_yes) < sizeof(rbmmap_size_optimized_no));
|
||||
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmmap_size_optimized_no;
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmmap_size_optimized_yes) < sizeof(avlmmap_size_optimized_no));
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmmap_size_optimized_yes) < sizeof(rbmap_size_optimized_no));
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmap_size_optimized_yes) < sizeof(avlmmap_size_optimized_no));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -8,11 +8,626 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/node_handle.hpp>
|
||||
#include <boost/container/new_allocator.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/container/detail/pair_key_mapped_of_value.hpp>
|
||||
|
||||
using namespace ::boost::container;
|
||||
|
||||
int main ()
|
||||
enum EAllocState
|
||||
{
|
||||
DefaultConstructed,
|
||||
MoveConstructed,
|
||||
MoveAssigned,
|
||||
CopyConstructed,
|
||||
CopyAssigned,
|
||||
Swapped,
|
||||
Destructed
|
||||
};
|
||||
|
||||
template<class Node>
|
||||
class trace_allocator
|
||||
: public new_allocator<Node>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(trace_allocator)
|
||||
|
||||
typedef new_allocator<Node> base_t;
|
||||
|
||||
public:
|
||||
|
||||
struct propagate_on_container_move_assignment
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
struct propagate_on_container_swap
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//!Obtains an new_allocator that allocates
|
||||
//!objects of type T2
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef trace_allocator<T2> other;
|
||||
};
|
||||
|
||||
explicit trace_allocator(unsigned value = 999)
|
||||
: m_state(DefaultConstructed), m_value(value)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
trace_allocator(BOOST_RV_REF(trace_allocator) other)
|
||||
: base_t(boost::move(BOOST_MOVE_BASE(base_t, other))), m_state(MoveConstructed), m_value(other.m_value)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
trace_allocator(const trace_allocator &other)
|
||||
: base_t(other), m_state(CopyConstructed), m_value(other.m_value)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
trace_allocator & operator=(BOOST_RV_REF(trace_allocator) other)
|
||||
{
|
||||
m_value = other.m_value;
|
||||
m_state = MoveAssigned;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class OtherNode>
|
||||
trace_allocator(const trace_allocator<OtherNode> &other)
|
||||
: m_state(CopyConstructed), m_value(other.m_value)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
template<class OtherNode>
|
||||
trace_allocator & operator=(BOOST_COPY_ASSIGN_REF(trace_allocator<OtherNode>) other)
|
||||
{
|
||||
m_value = other.m_value;
|
||||
m_state = CopyAssigned;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~trace_allocator()
|
||||
{
|
||||
m_value = 0u-1u;
|
||||
m_state = Destructed;
|
||||
--count;
|
||||
}
|
||||
|
||||
void swap(trace_allocator &other)
|
||||
{
|
||||
boost::adl_move_swap(m_value, other.m_value);
|
||||
m_state = other.m_state = Swapped;
|
||||
}
|
||||
|
||||
friend void swap(trace_allocator &left, trace_allocator &right)
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
EAllocState m_state;
|
||||
unsigned m_value;
|
||||
|
||||
static unsigned int count;
|
||||
|
||||
static void reset_count()
|
||||
{ count = 0; }
|
||||
};
|
||||
|
||||
template<class Node>
|
||||
unsigned int trace_allocator<Node>::count = 0;
|
||||
|
||||
template<class T>
|
||||
struct node
|
||||
{
|
||||
typedef T value_type;
|
||||
value_type value;
|
||||
|
||||
value_type &get_data() { return value; }
|
||||
const value_type &get_data() const { return value; }
|
||||
|
||||
node()
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
~node()
|
||||
{
|
||||
--count;
|
||||
}
|
||||
|
||||
static unsigned int count;
|
||||
|
||||
static void reset_count()
|
||||
{ count = 0; }
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct value
|
||||
{
|
||||
T1 first;
|
||||
T2 second;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
unsigned int node<T>::count = 0;
|
||||
|
||||
|
||||
//Common types
|
||||
typedef value<int, unsigned> test_pair;
|
||||
typedef pair_key_mapped_of_value<int, unsigned> key_mapped_t;
|
||||
typedef node<test_pair> node_t;
|
||||
typedef trace_allocator< node_t > node_alloc_t;
|
||||
typedef node_handle<node_alloc_t, void> node_handle_set_t;
|
||||
typedef node_handle<node_alloc_t, key_mapped_t> node_handle_map_t;
|
||||
typedef allocator_traits<node_alloc_t>::portable_rebind_alloc<test_pair>::type value_allocator_type;
|
||||
|
||||
void test_types()
|
||||
{
|
||||
//set
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_set_t::value_type, test_pair>::value ));
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_set_t::key_type, test_pair>::value ));
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_set_t::mapped_type, test_pair>::value ));
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_set_t::allocator_type, value_allocator_type>::value ));
|
||||
|
||||
//map
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_map_t::value_type, test_pair>::value ));
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_map_t::key_type, int>::value ));
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_map_t::mapped_type, unsigned>::value ));
|
||||
BOOST_STATIC_ASSERT(( container_detail::is_same<node_handle_map_t::allocator_type, value_allocator_type>::value ));
|
||||
}
|
||||
|
||||
void test_default_constructor()
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
{
|
||||
node_handle_set_t nh;
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
|
||||
void test_arg_constructor()
|
||||
{
|
||||
//With non-null pointer
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
{
|
||||
const node_alloc_t al;
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
{
|
||||
node_handle_set_t nh(new node_t, al);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
//With null pointer
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
{
|
||||
const node_alloc_t al;
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
{
|
||||
node_handle_set_t nh(0, al);
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
|
||||
void test_move_constructor()
|
||||
{
|
||||
//With non-null pointer
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
{
|
||||
const node_alloc_t al;
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
{
|
||||
node_t *const from_ptr = new node_t;
|
||||
node_handle_set_t nh(from_ptr, al);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
{
|
||||
node_handle_set_t nh2(boost::move(nh));
|
||||
BOOST_TEST(nh.empty());
|
||||
BOOST_TEST(!nh2.empty());
|
||||
BOOST_TEST(nh2.get() == from_ptr);
|
||||
BOOST_TEST(nh2.node_alloc().m_state == MoveConstructed);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
//With null pointer
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
{
|
||||
const node_alloc_t al;
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
{
|
||||
node_handle_set_t nh;
|
||||
{
|
||||
node_handle_set_t nh2(boost::move(nh));
|
||||
BOOST_TEST(nh.empty());
|
||||
BOOST_TEST(nh2.empty());
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
|
||||
void test_related_constructor()
|
||||
{
|
||||
//With non-null pointer
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
{
|
||||
const node_alloc_t al;
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
{
|
||||
node_t *const from_ptr = new node_t;
|
||||
node_handle_map_t nh(from_ptr, al);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
{
|
||||
node_handle_set_t nh2(boost::move(nh));
|
||||
BOOST_TEST(nh.empty());
|
||||
BOOST_TEST(!nh2.empty());
|
||||
BOOST_TEST(nh2.get() == from_ptr);
|
||||
BOOST_TEST(nh2.node_alloc().m_state == MoveConstructed);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
//With null pointer
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
{
|
||||
const node_alloc_t al;
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
{
|
||||
node_handle_set_t nh;
|
||||
{
|
||||
node_handle_map_t nh2(boost::move(nh));
|
||||
BOOST_TEST(nh.empty());
|
||||
BOOST_TEST(nh2.empty());
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
|
||||
void test_move_assignment()
|
||||
{
|
||||
//empty = full
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
node_t *const from_ptr = new node_t;
|
||||
node_handle_set_t nh_from(from_ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
node_handle_set_t nh_to;
|
||||
BOOST_TEST(nh_to.empty());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
nh_to = boost::move(nh_from);
|
||||
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(!nh_to.empty());
|
||||
BOOST_TEST(nh_to.get() == from_ptr);
|
||||
BOOST_TEST(nh_to.node_alloc().m_state == MoveConstructed);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
|
||||
//empty = empty
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_handle_set_t nh_from;
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
node_handle_set_t nh_to;
|
||||
BOOST_TEST(nh_to.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
nh_to = boost::move(nh_from);
|
||||
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(nh_to.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
|
||||
//full = empty
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_handle_set_t nh_from;
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
node_handle_set_t nh_to(new node_t, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
nh_to = boost::move(nh_from);
|
||||
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(nh_to.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
|
||||
//full = full
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_t *const from_ptr = new node_t;
|
||||
node_handle_set_t nh_from(from_ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
node_handle_set_t nh_to(new node_t, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 2);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
|
||||
nh_to = boost::move(nh_from);
|
||||
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(!nh_to.empty());
|
||||
BOOST_TEST(nh_to.get() == from_ptr);
|
||||
BOOST_TEST(nh_to.node_alloc().m_state == MoveAssigned);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
}
|
||||
|
||||
void test_value_key_mapped()
|
||||
{
|
||||
//value()
|
||||
{
|
||||
node_t *from_ptr = new node_t;
|
||||
const node_handle_set_t nh_from(from_ptr, node_alloc_t());
|
||||
from_ptr->value.first = -99;
|
||||
from_ptr->value.second = 99;
|
||||
BOOST_TEST(nh_from.value().first == -99);
|
||||
BOOST_TEST(nh_from.value().second == 99);
|
||||
}
|
||||
//key()/mapped()
|
||||
{
|
||||
node_t *from_ptr = new node_t;
|
||||
const node_handle_map_t nh_from(from_ptr, node_alloc_t());
|
||||
from_ptr->value.first = -98;
|
||||
from_ptr->value.second = 98;
|
||||
BOOST_TEST(nh_from.key() == -98);
|
||||
BOOST_TEST(nh_from.mapped() == 98);
|
||||
}
|
||||
}
|
||||
|
||||
void test_get_allocator()
|
||||
{
|
||||
const node_handle_set_t nh(new node_t, node_alloc_t(888));
|
||||
allocator_traits<node_alloc_t>::portable_rebind_alloc<test_pair>::type a = nh.get_allocator();
|
||||
BOOST_TEST(a.m_value == 888);
|
||||
}
|
||||
|
||||
void test_bool_conversion_empty()
|
||||
{
|
||||
const node_handle_set_t nh(new node_t, node_alloc_t(777));
|
||||
const node_handle_set_t nh_null;
|
||||
BOOST_TEST(nh && !nh_null);
|
||||
BOOST_TEST(!(!nh || nh_null));
|
||||
BOOST_TEST(!nh.empty() && nh_null.empty());
|
||||
BOOST_TEST(!(nh.empty() || !nh_null.empty()));
|
||||
}
|
||||
|
||||
void test_swap()
|
||||
{
|
||||
//empty.swap(full)
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
node_t *const from_ptr = new node_t;
|
||||
node_handle_set_t nh_from(from_ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
node_handle_set_t nh_to;
|
||||
BOOST_TEST(nh_to.empty());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
nh_to.swap(nh_from);
|
||||
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(!nh_to.empty());
|
||||
BOOST_TEST(nh_to.get() == from_ptr);
|
||||
BOOST_TEST(nh_to.node_alloc().m_state == MoveConstructed);
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
|
||||
//empty.swap(empty)
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_handle_set_t nh_from;
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
node_handle_set_t nh_to;
|
||||
BOOST_TEST(nh_to.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
nh_to.swap(nh_from);
|
||||
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(nh_to.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
}
|
||||
|
||||
//full.swap(empty)
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_handle_set_t nh_from;
|
||||
BOOST_TEST(nh_from.empty());
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
node_t *const to_ptr = new node_t;
|
||||
node_handle_set_t nh_to(to_ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
nh_to.swap(nh_from);
|
||||
|
||||
BOOST_TEST(!nh_from.empty());
|
||||
BOOST_TEST(nh_from.node_alloc().m_state == MoveConstructed);
|
||||
BOOST_TEST(nh_from.get() == to_ptr);
|
||||
BOOST_TEST(nh_to.empty());
|
||||
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
|
||||
//full.swap(full)
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_t *const from_ptr = new node_t;
|
||||
node_handle_set_t nh_from(from_ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
node_t *const to_ptr = new node_t;
|
||||
node_handle_set_t nh_to(to_ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 2);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
|
||||
nh_to.swap(nh_from);
|
||||
|
||||
BOOST_TEST(!nh_from.empty());
|
||||
BOOST_TEST(nh_from.get() == to_ptr);
|
||||
BOOST_TEST(nh_from.node_alloc().m_state == Swapped);
|
||||
|
||||
BOOST_TEST(!nh_to.empty());
|
||||
BOOST_TEST(nh_to.get() == from_ptr);
|
||||
BOOST_TEST(nh_to.node_alloc().m_state == Swapped);
|
||||
|
||||
BOOST_TEST(node_t::count == 2);
|
||||
BOOST_TEST(node_alloc_t::count == 2);
|
||||
}
|
||||
}
|
||||
|
||||
void test_get_release()
|
||||
{
|
||||
//get()
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_t *const ptr = new node_t;
|
||||
const node_handle_set_t nh(ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
BOOST_TEST(nh.get() == ptr);
|
||||
BOOST_TEST(!nh.empty());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
|
||||
//release()
|
||||
{
|
||||
node_alloc_t::reset_count();
|
||||
node_t::reset_count();
|
||||
|
||||
node_t *const ptr = new node_t;
|
||||
node_handle_set_t nh(ptr, node_alloc_t());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 1);
|
||||
|
||||
BOOST_TEST(nh.release() == ptr);
|
||||
BOOST_TEST(nh.empty());
|
||||
BOOST_TEST(node_t::count == 1);
|
||||
BOOST_TEST(node_alloc_t::count == 0);
|
||||
delete ptr;
|
||||
}
|
||||
BOOST_TEST(node_t::count == 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_types();
|
||||
test_default_constructor();
|
||||
test_arg_constructor();
|
||||
test_move_constructor();
|
||||
test_related_constructor();
|
||||
test_move_assignment();
|
||||
test_value_key_mapped();
|
||||
test_get_allocator();
|
||||
test_bool_conversion_empty();
|
||||
test_swap();
|
||||
test_get_release();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ template class set
|
||||
template class set
|
||||
< test::movable_and_copyable_int
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
, new_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
//multiset
|
||||
@@ -53,35 +53,6 @@ template class multiset
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
|
||||
}} //boost::container
|
||||
|
||||
//Test recursive structures
|
||||
@@ -301,12 +272,10 @@ int test_set_variants()
|
||||
{
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<int>::set_type MySet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_int>::set_type MyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::set_type MyCopySet;
|
||||
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<int>::multiset_type MyMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
|
||||
|
||||
typedef std::set<int> MyStdSet;
|
||||
@@ -330,15 +299,6 @@ int test_set_variants()
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyCopyMoveSet
|
||||
,MyStdSet
|
||||
,MyCopyMoveMultiSet
|
||||
,MyStdMultiSet>()){
|
||||
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::set_test<
|
||||
MyCopySet
|
||||
,MyStdSet
|
||||
@@ -452,29 +412,20 @@ int main ()
|
||||
//
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbset_size_optimized_no;
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbset_size_optimized_yes) < sizeof(rbset_size_optimized_no));
|
||||
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlset_size_optimized_no;
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlset_size_optimized_yes) < sizeof(avlset_size_optimized_no));
|
||||
//
|
||||
// multiset
|
||||
//
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmset_size_optimized_no;
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmset_size_optimized_yes) < sizeof(rbmset_size_optimized_no));
|
||||
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmset_size_optimized_no;
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmset_size_optimized_yes) < sizeof(avlmset_size_optimized_no));
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmset_size_optimized_yes) < sizeof(rbset_size_optimized_no));
|
||||
BOOST_STATIC_ASSERT(sizeof(avlset_size_optimized_yes) < sizeof(avlmset_size_optimized_no));
|
||||
|
||||
////////////////////////////////////
|
||||
// Iterator testing
|
||||
|
84
test/tree_test.cpp
Normal file
84
test/tree_test.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/tree.hpp>
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
#include "movable_int.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
typedef std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> pair_t;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<pair_t>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<pair_t>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<pair_t>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, adaptive_pool<test::movable_and_copyable_int>
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
|
||||
}} //boost::container
|
||||
|
||||
int main ()
|
||||
{
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user