Massive dependency reduction. Removed dependency on several boost libraries and standard C++ headers.

This commit is contained in:
Ion Gaztañaga
2015-01-02 19:34:21 +01:00
parent 955248b739
commit 360957a797
97 changed files with 4315 additions and 5030 deletions

View File

@@ -79,7 +79,7 @@ template class bc::node_allocator
, bc::NodeAlloc_nodes_per_block
, 2>;
template<class A> struct get_allocator_name;
template<class Allocator> struct get_allocator_name;
template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } };
@@ -124,10 +124,10 @@ class MyInt
}
};
template<class A>
template<class Allocator>
void list_test_template(std::size_t num_iterations, std::size_t num_elements, bool csv_output)
{
typedef typename A::template rebind<MyInt>::other IntAllocator;
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
nanosecond_type tinsert, terase;
boost_cont_malloc_stats_t insert_stats, erase_stats;
std::size_t insert_inuse, erase_inuse;
@@ -181,7 +181,7 @@ void list_test_template(std::size_t num_iterations, std::size_t num_elements, bo
if(csv_output){
std::cout << get_allocator_name<A>::get()
std::cout << get_allocator_name<Allocator>::get()
<< ";"
<< num_iterations
<< ";"
@@ -206,7 +206,7 @@ void list_test_template(std::size_t num_iterations, std::size_t num_elements, bo
}
else{
std::cout << std::endl
<< "A: " << get_allocator_name<A>::get()
<< "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl
<< " allocation/deallocation(ns): " << float(tinsert)/(num_iterations*num_elements) << '\t' << float(terase)/(num_iterations*num_elements)
<< std::endl

View File

@@ -32,7 +32,7 @@ typedef bc::allocator<int, 2, bc::expand_bwd | bc::expand_fwd> AllocatorPlusV2Ma
typedef bc::allocator<int, 2, bc::expand_fwd> AllocatorPlusV2;
typedef bc::allocator<int, 1> AllocatorPlusV1;
template<class A> struct get_allocator_name;
template<class Allocator> struct get_allocator_name;
template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } };
@@ -90,14 +90,14 @@ struct has_trivial_destructor_after_move<MyInt>
void print_header()
{
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
<< "Capacity" << ";" << "push_back(ns)" << ";" << "A calls" << ";"
<< "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";"
<< "New allocations" << ";" << "Bwd expansions" << std::endl;
}
template<class A>
template<class Allocator>
void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
{
typedef typename A::template rebind<MyInt>::other IntAllocator;
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
unsigned int numalloc = 0, numexpand = 0;
cpu_timer timer;
@@ -132,7 +132,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
nanosecond_type nseconds = timer.elapsed().wall;
if(csv_output){
std::cout << get_allocator_name<A>::get()
std::cout << get_allocator_name<Allocator>::get()
<< ";"
<< num_iterations
<< ";"
@@ -151,7 +151,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
}
else{
std::cout << std::endl
<< "A: " << get_allocator_name<A>::get()
<< "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl
<< " push_back ns: "
<< float(nseconds)/(num_iterations*num_elements)

View File

@@ -35,7 +35,7 @@ typedef bc::allocator<int, 2, bc::expand_bwd | bc::expand_fwd> AllocatorPlusV2Ma
typedef bc::allocator<int, 2> AllocatorPlusV2;
typedef bc::allocator<int, 1> AllocatorPlusV1;
template<class A> struct get_allocator_name;
template<class Allocator> struct get_allocator_name;
template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } };
@@ -60,32 +60,32 @@ struct stats_traits;
template<>
struct stats_traits<std::vector>
{
template<class T, class A>
static void reset_alloc_stats(std::vector<T, A> &)
template<class T, class Allocator>
static void reset_alloc_stats(std::vector<T, Allocator> &)
{}
template<class T, class A>
static std::size_t get_num_alloc(std::vector<T, A> &)
template<class T, class Allocator>
static std::size_t get_num_alloc(std::vector<T, Allocator> &)
{ return 0; }
template<class T, class A>
static std::size_t get_num_expand(std::vector<T, A> &)
template<class T, class Allocator>
static std::size_t get_num_expand(std::vector<T, Allocator> &)
{ return 0; }
};
template<>
struct stats_traits<bc::vector>
{
template<class T, class A>
static void reset_alloc_stats(bc::vector<T, A> &v)
template<class T, class Allocator>
static void reset_alloc_stats(bc::vector<T, Allocator> &v)
{ v.reset_alloc_stats(); }
template<class T, class A>
static std::size_t get_num_alloc(bc::vector<T, A> &v)
template<class T, class Allocator>
static std::size_t get_num_alloc(bc::vector<T, Allocator> &v)
{ return v.num_alloc; }
template<class T, class A>
static std::size_t get_num_expand(bc::vector<T, A> &v)
template<class T, class Allocator>
static std::size_t get_num_expand(bc::vector<T, Allocator> &v)
{ return v.num_expand_fwd; }
};
@@ -124,10 +124,10 @@ class MyInt
}
};
template<class A, template <class, class> class Vector>
template<class Allocator, template <class, class> class Vector>
void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
{
typedef typename A::template rebind<MyInt>::other IntAllocator;
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
unsigned int numalloc = 0, numexpand = 0;
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
@@ -193,7 +193,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
nanosecond_type nseconds = timer.elapsed().wall;
if(csv_output){
std::cout << get_allocator_name<A>::get()
std::cout << get_allocator_name<Allocator>::get()
<< ";"
<< num_iterations
<< ";"
@@ -212,7 +212,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
}
else{
std::cout << std::endl
<< "A: " << get_allocator_name<A>::get()
<< "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl
<< " push_back ns: "
<< float(nseconds)/(num_iterations*num_elements)
@@ -229,7 +229,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
void print_header()
{
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
<< "Capacity" << ";" << "push_back(ns)" << ";" << "A calls" << ";"
<< "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";"
<< "New allocations" << ";" << "Fwd expansions" << std::endl;
}

View File

@@ -34,7 +34,7 @@ typedef std::allocator<int> StdAllocator;
typedef bc::allocator<int, 2> AllocatorPlusV2;
typedef bc::allocator<int, 1> AllocatorPlusV1;
template<class A> struct get_allocator_name;
template<class Allocator> struct get_allocator_name;
template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } };
@@ -69,10 +69,10 @@ void print_header()
<< "num_shrink" << ";" << "shrink_to_fit(ns)" << std::endl;
}
template<class A>
template<class Allocator>
void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
{
typedef typename A::template rebind<MyInt>::other IntAllocator;
typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
unsigned int capacity = 0;
const std::size_t Step = 5;
@@ -84,7 +84,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
#ifndef NDEBUG
typedef bc::container_detail::integral_constant
<unsigned, bc::container_detail::version<A>::value> alloc_version;
<unsigned, bc::container_detail::version<Allocator>::value> alloc_version;
#endif
for(unsigned int r = 0; r != num_iterations; ++r){
@@ -105,7 +105,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
nanosecond_type nseconds = timer.elapsed().wall;
if(csv_output){
std::cout << get_allocator_name<A>::get()
std::cout << get_allocator_name<Allocator>::get()
<< ";"
<< num_iterations
<< ";"
@@ -118,7 +118,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
}
else{
std::cout << std::endl
<< "A: " << get_allocator_name<A>::get()
<< "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl
<< " num_shrink: " << num_shrink
<< std::endl

View File

@@ -41,7 +41,7 @@ typedef bc::adaptive_pool
, 2
, 2> AdPool2PercentV2;
template<class A> struct get_allocator_name;
template<class Allocator> struct get_allocator_name;
template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } };
@@ -71,32 +71,32 @@ class MyInt
}
};
template<class A>
template<class Allocator>
struct get_vector
{
typedef bc::vector
<MyInt, typename A::template rebind<MyInt>::other> type;
<MyInt, typename Allocator::template rebind<MyInt>::other> type;
static const char *vector_name()
{
return "vector<MyInt>";
}
};
template<class A>
template<class Allocator>
struct get_stable_vector
{
typedef bc::stable_vector
<MyInt, typename A::template rebind<MyInt>::other> type;
<MyInt, typename Allocator::template rebind<MyInt>::other> type;
static const char *vector_name()
{
return "stable_vector<MyInt>";
}
};
template<template<class> class GetContainer, class A>
template<template<class> class GetContainer, class Allocator>
void stable_vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
{
typedef typename GetContainer<A>::type vector_type;
typedef typename GetContainer<Allocator>::type vector_type;
//std::size_t top_capacity = 0;
nanosecond_type nseconds;
{
@@ -113,9 +113,9 @@ void stable_vector_test_template(unsigned int num_iterations, unsigned int num_e
nseconds = timer.elapsed().wall;
if(csv_output){
std::cout << get_allocator_name<A>::get()
std::cout << get_allocator_name<Allocator>::get()
<< ";"
<< GetContainer<A>::vector_name()
<< GetContainer<Allocator>::vector_name()
<< ";"
<< num_iterations
<< ";"
@@ -125,9 +125,9 @@ void stable_vector_test_template(unsigned int num_iterations, unsigned int num_e
<< ";";
}
else{
std::cout << "Allocator: " << get_allocator_name<A>::get()
std::cout << "Allocator: " << get_allocator_name<Allocator>::get()
<< '\t'
<< GetContainer<A>::vector_name()
<< GetContainer<Allocator>::vector_name()
<< std::endl
<< " allocation ns: "
<< float(nseconds)/(num_iterations*num_elements);

View File

@@ -23,7 +23,6 @@
using boost::timer::cpu_timer;
using boost::timer::cpu_times;
using boost::timer::nanosecond_type;
using namespace boost::container;
#ifdef NDEBUG
static const std::size_t NElements = 1000;
@@ -42,10 +41,10 @@ void compare_times(cpu_times time_numerator, cpu_times time_denominator){
std::cout << "----------------------------------------------" << '\n' << std::endl;
}
vector<int> sorted_unique_range_int;
vector<int> sorted_range_int;
vector<int> random_unique_range_int;
vector<int> random_range_int;
boost::container::vector<int> sorted_unique_range_int;
boost::container::vector<int> sorted_range_int;
boost::container::vector<int> random_unique_range_int;
boost::container::vector<int> random_range_int;
void fill_range_ints()
{
@@ -69,15 +68,15 @@ void fill_range_ints()
std::random_shuffle(random_unique_range_int.begin(), random_unique_range_int.end());
}
vector<string> sorted_unique_range_string;
vector<string> sorted_range_string;
vector<string> random_unique_range_string;
vector<string> random_range_string;
boost::container::vector<boost::container::string> sorted_unique_range_string;
boost::container::vector<boost::container::string> sorted_range_string;
boost::container::vector<boost::container::string> random_unique_range_string;
boost::container::vector<boost::container::string> random_range_string;
void fill_range_strings()
{
string model_s;
model_s.append(sizeof(string), '*');
boost::container::string model_s;
model_s.append(sizeof(boost::container::string), '*');
//sorted_unique_range_int
sorted_unique_range_string.resize(NElements);
@@ -111,7 +110,7 @@ struct range_provider;
template<>
struct range_provider<int>
{
typedef vector<int> type;
typedef boost::container::vector<int> type;
static type &sorted_unique()
{ return sorted_unique_range_int; }
@@ -127,9 +126,9 @@ struct range_provider<int>
};
template<>
struct range_provider<string>
struct range_provider<boost::container::string>
{
typedef vector<string> type;
typedef boost::container::vector<boost::container::string> type;
static type &sorted_unique()
{ return sorted_unique_range_string; }
@@ -145,7 +144,7 @@ struct range_provider<string>
};
template<typename C>
cpu_times copy_destroy_time(vector<typename C::value_type> &unique_range)
cpu_times copy_destroy_time(boost::container::vector<typename C::value_type> &unique_range)
{
cpu_timer copy_timer, assign_timer, destroy_timer;
@@ -176,7 +175,9 @@ cpu_times copy_destroy_time(vector<typename C::value_type> &unique_range)
}
template<typename C>
cpu_times construct_time(vector<typename C::value_type> &unique_range, vector<typename C::value_type> &range, const char *RangeType)
cpu_times construct_time( boost::container::vector<typename C::value_type> &unique_range
, boost::container::vector<typename C::value_type> &range
, const char *RangeType)
{
cpu_timer sur_timer, sr_timer;
@@ -206,7 +207,9 @@ cpu_times construct_time(vector<typename C::value_type> &unique_range, vector<ty
}
template<typename C>
cpu_times insert_time(vector<typename C::value_type> &unique_range, vector<typename C::value_type> &range, const char *RangeType)
cpu_times insert_time( boost::container::vector<typename C::value_type> &unique_range
, boost::container::vector<typename C::value_type> &range
, const char *RangeType)
{
cpu_timer ur_timer,r_timer;
ur_timer.stop();r_timer.stop();
@@ -240,7 +243,7 @@ cpu_times insert_time(vector<typename C::value_type> &unique_range, vector<typen
}
template<typename Iterator>
bool check_not_end(vector<Iterator> &iterators, Iterator itend, std::size_t number_of_ends = 0)
bool check_not_end(boost::container::vector<Iterator> &iterators, Iterator itend, std::size_t number_of_ends = 0)
{
std::size_t end_count = 0;
for(std::size_t i = 0, max = iterators.size(); i != max; ++i){
@@ -251,7 +254,7 @@ bool check_not_end(vector<Iterator> &iterators, Iterator itend, std::size_t numb
}
template<typename Iterator>
bool check_all_not_empty(vector< std::pair<Iterator, Iterator > > &iterator_pairs)
bool check_all_not_empty(boost::container::vector< std::pair<Iterator, Iterator > > &iterator_pairs)
{
for(std::size_t i = 0, max = iterator_pairs.size(); i != max; ++i){
if(iterator_pairs[i].first == iterator_pairs[i].second)
@@ -261,7 +264,7 @@ bool check_all_not_empty(vector< std::pair<Iterator, Iterator > > &iterator_pair
}
template<typename C>
cpu_times search_time(vector<typename C::value_type> &unique_range, const char *RangeType)
cpu_times search_time(boost::container::vector<typename C::value_type> &unique_range, const char *RangeType)
{
cpu_timer find_timer, lower_timer, upper_timer, equal_range_timer, count_timer;
@@ -270,8 +273,8 @@ cpu_times search_time(vector<typename C::value_type> &unique_range, const char *
cpu_timer total_time;
total_time.resume();
vector<typename C::iterator> v_it(NElements);
vector< std::pair<typename C::iterator, typename C::iterator> > v_itp(NElements);
boost::container::vector<typename C::iterator> v_it(NElements);
boost::container::vector< std::pair<typename C::iterator, typename C::iterator> > v_itp(NElements);
for(std::size_t i = 0; i != NIter; ++i){
//Find
@@ -348,7 +351,7 @@ cpu_times search_time(vector<typename C::value_type> &unique_range, const char *
}
template<typename C>
void extensions_time(vector<typename C::value_type> &sorted_unique_range)
void extensions_time(boost::container::vector<typename C::value_type> &sorted_unique_range)
{
cpu_timer sur_timer,sur_opt_timer;
sur_timer.stop();sur_opt_timer.stop();

View File

@@ -8,9 +8,9 @@
//
//////////////////////////////////////////////////////////////////////////////
#include "boost/container/set.hpp"
#include "boost/container/allocator.hpp"
#include "bench_set.hpp"
#include <boost/container/set.hpp>
#include <boost/container/allocator.hpp>
int main()
{
@@ -19,7 +19,7 @@ int main()
fill_range_ints();
fill_range_strings();
//set<..., allocator_v2> vs. set
//set<..., version_2> vs. set
launch_tests< set<int, std::less<int>, allocator<int> >, set<int> >
("set<int, ..., allocator<int>", "set<int>");
launch_tests< set<string, std::less<string>, allocator<string> >, set<string> >

View File

@@ -17,24 +17,25 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/addressof.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/adl_move_swap.hpp> //adl_move_swap
#include "varray_util.hpp"
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/integer.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/static_assert.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <stdexcept>
@@ -84,17 +85,17 @@ struct def
//!
//! This strategy defines the same types that are defined in the Allocator.
//!
//! @tparam A The Allocator which will be adapted.
template <typename A>
//! @tparam Allocator The Allocator which will be adapted.
template <typename Allocator>
struct allocator_adaptor
{
typedef typename A::value_type value_type;
typedef typename A::size_type size_type;
typedef typename A::difference_type difference_type;
typedef typename A::pointer pointer;
typedef typename A::const_pointer const_pointer;
typedef typename A::reference reference;
typedef typename A::const_reference const_reference;
typedef typename Allocator::value_type value_type;
typedef typename Allocator::size_type size_type;
typedef typename Allocator::difference_type difference_type;
typedef typename Allocator::pointer pointer;
typedef typename Allocator::const_pointer const_pointer;
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
static void allocate_failed()
{
@@ -176,9 +177,9 @@ struct varray_traits
typedef varray_error_handler error_handler;
typedef boost::false_type use_memop_in_swap_and_move;
typedef boost::false_type use_optimized_swap;
typedef boost::false_type disable_trivial_init;
typedef false_type use_memop_in_swap_and_move;
typedef false_type use_optimized_swap;
typedef false_type disable_trivial_init;
};
/**
@@ -220,18 +221,10 @@ class varray
> vt;
typedef typename vt::error_handler errh;
BOOST_MPL_ASSERT_MSG(
( boost::is_unsigned<typename vt::size_type>::value &&
sizeof(typename boost::uint_value_t<Capacity>::least) <= sizeof(typename vt::size_type) ),
SIZE_TYPE_IS_TOO_SMALL_FOR_SPECIFIED_CAPACITY,
(varray)
);
typedef boost::aligned_storage<
typedef typename aligned_storage<
sizeof(Value[Capacity]),
boost::alignment_of<Value[Capacity]>::value
> aligned_storage_type;
boost::container::container_detail::alignment_of<Value[Capacity]>::value
>::type aligned_storage_type;
template <typename V, std::size_t C, typename S>
friend class varray;
@@ -1004,7 +997,7 @@ public:
}
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! @pre <tt>size() < capacity()</tt>
//!
//! @brief Inserts a Value constructed with
@@ -1075,8 +1068,9 @@ public:
++m_size; // update end
sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage;
value_type * val_p = static_cast<value_type *>(temp_storage.address());
typename aligned_storage
<sizeof(value_type), alignment_of<value_type>::value>::type temp_storage;
value_type * val_p = static_cast<value_type*>(static_cast<void*>(&temp_storage));
sv::construct(dti(), val_p, ::boost::forward<Args>(args)...); // may throw
sv::scoped_destructor<value_type> d(val_p);
sv::assign(position, ::boost::move(*val_p)); // may throw
@@ -1085,63 +1079,51 @@ public:
return position;
}
#else // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_CONTAINER_DOXYGEN_INVOKED
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typedef typename vt::disable_trivial_init dti; \
\
errh::check_capacity(*this, m_size + 1); /*may throw*/\
\
namespace sv = varray_detail; \
sv::construct(dti(), this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
++m_size; /*update end*/ \
} \
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_VARRAY_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void emplace_back(BOOST_MOVE_UREF##N)\
{\
typedef typename vt::disable_trivial_init dti;\
errh::check_capacity(*this, m_size + 1);/*may throw*/\
\
namespace sv = varray_detail;\
sv::construct(dti(), this->end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
++m_size; /*update end*/\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
typedef typename vt::disable_trivial_init dti;\
namespace sv = varray_detail;\
errh::check_iterator_end_eq(*this, position);\
errh::check_capacity(*this, m_size + 1); /*may throw*/\
if ( position == this->end() ){\
sv::construct(dti(), position BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
++m_size; /*update end*/\
}\
else{\
/* TODO - should following lines check for exception and revert to the old size? */\
/* TODO - should move be used only if it's nonthrowing? */\
value_type & r = *(this->end() - 1);\
sv::construct(dti(), this->end(), boost::move(r));/*may throw*/\
++m_size; /*update end*/\
sv::move_backward(position, this->end() - 2, this->end() - 1);/*may throw*/\
typename aligned_storage\
<sizeof(value_type), alignment_of<value_type>::value>::type temp_storage;\
value_type * val_p = static_cast<value_type*>(static_cast<void*>(&temp_storage));\
sv::construct(dti(), val_p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
sv::scoped_destructor<value_type> d(val_p);\
sv::assign(position, ::boost::move(*val_p));/*may throw*/\
}\
return position;\
}\
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VARRAY_EMPLACE_CODE)
#undef BOOST_CONTAINER_VARRAY_EMPLACE_CODE
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(iterator position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typedef typename vt::disable_trivial_init dti; \
namespace sv = varray_detail; \
\
errh::check_iterator_end_eq(*this, position); \
errh::check_capacity(*this, m_size + 1); /*may throw*/\
\
if ( position == this->end() ) \
{ \
sv::construct(dti(), position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
++m_size; /*update end*/ \
} \
else \
{ \
/* TODO - should following lines check for exception and revert to the old size? */ \
/* TODO - should move be used only if it's nonthrowing? */ \
\
value_type & r = *(this->end() - 1); \
sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
++m_size; /*update end*/ \
sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\
\
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; \
value_type * val_p = static_cast<value_type *>(temp_storage.address()); \
sv::construct(dti(), val_p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
sv::scoped_destructor<value_type> d(val_p); \
sv::assign(position, ::boost::move(*val_p)); /*may throw*/\
} \
\
return position; \
} \
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_CONTAINER_DOXYGEN_INVOKED
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
//! @brief Removes all elements from the container.
@@ -1321,7 +1303,7 @@ public:
//! Constant O(1).
Value * data()
{
return boost::addressof(*(this->ptr()));
return (addressof)(*(this->ptr()));
}
//! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
@@ -1334,7 +1316,7 @@ public:
//! Constant O(1).
const Value * data() const
{
return boost::addressof(*(this->ptr()));
return (addressof)(*(this->ptr()));
}
@@ -1528,7 +1510,7 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C, typename S>
void move_ctor_dispatch(varray<value_type, C, S> & other, boost::true_type /*use_memop*/)
void move_ctor_dispatch(varray<value_type, C, S> & other, true_type /*use_memop*/)
{
::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
m_size = other.m_size;
@@ -1540,7 +1522,7 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C, typename S>
void move_ctor_dispatch(varray<value_type, C, S> & other, boost::false_type /*use_memop*/)
void move_ctor_dispatch(varray<value_type, C, S> & other, false_type /*use_memop*/)
{
namespace sv = varray_detail;
sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
@@ -1552,7 +1534,7 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C, typename S>
void move_assign_dispatch(varray<value_type, C, S> & other, boost::true_type /*use_memop*/)
void move_assign_dispatch(varray<value_type, C, S> & other, true_type /*use_memop*/)
{
this->clear();
@@ -1566,7 +1548,7 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C, typename S>
void move_assign_dispatch(varray<value_type, C, S> & other, boost::false_type /*use_memop*/)
void move_assign_dispatch(varray<value_type, C, S> & other, false_type /*use_memop*/)
{
namespace sv = varray_detail;
if ( m_size <= static_cast<size_type>(other.size()) )
@@ -1588,18 +1570,18 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C, typename S>
void swap_dispatch(varray<value_type, C, S> & other, boost::true_type const& /*use_optimized_swap*/)
void swap_dispatch(varray<value_type, C, S> & other, true_type const& /*use_optimized_swap*/)
{
typedef typename
boost::mpl::if_c<
if_c<
Capacity < C,
aligned_storage_type,
typename varray<value_type, C, S>::aligned_storage_type
>::type
storage_type;
storage_type temp;
Value * temp_ptr = reinterpret_cast<Value*>(temp.address());
storage_type temp_storage;
value_type * temp_ptr = static_cast<value_type*>(static_cast<void*>(&temp_storage));
::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
@@ -1614,7 +1596,7 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C, typename S>
void swap_dispatch(varray<value_type, C, S> & other, boost::false_type const& /*use_optimized_swap*/)
void swap_dispatch(varray<value_type, C, S> & other, false_type const& /*use_optimized_swap*/)
{
namespace sv = varray_detail;
@@ -1632,22 +1614,21 @@ private:
// Nothing.
// @par Complexity
// Linear O(N).
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::true_type const& /*use_memop*/)
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, true_type const& /*use_memop*/)
{
//BOOST_ASSERT_MSG(boost::container::iterator_distance(first_sm, last_sm) <= boost::container::iterator_distance(first_la, last_la));
namespace sv = varray_detail;
for (; first_sm != last_sm ; ++first_sm, ++first_la)
{
boost::aligned_storage<
typename aligned_storage<
sizeof(value_type),
boost::alignment_of<value_type>::value
> temp_storage;
value_type * temp_ptr = reinterpret_cast<value_type*>(temp_storage.address());
::memcpy(temp_ptr, boost::addressof(*first_sm), sizeof(value_type));
::memcpy(boost::addressof(*first_sm), boost::addressof(*first_la), sizeof(value_type));
::memcpy(boost::addressof(*first_la), temp_ptr, sizeof(value_type));
alignment_of<value_type>::value
>::type temp_storage;
value_type * temp_ptr = static_cast<value_type*>(static_cast<void*>(&temp_storage));
::memcpy(temp_ptr, (addressof)(*first_sm), sizeof(value_type));
::memcpy((addressof)(*first_sm), (addressof)(*first_la), sizeof(value_type));
::memcpy((addressof)(*first_la), temp_ptr, sizeof(value_type));
}
::memcpy(first_sm, first_la, sizeof(value_type) * boost::container::iterator_distance(first_la, last_la));
@@ -1657,7 +1638,7 @@ private:
// If Value's move constructor or move assignment throws.
// @par Complexity
// Linear O(N).
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::false_type const& /*use_memop*/)
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, false_type const& /*use_memop*/)
{
//BOOST_ASSERT_MSG(boost::container::iterator_distance(first_sm, last_sm) <= boost::container::iterator_distance(first_la, last_la));
@@ -1860,12 +1841,12 @@ private:
pointer ptr()
{
return pointer(static_cast<Value*>(m_storage.address()));
return pointer(static_cast<Value*>(static_cast<void*>(&m_storage)));
}
const_pointer ptr() const
{
return const_pointer(static_cast<const Value*>(m_storage.address()));
return pointer(static_cast<const Value*>(static_cast<const void*>(&m_storage)));
}
size_type m_size;
@@ -2091,8 +2072,8 @@ public:
}
// nothrow
Value * data() { return boost::addressof(*(this->ptr())); }
const Value * data() const { return boost::addressof(*(this->ptr())); }
Value * data() { return (addressof)(*(this->ptr())); }
const Value * data() const { return (addressof)(*(this->ptr())); }
// nothrow
iterator begin() { return this->ptr(); }

View File

@@ -17,26 +17,20 @@
#include <memory>
#include <limits>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/int.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/move/traits.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/config.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/container/detail/addressof.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/algorithm.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
// TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
@@ -47,22 +41,24 @@
namespace boost { namespace container { namespace varray_detail {
namespace bcd = ::boost::container::container_detail;
template <typename I>
struct are_elements_contiguous : boost::is_pointer<I>
struct are_elements_contiguous : boost::container::container_detail::is_pointer<I>
{};
#if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
template <typename Pointer>
struct are_elements_contiguous<
boost::container::container_detail::vector_const_iterator<Pointer>
> : boost::true_type
bcd::vector_const_iterator<Pointer>
> : bcd::true_type
{};
template <typename Pointer>
struct are_elements_contiguous<
boost::container::container_detail::vector_iterator<Pointer>
> : boost::true_type
bcd::vector_iterator<Pointer>
> : bcd::true_type
{};
#if defined(BOOST_DINKUMWARE_STDLIB)
@@ -70,21 +66,21 @@ struct are_elements_contiguous<
template <typename T>
struct are_elements_contiguous<
std::_Vector_const_iterator<T>
> : boost::true_type
> : bcd::true_type
{};
template <typename T>
struct are_elements_contiguous<
std::_Vector_iterator<T>
> : boost::true_type
> : bcd::true_type
{};
#elif defined(BOOST_GNU_STDLIB)
template <typename P, typename T, typename A>
template <typename P, typename T, typename Allocator>
struct are_elements_contiguous<
__gnu_cxx::__normal_iterator<P, std::vector<T, A> >
> : boost::true_type
__gnu_cxx::__normal_iterator<P, std::vector<T, Allocator> >
> : bcd::true_type
{};
#elif defined(_LIBCPP_VERSION)
@@ -93,7 +89,7 @@ struct are_elements_contiguous<
//template <typename P>
//struct are_elements_contiguous<
// __wrap_iter<P>
//> : boost::true_type
//> : bcd::true_type
//{};
#else // OTHER_STDLIB
@@ -104,46 +100,40 @@ struct are_elements_contiguous<
#endif // BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
}}} // namespace boost::container::varray_detail
namespace boost { namespace container { namespace varray_detail {
template <typename I, typename O>
struct are_corresponding :
::boost::mpl::and_<
::boost::is_same<
::boost::remove_const<
bcd::bool_<
bcd::is_same<
bcd::remove_const<
typename ::boost::container::iterator_traits<I>::value_type
>,
::boost::remove_const<
bcd::remove_const<
typename ::boost::container::iterator_traits<O>::value_type
>
>,
are_elements_contiguous<I>,
are_elements_contiguous<O>
>::value &&
are_elements_contiguous<I>::value &&
are_elements_contiguous<O>::value
>
{};
template <typename I, typename V>
struct is_corresponding_value :
::boost::is_same<
::boost::remove_const<
typename ::boost::container::iterator_traits<I>::value_type
>,
::boost::remove_const<V>
>
bcd::bool_<
bcd::is_same<
bcd::remove_const<typename ::boost::container::iterator_traits<I>::value_type>,
bcd::remove_const<V>
>::value
>
{};
// destroy(I, I)
template <typename I>
void destroy_dispatch(I /*first*/, I /*last*/,
boost::true_type const& /*has_trivial_destructor*/)
void destroy_dispatch(I /*first*/, I /*last*/, bcd::true_type const& /*is_trivially_destructible*/)
{}
template <typename I>
void destroy_dispatch(I first, I last,
boost::false_type const& /*has_trivial_destructor*/)
void destroy_dispatch(I first, I last, bcd::false_type const& /*is_trivially_destructible*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
for ( ; first != last ; ++first )
@@ -154,19 +144,19 @@ template <typename I>
void destroy(I first, I last)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
destroy_dispatch(first, last, has_trivial_destructor<value_type>());
destroy_dispatch(first, last, bcd::bool_<bcd::is_trivially_destructible<value_type>::value>());
}
// destroy(I)
template <typename I>
void destroy_dispatch(I /*pos*/,
boost::true_type const& /*has_trivial_destructor*/)
bcd::true_type const& /*is_trivially_destructible*/)
{}
template <typename I>
void destroy_dispatch(I pos,
boost::false_type const& /*has_trivial_destructor*/)
bcd::false_type const& /*is_trivially_destructible*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
pos->~value_type();
@@ -176,24 +166,22 @@ template <typename I>
void destroy(I pos)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
destroy_dispatch(pos, has_trivial_destructor<value_type>());
destroy_dispatch(pos, bcd::bool_<bcd::is_trivially_destructible<value_type>::value>());
}
// copy(I, I, O)
template <typename I, typename O>
inline O copy_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memmove*/)
inline O copy_dispatch(I first, I last, O dst, bcd::true_type const& /*use_memmove*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last);
::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
::memmove(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type) * d);
return dst + d;
}
template <typename I, typename O>
inline O copy_dispatch(I first, I last, O dst,
boost::mpl::bool_<false> const& /*use_memmove*/)
inline O copy_dispatch(I first, I last, O dst, bcd::false_type const& /*use_memmove*/)
{
return std::copy(first, last, dst); // may throw
}
@@ -201,16 +189,12 @@ inline O copy_dispatch(I first, I last, O dst,
template <typename I, typename O>
inline O copy(I first, I last, O dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, O>,
::boost::has_trivial_assign<
typename ::boost::container::iterator_traits<O>::value_type
>
>::type
use_memmove;
typedef bcd::bool_
< are_corresponding<I, O>::value &&
bcd::is_trivially_copy_assignable<typename ::boost::container::iterator_traits<O>::value_type>::value
> use_memmove;
return copy_dispatch(first, last, dst, use_memmove()); // may throw
return copy_dispatch(first, last, dst, use_memmove()); // may throw
}
// uninitialized_copy(I, I, O)
@@ -218,18 +202,18 @@ inline O copy(I first, I last, O dst)
template <typename I, typename O>
inline
O uninitialized_copy_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memcpy*/)
bcd::true_type const& /*use_memcpy*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last);
::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
::memcpy(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type) * d);
return dst + d;
}
template <typename I, typename F>
inline
F uninitialized_copy_dispatch(I first, I last, F dst,
boost::mpl::bool_<false> const& /*use_memcpy*/)
bcd::false_type const& /*use_memcpy*/)
{
return std::uninitialized_copy(first, last, dst); // may throw
}
@@ -238,16 +222,11 @@ template <typename I, typename F>
inline
F uninitialized_copy(I first, I last, F dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, F>,
::boost::has_trivial_copy<
typename ::boost::container::iterator_traits<F>::value_type
>
>::type
use_memcpy;
return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
typedef bcd::bool_
< are_corresponding<I, F>::value &&
bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<F>::value_type>::value
> use_memcpy;
return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
}
// uninitialized_move(I, I, O)
@@ -255,18 +234,18 @@ F uninitialized_copy(I first, I last, F dst)
template <typename I, typename O>
inline
O uninitialized_move_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memcpy*/)
bcd::true_type const& /*use_memcpy*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last);
::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
::memcpy(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type) * d);
return dst + d;
}
template <typename I, typename O>
inline
O uninitialized_move_dispatch(I first, I last, O dst,
boost::mpl::bool_<false> const& /*use_memcpy*/)
bcd::false_type const& /*use_memcpy*/)
{
//return boost::uninitialized_move(first, last, dst); // may throw
@@ -276,7 +255,7 @@ O uninitialized_move_dispatch(I first, I last, O dst,
{
typedef typename boost::container::iterator_traits<O>::value_type value_type;
for (; first != last; ++first, ++o )
new (boost::addressof(*o)) value_type(boost::move(*first));
new (boost::container::container_detail::addressof(*o)) value_type(boost::move(*first));
}
BOOST_CATCH(...)
{
@@ -292,15 +271,10 @@ template <typename I, typename O>
inline
O uninitialized_move(I first, I last, O dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, O>,
::boost::has_trivial_copy<
typename ::boost::container::iterator_traits<O>::value_type
>
>::type
use_memcpy;
typedef bcd::bool_
< are_corresponding<I, O>::value &&
bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<O>::value_type>::value
> use_memcpy;
return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw
}
@@ -311,18 +285,18 @@ O uninitialized_move(I first, I last, O dst)
template <typename I, typename O>
inline
O move_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memmove*/)
bcd::true_type const& /*use_memmove*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last);
::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type)*d );
::memmove(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type)*d );
return dst + d;
}
template <typename I, typename O>
inline
O move_dispatch(I first, I last, O dst,
boost::mpl::bool_<false> const& /*use_memmove*/)
bcd::false_type const& /*use_memmove*/)
{
return boost::move(first, last, dst); // may throw
}
@@ -331,15 +305,10 @@ template <typename I, typename O>
inline
O move(I first, I last, O dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, O>,
::boost::has_trivial_assign<
typename ::boost::container::iterator_traits<O>::value_type
>
>::type
use_memmove;
typedef bcd::bool_
< are_corresponding<I, O>::value &&
bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<O>::value_type>::value
> use_memmove;
return move_dispatch(first, last, dst, use_memmove()); // may throw
}
@@ -348,19 +317,19 @@ O move(I first, I last, O dst)
template <typename BDI, typename BDO>
inline
BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
boost::mpl::bool_<true> const& /*use_memmove*/)
bcd::true_type const& /*use_memmove*/)
{
typedef typename ::boost::container::iterator_traits<BDI>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last);
BDO foo(dst - d);
::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d);
::memmove(boost::container::container_detail::addressof(*foo), boost::container::container_detail::addressof(*first), sizeof(value_type) * d);
return foo;
}
template <typename BDI, typename BDO>
inline
BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
boost::mpl::bool_<false> const& /*use_memmove*/)
bcd::false_type const& /*use_memmove*/)
{
return boost::move_backward(first, last, dst); // may throw
}
@@ -369,29 +338,21 @@ template <typename BDI, typename BDO>
inline
BDO move_backward(BDI first, BDI last, BDO dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<BDI, BDO>,
::boost::has_trivial_assign<
typename ::boost::container::iterator_traits<BDO>::value_type
>
>::type
use_memmove;
return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
typedef bcd::bool_
< are_corresponding<BDI, BDO>::value &&
bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<BDO>::value_type>::value
> use_memmove;
return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
}
template <typename T>
struct has_nothrow_move : public
::boost::mpl::or_<
boost::mpl::bool_<
::boost::has_nothrow_move<
typename ::boost::remove_const<T>::type
>::value
>,
boost::mpl::bool_<
::boost::has_nothrow_move<T>::value
>
bcd::bool_<
::boost::has_nothrow_move<
typename bcd::remove_const<T>::type
>::value
||
::boost::has_nothrow_move<T>::value
>
{};
@@ -399,21 +360,21 @@ struct has_nothrow_move : public
template <typename I, typename O>
inline
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, bcd::true_type const& /*use_move*/)
{ return uninitialized_move(first, last, dst); }
template <typename I, typename O>
inline
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, bcd::false_type const& /*use_move*/)
{ return uninitialized_copy(first, last, dst); }
template <typename I, typename O>
inline
O uninitialized_move_if_noexcept(I first, I last, O dst)
{
typedef typename has_nothrow_move<
typedef has_nothrow_move<
typename ::boost::container::iterator_traits<O>::value_type
>::type use_move;
> use_move;
return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
}
@@ -422,21 +383,21 @@ O uninitialized_move_if_noexcept(I first, I last, O dst)
template <typename I, typename O>
inline
O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
O move_if_noexcept_dispatch(I first, I last, O dst, bcd::true_type const& /*use_move*/)
{ return move(first, last, dst); }
template <typename I, typename O>
inline
O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
O move_if_noexcept_dispatch(I first, I last, O dst, bcd::false_type const& /*use_move*/)
{ return copy(first, last, dst); }
template <typename I, typename O>
inline
O move_if_noexcept(I first, I last, O dst)
{
typedef typename has_nothrow_move<
typedef has_nothrow_move<
typename ::boost::container::iterator_traits<O>::value_type
>::type use_move;
> use_move;
return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
}
@@ -446,25 +407,25 @@ O move_if_noexcept(I first, I last, O dst)
template <typename I>
inline
void uninitialized_fill_dispatch(I first, I last,
boost::true_type const& /*has_trivial_constructor*/,
boost::true_type const& /*disable_trivial_init*/)
bcd::true_type const& /*is_trivially_default_constructible*/,
bcd::true_type const& /*disable_trivial_init*/)
{}
template <typename I>
inline
void uninitialized_fill_dispatch(I first, I last,
boost::true_type const& /*has_trivial_constructor*/,
boost::false_type const& /*disable_trivial_init*/)
bcd::true_type const& /*is_trivially_default_constructible*/,
bcd::false_type const& /*disable_trivial_init*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
for ( ; first != last ; ++first )
new (boost::addressof(*first)) value_type();
new (boost::container::container_detail::addressof(*first)) value_type();
}
template <typename I, typename DisableTrivialInit>
inline
void uninitialized_fill_dispatch(I first, I last,
boost::false_type const& /*has_trivial_constructor*/,
bcd::false_type const& /*is_trivially_default_constructible*/,
DisableTrivialInit const& /*not_used*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
@@ -473,7 +434,7 @@ void uninitialized_fill_dispatch(I first, I last,
BOOST_TRY
{
for ( ; it != last ; ++it )
new (boost::addressof(*it)) value_type(); // may throw
new (boost::container::container_detail::addressof(*it)) value_type(); // may throw
}
BOOST_CATCH(...)
{
@@ -488,22 +449,24 @@ inline
void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
uninitialized_fill_dispatch(first, last
, bcd::bool_<bcd::is_trivially_default_constructible<value_type>::value>()
, disable_trivial_init); // may throw
}
// construct(I)
template <typename I>
inline
void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I pos)
void construct_dispatch(bcd::true_type const& /*dont_init*/, I pos)
{}
template <typename I>
inline
void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos)
void construct_dispatch(bcd::false_type const& /*dont_init*/, I pos)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw
new (static_cast<void*>(::boost::container::container_detail::addressof(*pos))) value_type(); // may throw
}
template <typename DisableTrivialInit, typename I>
@@ -511,11 +474,10 @@ inline
void construct(DisableTrivialInit const&, I pos)
{
typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
typedef typename ::boost::mpl::and_<
boost::has_trivial_constructor<value_type>,
DisableTrivialInit
>::type dont_init;
bcd::bool_<
bcd::is_trivially_default_constructible<value_type>::value &&
DisableTrivialInit::value
> dont_init;
construct_dispatch(dont_init(), pos); // may throw
}
@@ -523,34 +485,29 @@ void construct(DisableTrivialInit const&, I pos)
template <typename I, typename V>
inline
void construct_dispatch(I pos, V const& v,
boost::mpl::bool_<true> const& /*use_memcpy*/)
void construct_dispatch(I pos, V const& v, bcd::true_type const& /*use_memcpy*/)
{
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
::memcpy(boost::container::container_detail::addressof(*pos), boost::container::container_detail::addressof(v), sizeof(V));
}
template <typename I, typename P>
inline
void construct_dispatch(I pos, P const& p,
boost::mpl::bool_<false> const& /*use_memcpy*/)
bcd::false_type const& /*use_memcpy*/)
{
typedef typename ::boost::container::iterator_traits<I>::value_type V;
new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw
new (static_cast<void*>(boost::container::container_detail::addressof(*pos))) V(p); // may throw
}
template <typename DisableTrivialInit, typename I, typename P>
inline
void construct(DisableTrivialInit const&,
I pos, P const& p)
void construct(DisableTrivialInit const&, I pos, P const& p)
{
typedef typename
::boost::mpl::and_<
is_corresponding_value<I, P>,
::boost::has_trivial_copy<P>
>::type
use_memcpy;
construct_dispatch(pos, p, use_memcpy()); // may throw
typedef bcd::bool_
< is_corresponding_value<I, P>::value &&
bcd::is_trivially_copy_constructible<P>::value
> use_memcpy;
construct_dispatch(pos, p, use_memcpy()); // may throw
}
// Needed by push_back(V &&)
@@ -560,13 +517,13 @@ inline
void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
{
typedef typename ::boost::container::iterator_traits<I>::value_type V;
new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw
new (static_cast<void*>(boost::container::container_detail::addressof(*pos))) V(::boost::move(p)); // may throw
}
// Needed by emplace_back() and emplace()
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename DisableTrivialInit, typename I, class ...Args>
inline
@@ -575,33 +532,27 @@ void construct(DisableTrivialInit const&,
BOOST_FWD_REF(Args) ...args)
{
typedef typename ::boost::container::iterator_traits<I>::value_type V;
new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
new (static_cast<void*>(boost::container::container_detail::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
}
#else // !BOOST_NO_VARIADIC_TEMPLATES
#else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
// BOOST_NO_RVALUE_REFERENCES -> P0 const& p0
// !BOOST_NO_RVALUE_REFERENCES -> P0 && p0
// which means that version with one parameter may take V const& v
#define BOOST_PP_LOCAL_MACRO(n) \
template <typename DisableTrivialInit, typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \
inline \
void construct(DisableTrivialInit const&, \
I pos, \
BOOST_CONTAINER_PP_PARAM(P, p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typedef typename ::boost::container::iterator_traits<I>::value_type V; \
new \
(static_cast<void*>(boost::addressof(*pos))) \
V(p, BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); /*may throw*/ \
} \
//
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE(N) \
template <typename DisableTrivialInit, typename I BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
inline void construct(DisableTrivialInit const&, I pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
{\
typedef typename ::boost::container::iterator_traits<I>::value_type V;\
new (static_cast<void*>(boost::container::container_detail::addressof(*pos)))\
V(boost::container::container_detail::addressof(*pos) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/\
}
BOOST_MOVE_ITERATE_2TO9(BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE)
#undef BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE
#endif // !BOOST_NO_VARIADIC_TEMPLATES
#endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
// assign(I, V)
@@ -609,15 +560,15 @@ void construct(DisableTrivialInit const&,
template <typename I, typename V>
inline
void assign_dispatch(I pos, V const& v,
boost::mpl::bool_<true> const& /*use_memcpy*/)
bcd::true_type const& /*use_memcpy*/)
{
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
::memcpy(boost::container::container_detail::addressof(*pos), boost::container::container_detail::addressof(v), sizeof(V));
}
template <typename I, typename V>
inline
void assign_dispatch(I pos, V const& v,
boost::mpl::bool_<false> const& /*use_memcpy*/)
bcd::false_type const& /*use_memcpy*/)
{
*pos = v; // may throw
}
@@ -626,14 +577,11 @@ template <typename I, typename V>
inline
void assign(I pos, V const& v)
{
typedef typename
::boost::mpl::and_<
is_corresponding_value<I, V>,
::boost::has_trivial_assign<V>
>::type
use_memcpy;
assign_dispatch(pos, v, use_memcpy()); // may throw
typedef bcd::bool_
< is_corresponding_value<I, V>::value &&
bcd::is_trivially_copy_assignable<V>::value
> use_memcpy;
assign_dispatch(pos, v, use_memcpy()); // may throw
}
template <typename I, typename V>

View File

@@ -27,7 +27,7 @@ doxygen autodoc
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
\"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\
\"BOOST_MOVE_IMPDEF(T)=implementation_defined\" \\
\"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\
\"BOOST_CONTAINER_NOEXCEPT=noexcept\" \\
\"BOOST_CONTAINER_NOEXCEPT_IF(T)=noexcept(T)\" \\
@@ -41,6 +41,8 @@ doxygen autodoc
\"BOOST_CONTAINER_DOC1ST(T1, T2)=T1\" \\
\"BOOST_CONTAINER_DOCIGN(T) \"\\
\"BOOST_CONTAINER_DOCONLY(T) T\"\\
\"BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE=\"\\
\"BOOST_CONTAINER_SCOPEDALLOC_ALLINNER=InnerAllocs...\"\\
"
<xsl:param>"boost.doxygen.reftitle=Boost.Container Header Reference"
;

View File

@@ -729,7 +729,7 @@ are movable, requirements for `value_type` are those specified for C++11 contain
For compilers with variadic templates, [*Boost.Container] supports placement insertion
(`emplace`, ...) functions from C++11. For those compilers without variadic templates
support [*Boost.Container] uses the preprocessor to create a set of overloads up to
a finite (10) number of parameters.
a finite number of parameters.
[endsect]
@@ -777,7 +777,8 @@ is the outer allocator for use by the container, the second allocator is passed
container's elements, and, if the elements themselves are containers, the third allocator is passed to the
elements' elements, and so on.
[*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also
[*Boost.Container] implements its own [classref boost::container::scoped_allocator_adaptor scoped_allocator_adaptor]
class and [*backports this feature also
to C++03 compilers]. Due to C++03 limitations, in those compilers
the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions
will be based on traits ([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix]
@@ -1080,10 +1081,18 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes]
[section:release_notes_boost_1_58_00 Boost 1.58 Release]
* Massive dependency reorganization. Now [*Boost.Container depends on very basic utilities like Boost.Core
and [*Boost.Intrusive]. Preprocessed code size have decreased considerably and compilation times have improved.
* Added `nth` and `index_of` functions to containers with random-access iterators (except `basic_string`).
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/10790 Trac #10790 (['long long errors from container"])].
* [@https://svn.boost.org/trac/boost/ticket/10808 Trac #10808 (['compare equal operator of vector is broken"])].
* [*Source Breaking]: [classref boost::container::scoped_allocator_adaptor scoped_allocator_adaptor]'s
`propagate_on_container_copy_assignment`, `propagate_on_container_move_assignment` and `propagate_on_container_swap`
are no longer `::boost::integral_constant<bool, true/false>` types. The dependency reorganization needed to break
with those classes to avoid MPL dependencies, and interoperability with `std::integral_constant` was not guaranteed.
Code assumming `boost::true_type/boost::false_type` on this will not compile. As a workaround, use the guarantee internal
`::value` constant: `::boost::integral_constant<bool, scoped_allocator_adaptor<Allocator>::propagate_on_container_move_assignment::value>`.
[endsect]

View File

@@ -25,14 +25,11 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/alloc_lib_auto_link.hpp>
#include <boost/container/detail/singleton.hpp>
#include <boost/container/detail/placement_new.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/utility_core.hpp>
#include <utility>
#include <cstddef>
@@ -56,7 +53,7 @@ template < class T
, std::size_t NodesPerBlock BOOST_CONTAINER_DOCONLY(= ADP_nodes_per_block)
, std::size_t MaxFreeBlocks BOOST_CONTAINER_DOCONLY(= ADP_max_free_blocks)
, std::size_t OverheadPercent BOOST_CONTAINER_DOCONLY(= ADP_overhead_percent)
BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I unsigned Version)
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I unsigned Version)
>
class adaptive_pool
{
@@ -66,7 +63,7 @@ class adaptive_pool
typedef unsigned int allocation_type;
typedef adaptive_pool
<T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I Version)
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
> self_t;
static const std::size_t nodes_per_block = NodesPerBlock;
@@ -109,7 +106,7 @@ class adaptive_pool
, NodesPerBlock
, MaxFreeBlocks
, OverheadPercent
BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I Version)
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
> other;
};
@@ -137,7 +134,7 @@ class adaptive_pool
template<class T2>
adaptive_pool
(const adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I Version)> &) BOOST_CONTAINER_NOEXCEPT
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)> &) BOOST_CONTAINER_NOEXCEPT
{}
//!Destructor
@@ -153,7 +150,7 @@ class adaptive_pool
//!Throws std::bad_alloc if there is no enough memory
pointer allocate(size_type count, const void * = 0)
{
if(count > this->max_size())
if(BOOST_UNLIKELY(count > this->max_size()))
boost::container::throw_bad_alloc();
if(Version == 1 && count == 1){
@@ -183,15 +180,13 @@ class adaptive_pool
}
}
std::pair<pointer, bool>
allocation_command(allocation_type command,
pointer allocation_command(allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, pointer reuse = pointer())
size_type &prefer_in_recvd_out_size,
pointer &reuse)
{
std::pair<pointer, bool> ret =
this->priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
boost::container::throw_bad_alloc();
return ret;
}
@@ -254,14 +249,15 @@ class adaptive_pool
BOOST_STATIC_ASSERT(( Version > 1 ));/*
boost_cont_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes
(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}
@@ -273,14 +269,15 @@ class adaptive_pool
BOOST_STATIC_ASSERT(( Version > 1 ));/*
boost_cont_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
if(BOOST_UNLIKELY(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
if(BOOST_UNLIKELY(!boost_cont_multialloc_arrays
(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}
@@ -320,23 +317,25 @@ class adaptive_pool
{ return false; }
private:
std::pair<pointer, bool> priv_allocation_command
pointer priv_allocation_command
(allocation_type command, std::size_t limit_size
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr)
{
std::size_t const preferred_size = prefer_in_recvd_out_size;
boost_cont_command_ret_t ret = {0 , 0};
if(limit_size > this->max_size() || preferred_size > this->max_size()){
// ret.first = 0;
return std::pair<pointer, bool>(pointer(), false);
if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){
return pointer();
}
std::size_t l_size = limit_size*sizeof(T);
std::size_t p_size = preferred_size*sizeof(T);
std::size_t r_size;
{
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
void* reuse_ptr_void = reuse_ptr;
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
}
received_size = r_size/sizeof(T);
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
prefer_in_recvd_out_size = r_size/sizeof(T);
return (pointer)ret.first;
}
};

View File

@@ -25,7 +25,6 @@
#include <boost/static_assert.hpp>
#include <cstddef>
#include <cassert>
#include <new>
namespace boost {
namespace container {
@@ -218,18 +217,16 @@ class allocator
//!capabilities. Memory allocated with this function can only be deallocated with deallocate()
//!or deallocate_many().
//!This function is available only with Version == 2
std::pair<pointer, bool>
allocation_command(allocation_type command,
pointer allocation_command(allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, pointer reuse = pointer())
size_type &prefer_in_recvd_out_size,
pointer &reuse)
{
BOOST_STATIC_ASSERT(( Version > 1 ));
const allocation_type mask(AllocationDisableMask);
command &= ~mask;
std::pair<pointer, bool> ret =
priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
if(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
boost::container::throw_bad_alloc();
return ret;
}
@@ -339,22 +336,26 @@ class allocator
private:
std::pair<pointer, bool> priv_allocation_command
(allocation_type command, std::size_t limit_size
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
pointer priv_allocation_command
(allocation_type command, std::size_t limit_size
,size_type &prefer_in_recvd_out_size
,pointer &reuse_ptr)
{
std::size_t const preferred_size = prefer_in_recvd_out_size;
boost_cont_command_ret_t ret = {0 , 0};
if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
return std::pair<pointer, bool>(pointer(), false);
return pointer();
}
std::size_t l_size = limit_size*sizeof(T);
std::size_t p_size = preferred_size*sizeof(T);
std::size_t r_size;
{
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
void* reuse_ptr_void = reuse_ptr;
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
}
received_size = r_size/sizeof(T);
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
prefer_in_recvd_out_size = r_size/sizeof(T);
return (pointer)ret.first;
}
};

View File

@@ -13,7 +13,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
@@ -23,25 +22,52 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/memory_util.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/placement_new.hpp>
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
#include <boost/container/detail/std_fwd.hpp>
#endif
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
// move
#include <boost/move/utility_core.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp>
#include <boost/move/detail/fwd_macros.hpp>
#endif
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
namespace boost {
namespace container {
namespace allocator_traits_detail {
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size)
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction)
}
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -50,7 +76,7 @@ namespace container_detail {
//workaround needed for C++03 compilers with no construct()
//supporting rvalue references
template<class A>
template<class Allocator>
struct is_std_allocator
{ static const bool value = false; };
@@ -59,11 +85,11 @@ struct is_std_allocator< std::allocator<T> >
{ static const bool value = true; };
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer)
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(void_pointer)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_void_pointer)
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer)
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
@@ -76,50 +102,50 @@ BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
//! The class template allocator_traits supplies a uniform interface to all allocator types.
//! This class is a C++03-compatible implementation of std::allocator_traits
template <typename Alloc>
template <typename Allocator>
struct allocator_traits
{
//allocator_type
typedef Alloc allocator_type;
typedef Allocator allocator_type;
//value_type
typedef typename Alloc::value_type value_type;
typedef typename allocator_type::value_type value_type;
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! Alloc::pointer if such a type exists; otherwise, value_type*
//! Allocator::pointer if such a type exists; otherwise, value_type*
//!
typedef unspecified pointer;
//! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
//! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
//!
typedef see_documentation const_pointer;
//! Non-standard extension
//! Alloc::reference if such a type exists; otherwise, value_type&
//! Allocator::reference if such a type exists; otherwise, value_type&
typedef see_documentation reference;
//! Non-standard extension
//! Alloc::const_reference if such a type exists ; otherwise, const value_type&
//! Allocator::const_reference if such a type exists ; otherwise, const value_type&
typedef see_documentation const_reference;
//! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
//! Allocator::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
//!
typedef see_documentation void_pointer;
//! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
//! Allocator::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
//!
typedef see_documentation const_void_pointer;
//! Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
//! Allocator::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
//!
typedef see_documentation difference_type;
//! Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
//! Allocator::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
//!
typedef see_documentation size_type;
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member <code>value</code> == false.
//! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type
//! with an internal constant static boolean member <code>value</code> == false.
typedef see_documentation propagate_on_container_copy_assignment;
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member <code>value</code> == false.
//! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise otherwise a type
//! with an internal constant static boolean member <code>value</code> == false.
typedef see_documentation propagate_on_container_move_assignment;
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
//! type with internal constant static member <code>value</code> == false.
//! Allocator::propagate_on_container_swap if such a type exists, otherwise an otherwise a type
//! with an internal constant static boolean member <code>value</code> == false.
typedef see_documentation propagate_on_container_swap;
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
//! Defines an allocator: Allocator::rebind<T>::other if such a type exists; otherwise, Allocator<T, Args>
//! if Allocator is a class template instantiation of the form Allocator<U, Args>, where Args is zero or
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
//!
//! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
@@ -132,114 +158,110 @@ struct allocator_traits
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
//! <code>type</code> is an allocator related to Alloc deduced deduced by rules explained in <code>rebind_alloc</code>.
//! <code>type</code> is an allocator related to Allocator deduced deduced by rules explained in <code>rebind_alloc</code>.
template <class T>
struct portable_rebind_alloc
{ typedef see_documentation type; };
#else
//pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
pointer, value_type*)
pointer;
//const_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const value_type>)
const_pointer;
//reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
reference, typename container_detail::unvoid<value_type>::type&)
reference;
//const_reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
const_reference, const typename container_detail::unvoid<value_type>::type&)
const_reference;
//void_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<void>)
void_pointer;
//const_void_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const void>)
const_void_pointer;
//difference_type
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
difference_type, std::ptrdiff_t)
difference_type;
//size_type
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
size_type, std::size_t)
size_type;
//propagate_on_container_copy_assignment
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
propagate_on_container_copy_assignment, container_detail::false_type)
propagate_on_container_copy_assignment;
//propagate_on_container_move_assignment
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
propagate_on_container_move_assignment, container_detail::false_type)
propagate_on_container_move_assignment;
//propagate_on_container_swap
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
propagate_on_container_swap, container_detail::false_type)
propagate_on_container_swap;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//C++11
template <typename T> using rebind_alloc = typename boost::intrusive::pointer_rebind<Alloc, T>::type;
template <typename T> using rebind_alloc = typename boost::intrusive::pointer_rebind<Allocator, T>::type;
template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
#else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//Some workaround for C++03 or C++11 compilers with no template aliases
template <typename T>
struct rebind_alloc : boost::intrusive::pointer_rebind<Alloc,T>::type
struct rebind_alloc : boost::intrusive::pointer_rebind<Allocator,T>::type
{
typedef typename boost::intrusive::pointer_rebind<Alloc,T>::type Base;
typedef typename boost::intrusive::pointer_rebind<Allocator,T>::type Base;
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename... Args>
rebind_alloc(BOOST_FWD_REF(Args)... args)
: Base(boost::forward<Args>(args)...)
{}
template <typename... Args>
rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward<Args>(args)...) {}
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC)
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
};
template <typename T>
struct rebind_traits
: allocator_traits<typename boost::intrusive::pointer_rebind<Alloc, T>::type>
: allocator_traits<typename boost::intrusive::pointer_rebind<Allocator, T>::type>
{};
#endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T>
struct portable_rebind_alloc
{ typedef typename boost::intrusive::pointer_rebind<Alloc, T>::type type; };
{ typedef typename boost::intrusive::pointer_rebind<Allocator, T>::type type; };
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: <code>a.allocate(n)</code>
//!
static pointer allocate(Alloc &a, size_type n)
static pointer allocate(Allocator &a, size_type n)
{ return a.allocate(n); }
//! <b>Returns</b>: <code>a.deallocate(p, n)</code>
//!
//! <b>Throws</b>: Nothing
static void deallocate(Alloc &a, pointer p, size_type n)
static void deallocate(Allocator &a, pointer p, size_type n)
{ a.deallocate(p, n); }
//! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
//! otherwise, invokes <code>a.allocate(n)</code>
static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
static pointer allocate(Allocator &a, size_type n, const_void_pointer p)
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_allocate
<Alloc, const size_type, const const_void_pointer>::value;
<Allocator, const size_type, const const_void_pointer>::value;
container_detail::bool_<value> flag;
return allocator_traits::priv_allocate(flag, a, n, p);
}
@@ -247,23 +269,21 @@ struct allocator_traits
//! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
//! otherwise, invokes <code>p->~T()</code>.
template<class T>
static void destroy(Alloc &a, T*p) BOOST_CONTAINER_NOEXCEPT
static void destroy(Allocator &a, T*p) BOOST_CONTAINER_NOEXCEPT
{
typedef T* destroy_pointer;
const bool value = boost::container::container_detail::
has_member_function_callable_with_destroy
<Alloc, const destroy_pointer>::value;
<Allocator, const destroy_pointer>::value;
container_detail::bool_<value> flag;
allocator_traits::priv_destroy(flag, a, p);
}
//! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
//! <code>numeric_limits<size_type>::max()</code>.
static size_type max_size(const Alloc &a) BOOST_CONTAINER_NOEXCEPT
static size_type max_size(const Allocator &a) BOOST_CONTAINER_NOEXCEPT
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_max_size
<const Alloc>::value;
const bool value = allocator_traits_detail::has_max_size<Allocator, size_type (Allocator::*)() const>::value;
container_detail::bool_<value> flag;
return allocator_traits::priv_max_size(flag, a);
}
@@ -273,20 +293,17 @@ struct allocator_traits
static
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
typename container_detail::if_c
< boost::container::container_detail::
has_member_function_callable_with_select_on_container_copy_construction
<const Alloc>::value
, Alloc
, const Alloc &
< allocator_traits_detail::has_select_on_container_copy_construction<Allocator, Allocator (Allocator::*)() const>::value
, Allocator
, const Allocator &
>::type
#else
Alloc
Allocator
#endif
select_on_container_copy_construction(const Alloc &a)
select_on_container_copy_construction(const Allocator &a)
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_select_on_container_copy_construction
<const Alloc>::value;
const bool value = allocator_traits_detail::has_select_on_container_copy_construction
<Allocator, Allocator (Allocator::*)() const>::value;
container_detail::bool_<value> flag;
return allocator_traits::priv_select_on_container_copy_construction(flag, a);
}
@@ -295,119 +312,107 @@ struct allocator_traits
//! <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>
template <class T, class ...Args>
static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args)
{
container_detail::bool_<container_detail::is_std_allocator<Alloc>::value> flag;
container_detail::bool_<container_detail::is_std_allocator<Allocator>::value> flag;
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
}
#endif
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
private:
static pointer priv_allocate(container_detail::true_type, Alloc &a, size_type n, const_void_pointer p)
static pointer priv_allocate(container_detail::true_type, Allocator &a, size_type n, const_void_pointer p)
{ return a.allocate(n, p); }
static pointer priv_allocate(container_detail::false_type, Alloc &a, size_type n, const_void_pointer)
static pointer priv_allocate(container_detail::false_type, Allocator &a, size_type n, const_void_pointer)
{ return a.allocate(n); }
template<class T>
static void priv_destroy(container_detail::true_type, Alloc &a, T* p) BOOST_CONTAINER_NOEXCEPT
static void priv_destroy(container_detail::true_type, Allocator &a, T* p) BOOST_CONTAINER_NOEXCEPT
{ a.destroy(p); }
template<class T>
static void priv_destroy(container_detail::false_type, Alloc &, T* p) BOOST_CONTAINER_NOEXCEPT
static void priv_destroy(container_detail::false_type, Allocator &, T* p) BOOST_CONTAINER_NOEXCEPT
{ p->~T(); (void)p; }
static size_type priv_max_size(container_detail::true_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
static size_type priv_max_size(container_detail::true_type, const Allocator &a) BOOST_CONTAINER_NOEXCEPT
{ return a.max_size(); }
static size_type priv_max_size(container_detail::false_type, const Alloc &) BOOST_CONTAINER_NOEXCEPT
static size_type priv_max_size(container_detail::false_type, const Allocator &) BOOST_CONTAINER_NOEXCEPT
{ return size_type(-1); }
static Alloc priv_select_on_container_copy_construction(container_detail::true_type, const Alloc &a)
static Allocator priv_select_on_container_copy_construction(container_detail::true_type, const Allocator &a)
{ return a.select_on_container_copy_construction(); }
static const Alloc &priv_select_on_container_copy_construction(container_detail::false_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
static const Allocator &priv_select_on_container_copy_construction(container_detail::false_type, const Allocator &a) BOOST_CONTAINER_NOEXCEPT
{ return a; }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class ...Args>
static void priv_construct(container_detail::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
static void priv_construct(container_detail::false_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_construct
< Alloc, T*, Args... >::value;
< Allocator, T*, Args... >::value;
container_detail::bool_<value> flag;
priv_construct_dispatch2(flag, a, p, ::boost::forward<Args>(args)...);
(priv_construct_dispatch_next)(flag, a, p, ::boost::forward<Args>(args)...);
}
template<class T, class ...Args>
static void priv_construct(container_detail::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
{
priv_construct_dispatch2(container_detail::false_type(), a, p, ::boost::forward<Args>(args)...);
}
static void priv_construct(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
{ (priv_construct_dispatch_next)(container_detail::false_type(), a, p, ::boost::forward<Args>(args)...); }
template<class T, class ...Args>
static void priv_construct_dispatch2(container_detail::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
{ a.construct( p, ::boost::forward<Args>(args)...); }
template<class T, class ...Args>
static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args)
static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args)
{ ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); }
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
public:
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
static void construct(Alloc &a, T *p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
container_detail::bool_ \
<container_detail::is_std_allocator<Alloc>::value> flag; \
allocator_traits::priv_construct(flag, a, p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
container_detail::bool_<container_detail::is_std_allocator<Allocator>::value> flag;\
(priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
}\
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
private:
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
static void priv_construct(container_detail::false_type, Alloc &a, T *p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
{ \
const bool value = \
boost::container::container_detail::has_member_function_callable_with_construct \
< Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value; \
container_detail::bool_<value> flag; \
priv_construct_dispatch2(flag, a, p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
} \
\
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
static void priv_construct(container_detail::true_type, Alloc &a, T *p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
{ \
priv_construct_dispatch2(container_detail::false_type(), a, p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
} \
\
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
static void priv_construct_dispatch2(container_detail::true_type, Alloc &a, T *p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
{ a.construct( p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); } \
\
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
{ ::new((void*)p, boost_container_new_t()) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
static void priv_construct(container_detail::false_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
const bool value = boost::container::container_detail::has_member_function_callable_with_construct\
< Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N>::value;\
container_detail::bool_<value> flag;\
(priv_construct_dispatch_next)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
}\
\
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ (priv_construct_dispatch_next)(container_detail::false_type(), a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
\
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\
\
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL)
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T>
static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p, ::boost::container::default_init_t)
static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
{ ::new((void*)p) T; }
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)

View File

@@ -80,27 +80,30 @@ enum tree_type_enum
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template<class T>
class new_allocator;
template <class T
,class A = std::allocator<T> >
,class Allocator = new_allocator<T> >
class vector;
template <class T
,class A = std::allocator<T> >
,class Allocator = new_allocator<T> >
class stable_vector;
template <class T, std::size_t Capacity>
class static_vector;
template <class T
,class A = std::allocator<T> >
,class Allocator = new_allocator<T> >
class deque;
template <class T
,class A = std::allocator<T> >
,class Allocator = new_allocator<T> >
class list;
template <class T
,class A = std::allocator<T> >
,class Allocator = new_allocator<T> >
class slist;
template<tree_type_enum TreeType, bool OptimizeSize>
@@ -110,67 +113,67 @@ typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
template <class Key
,class Compare = std::less<Key>
,class A = std::allocator<Key>
,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults >
class set;
template <class Key
,class Compare = std::less<Key>
,class A = std::allocator<Key>
,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults >
class multiset;
template <class Key
,class T
,class Compare = std::less<Key>
,class A = std::allocator<std::pair<const Key, T> >
,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults >
class map;
template <class Key
,class T
,class Compare = std::less<Key>
,class A = std::allocator<std::pair<const Key, T> >
,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults >
class multimap;
template <class Key
,class Compare = std::less<Key>
,class A = std::allocator<Key> >
,class Allocator = new_allocator<Key> >
class flat_set;
template <class Key
,class Compare = std::less<Key>
,class A = std::allocator<Key> >
,class Allocator = new_allocator<Key> >
class flat_multiset;
template <class Key
,class T
,class Compare = std::less<Key>
,class A = std::allocator<std::pair<Key, T> > >
,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_map;
template <class Key
,class T
,class Compare = std::less<Key>
,class A = std::allocator<std::pair<Key, T> > >
,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_multimap;
template <class CharT
,class Traits = std::char_traits<CharT>
,class A = std::allocator<CharT> >
,class Allocator = new_allocator<CharT> >
class basic_string;
typedef basic_string
<char
,std::char_traits<char>
,std::allocator<char> >
,new_allocator<char> >
string;
typedef basic_string
<wchar_t
,std::char_traits<wchar_t>
,std::allocator<wchar_t> >
,new_allocator<wchar_t> >
wstring;
static const std::size_t ADP_nodes_per_block = 256u;

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DEQUE_HPP
#define BOOST_CONTAINER_DEQUE_HPP
@@ -17,35 +16,39 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/mpl.hpp>
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_nothrow_copy.hpp>
#include <boost/type_traits/has_nothrow_assign.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <boost/move/algorithm.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
// container/detail
#include <boost/container/detail/advanced_insert_int.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#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/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/container/detail/type_traits.hpp>
// move
#include <boost/move/adl_move_swap.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/detail/move_helpers.hpp>
// other
#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
// std
#include <cstddef>
#include <memory> //std::allocator
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -54,20 +57,15 @@ namespace boost {
namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A>
template <class T, class Allocator>
class deque;
template <class T>
struct deque_value_traits
{
typedef T value_type;
static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
static const bool trivial_dctr = container_detail::is_trivially_destructible<value_type>::value;
static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
static const bool trivial_copy = has_trivial_copy<value_type>::value;
static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
static const bool trivial_assign = has_trivial_assign<value_type>::value;
//static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
static const bool nothrow_assign = false;
};
// Note: this function is simply a kludge to work around several compilers'
@@ -276,12 +274,12 @@ class deque_iterator
// Deque base class. It has two purposes. First, its constructor
// and destructor allocate (but don't initialize) storage. This makes
// exception safety easier.
template <class A>
template <class Allocator>
class deque_base
{
BOOST_COPYABLE_AND_MOVABLE(deque_base)
public:
typedef allocator_traits<A> val_alloc_traits_type;
typedef allocator_traits<Allocator> val_alloc_traits_type;
typedef typename val_alloc_traits_type::value_type val_alloc_val;
typedef typename val_alloc_traits_type::pointer val_alloc_ptr;
typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr;
@@ -297,7 +295,7 @@ class deque_base
typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr;
typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref;
typedef A allocator_type;
typedef Allocator allocator_type;
typedef allocator_type stored_allocator_type;
typedef val_alloc_size size_type;
@@ -476,16 +474,16 @@ class deque_base
//! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.
//!
//! \tparam T The type of object that is stored in the deque
//! \tparam A The allocator used for all internal memory management
template <class T, class A = std::allocator<T> >
//! \tparam Allocator The allocator used for all internal memory management
template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class A>
template <class T, class Allocator>
#endif
class deque : protected deque_base<A>
class deque : protected deque_base<Allocator>
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
typedef deque_base<A> Base;
typedef deque_base<Allocator> Base;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -497,18 +495,18 @@ class deque : protected deque_base<A>
//////////////////////////////////////////////
typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef BOOST_MOVE_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(typename Base::iterator) iterator;
typedef BOOST_MOVE_IMPDEF(typename Base::const_iterator) const_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -517,7 +515,7 @@ class deque : protected deque_base<A>
typedef typename Base::ptr_alloc_ptr index_pointer;
static size_type s_buffer_size()
{ return Base::s_buffer_size(); }
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -556,7 +554,7 @@ class deque : protected deque_base<A>
explicit deque(size_type n)
: Base(n, allocator_type())
{
container_detail::insert_value_initialized_n_proxy<A, iterator> proxy;
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
//deque_base will deallocate in case of exception...
}
@@ -573,7 +571,7 @@ class deque : protected deque_base<A>
deque(size_type n, default_init_t)
: Base(n, allocator_type())
{
container_detail::insert_default_initialized_n_proxy<A, iterator> proxy;
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
//deque_base will deallocate in case of exception...
}
@@ -1031,7 +1029,7 @@ class deque : protected deque_base<A>
this->priv_erase_last_n(len - new_size);
else{
const size_type n = new_size - this->size();
container_detail::insert_value_initialized_n_proxy<A, iterator> proxy;
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
priv_insert_back_aux_impl(n, proxy);
}
}
@@ -1051,7 +1049,7 @@ class deque : protected deque_base<A>
this->priv_erase_last_n(len - new_size);
else{
const size_type n = new_size - this->size();
container_detail::insert_default_initialized_n_proxy<A, iterator> proxy;
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
priv_insert_back_aux_impl(n, proxy);
}
}
@@ -1249,7 +1247,7 @@ class deque : protected deque_base<A>
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the beginning of the deque.
@@ -1258,7 +1256,7 @@ class deque : protected deque_base<A>
//!
//! <b>Complexity</b>: Amortized constant time
template <class... Args>
void emplace_front(Args&&... args)
void emplace_front(BOOST_FWD_REF(Args)... args)
{
if(this->priv_push_front_simple_available()){
allocator_traits_type::construct
@@ -1268,7 +1266,7 @@ class deque : protected deque_base<A>
this->priv_push_front_simple_commit();
}
else{
typedef container_detail::insert_non_movable_emplace_proxy<A, iterator, Args...> type;
typedef container_detail::insert_nonmovable_emplace_proxy<Allocator, iterator, Args...> type;
this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
}
}
@@ -1280,7 +1278,7 @@ class deque : protected deque_base<A>
//!
//! <b>Complexity</b>: Amortized constant time
template <class... Args>
void emplace_back(Args&&... args)
void emplace_back(BOOST_FWD_REF(Args)... args)
{
if(this->priv_push_back_simple_available()){
allocator_traits_type::construct
@@ -1290,7 +1288,7 @@ class deque : protected deque_base<A>
this->priv_push_back_simple_commit();
}
else{
typedef container_detail::insert_non_movable_emplace_proxy<A, iterator, Args...> type;
typedef container_detail::insert_nonmovable_emplace_proxy<Allocator, iterator, Args...> type;
this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
}
}
@@ -1305,7 +1303,7 @@ class deque : protected deque_base<A>
//! <b>Complexity</b>: If p is end(), amortized constant time
//! Linear time otherwise.
template <class... Args>
iterator emplace(const_iterator p, Args&&... args)
iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{
if(p == this->cbegin()){
this->emplace_front(boost::forward<Args>(args)...);
@@ -1316,75 +1314,66 @@ class deque : protected deque_base<A>
return (this->end()-1);
}
else{
typedef container_detail::insert_emplace_proxy<A, iterator, Args...> type;
typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
}
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//advanced_insert_int.hpp includes all necessary preprocessor machinery...
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, > ) \
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
if(priv_push_front_simple_available()){ \
allocator_traits_type::construct \
( this->alloc() \
, this->priv_push_front_simple_pos() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_push_front_simple_commit(); \
} \
else{ \
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
priv_insert_front_aux_impl \
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
if(priv_push_back_simple_available()){ \
allocator_traits_type::construct \
( this->alloc() \
, this->priv_push_back_simple_pos() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_push_back_simple_commit(); \
} \
else{ \
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
priv_insert_back_aux_impl \
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
if(p == this->cbegin()){ \
this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
return this->begin(); \
} \
else if(p == cend()){ \
this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
return (this->end()-1); \
} \
else{ \
typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
return this->priv_insert_aux_impl \
(p, 1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
void emplace_front(BOOST_MOVE_UREF##N)\
{\
if(priv_push_front_simple_available()){\
allocator_traits_type::construct\
( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
priv_push_front_simple_commit();\
}\
else{\
typedef container_detail::insert_nonmovable_emplace_proxy##N\
<Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
}\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
void emplace_back(BOOST_MOVE_UREF##N)\
{\
if(priv_push_back_simple_available()){\
allocator_traits_type::construct\
( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
priv_push_back_simple_commit();\
}\
else{\
typedef container_detail::insert_nonmovable_emplace_proxy##N\
<Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
}\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
if(p == this->cbegin()){\
this->emplace_front(BOOST_MOVE_FWD##N);\
return this->begin();\
}\
else if(p == cend()){\
this->emplace_back(BOOST_MOVE_FWD##N);\
return (--this->end());\
}\
else{\
typedef container_detail::insert_emplace_proxy_arg##N\
<Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
}\
}
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
#undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the front of the deque.
@@ -1526,7 +1515,7 @@ class deque : protected deque_base<A>
#endif
)
{
container_detail::insert_range_proxy<A, FwdIt, iterator> proxy(first);
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
return priv_insert_aux_impl(p, boost::container::iterator_distance(first, last), proxy);
}
#endif
@@ -1581,11 +1570,11 @@ class deque : protected deque_base<A>
++next;
size_type index = pos - this->members_.m_start;
if (index < (this->size()/2)) {
boost::move_backward(this->begin(), pos.unconst(), next);
boost::container::move_backward(this->begin(), pos.unconst(), next);
pop_front();
}
else {
boost::move(next, this->end(), pos.unconst());
boost::container::move(next, this->end(), pos.unconst());
pop_back();
}
return this->members_.m_start + index;
@@ -1609,7 +1598,7 @@ class deque : protected deque_base<A>
const size_type n = static_cast<size_type>(last - first);
const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
if (elems_before < (this->size() - n) - elems_before) {
boost::move_backward(begin(), first.unconst(), last.unconst());
boost::container::move_backward(begin(), first.unconst(), last.unconst());
iterator new_start = this->members_.m_start + n;
if(!Base::traits_t::trivial_dctr_after_move)
this->priv_destroy_range(this->members_.m_start, new_start);
@@ -1617,7 +1606,7 @@ class deque : protected deque_base<A>
this->members_.m_start = new_start;
}
else {
boost::move(last.unconst(), end(), first.unconst());
boost::container::move(last.unconst(), end(), first.unconst());
iterator new_finish = this->members_.m_finish - n;
if(!Base::traits_t::trivial_dctr_after_move)
this->priv_destroy_range(new_finish, this->members_.m_finish);
@@ -1749,7 +1738,7 @@ class deque : protected deque_base<A>
else {
return priv_insert_aux_impl
( p, (size_type)1
, container_detail::get_insert_value_proxy<iterator, A>(::boost::forward<U>(x)));
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
}
}
@@ -1764,7 +1753,7 @@ class deque : protected deque_base<A>
else{
priv_insert_aux_impl
( this->cbegin(), (size_type)1
, container_detail::get_insert_value_proxy<iterator, A>(::boost::forward<U>(x)));
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
}
}
@@ -1779,7 +1768,7 @@ class deque : protected deque_base<A>
else{
priv_insert_aux_impl
( this->cend(), (size_type)1
, container_detail::get_insert_value_proxy<iterator, A>(::boost::forward<U>(x)));
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
}
}
@@ -1813,21 +1802,19 @@ class deque : protected deque_base<A>
void priv_destroy_range(iterator p, iterator p2)
{
for(;p != p2; ++p){
allocator_traits_type::destroy
( this->alloc()
, container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p))
);
if(!Base::traits_t::trivial_dctr){
for(;p != p2; ++p){
allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
}
}
}
void priv_destroy_range(pointer p, pointer p2)
{
for(;p != p2; ++p){
allocator_traits_type::destroy
( this->alloc()
, container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p))
);
if(!Base::traits_t::trivial_dctr){
for(;p != p2; ++p){
allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
}
}
}
@@ -1857,7 +1844,7 @@ class deque : protected deque_base<A>
::boost::container::uninitialized_move_alloc
(this->alloc(), this->members_.m_start, start_n, new_start);
this->members_.m_start = new_start;
boost::move(start_n, pos, old_start);
boost::container::move(start_n, pos, old_start);
proxy.copy_n_and_update(this->alloc(), pos - n, n);
}
else {
@@ -1887,7 +1874,7 @@ class deque : protected deque_base<A>
::boost::container::uninitialized_move_alloc
(this->alloc(), finish_n, old_finish, old_finish);
this->members_.m_finish = new_finish;
boost::move_backward(pos, finish_n, old_finish);
boost::container::move_backward(pos, finish_n, old_finish);
proxy.copy_n_and_update(this->alloc(), pos, n);
}
else {
@@ -2092,9 +2079,9 @@ class deque : protected deque_base<A>
new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
if (new_nstart < this->members_.m_start.m_node)
boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
else
boost::move_backward
boost::container::move_backward
(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
}
else {
@@ -2104,7 +2091,7 @@ class deque : protected deque_base<A>
index_pointer new_map = this->priv_allocate_map(new_map_size);
new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
this->members_.m_map = new_map;
@@ -2125,10 +2112,13 @@ namespace boost {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class A>
struct has_trivial_destructor_after_move<boost::container::deque<T, A> >
: public ::boost::has_trivial_destructor_after_move<A>
{};
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};
}

View File

@@ -19,13 +19,14 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/container/detail/alloc_lib_auto_link.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/detail/pool_common_alloc.hpp>
#include <boost/container/detail/mutex.hpp>
#include <boost/container/detail/adaptive_node_pool_impl.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <cstddef>
#include <cmath>
#include <cassert>

View File

@@ -18,17 +18,23 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/throw_exception.hpp>
// 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/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.hpp>
#include <boost/container/throw_exception.hpp>
// other
#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <cstddef>
@@ -482,7 +488,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_pointer(itf));
void *pElem = container_detail::to_raw_pointer(container_detail::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;

View File

@@ -0,0 +1,37 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_ADDRESSOF_HPP
#define BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <cstddef>
namespace boost {
namespace container {
namespace container_detail {
template <typename T>
inline T* addressof(T& obj)
{
return static_cast<T*>(
static_cast<void*>(
const_cast<char*>(
&reinterpret_cast<const char&>(obj)
)));
}
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP

View File

@@ -18,38 +18,44 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/allocator_traits.hpp>
// container/detail
#include <boost/container/detail/copy_move_algo.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/utilities.hpp>
#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>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
// move
#include <boost/move/utility_core.hpp>
// other
#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
namespace boost { namespace container { namespace container_detail {
template<class A, class FwdIt, class Iterator>
template<class Allocator, class FwdIt, class Iterator>
struct move_insert_range_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<Allocator>::value_type value_type;
explicit move_insert_range_proxy(FwdIt first)
: first_(first)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
{
this->first_ = ::boost::container::uninitialized_move_alloc_n_source
(a, this->first_, n, p);
}
void copy_n_and_update(A &, Iterator p, size_type n)
void copy_n_and_update(Allocator &, Iterator p, size_type n)
{
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
}
@@ -58,22 +64,22 @@ struct move_insert_range_proxy
};
template<class A, class FwdIt, class Iterator>
template<class Allocator, class FwdIt, class Iterator>
struct insert_range_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<Allocator>::value_type value_type;
explicit insert_range_proxy(FwdIt first)
: first_(first)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
{
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
}
void copy_n_and_update(A &, Iterator p, size_type n)
void copy_n_and_update(Allocator &, Iterator p, size_type n)
{
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
}
@@ -82,20 +88,20 @@ struct insert_range_proxy
};
template<class A, class Iterator>
template<class Allocator, class Iterator>
struct insert_n_copies_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<Allocator>::value_type value_type;
explicit insert_n_copies_proxy(const value_type &v)
: v_(v)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
{ boost::container::uninitialized_fill_alloc_n(a, v_, n, p); }
void copy_n_and_update(A &, Iterator p, size_type n) const
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
for (; 0 < n; --n, ++p){
*p = v_;
@@ -105,38 +111,38 @@ struct insert_n_copies_proxy
const value_type &v_;
};
template<class A, class Iterator>
template<class Allocator, class Iterator>
struct insert_value_initialized_n_proxy
{
typedef ::boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<Allocator>::value_type value_type;
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
{ boost::container::uninitialized_value_init_alloc_n(a, n, p); }
void copy_n_and_update(A &, Iterator, size_type) const
void copy_n_and_update(Allocator &, Iterator, size_type) const
{ BOOST_ASSERT(false); }
};
template<class A, class Iterator>
template<class Allocator, class Iterator>
struct insert_default_initialized_n_proxy
{
typedef ::boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<Allocator>::value_type value_type;
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
{ boost::container::uninitialized_default_init_alloc_n(a, n, p); }
void copy_n_and_update(A &, Iterator, size_type) const
void copy_n_and_update(Allocator &, Iterator, size_type) const
{ BOOST_ASSERT(false); }
};
template<class A, class Iterator>
template<class Allocator, class Iterator>
struct insert_copy_proxy
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
@@ -144,13 +150,13 @@ struct insert_copy_proxy
: v_(v)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
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_);
}
void copy_n_and_update(A &, Iterator p, size_type n) const
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p =v_;
@@ -160,10 +166,10 @@ struct insert_copy_proxy
};
template<class A, class Iterator>
template<class Allocator, class Iterator>
struct insert_move_proxy
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
@@ -171,13 +177,13 @@ struct insert_move_proxy
: v_(v)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
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_) );
}
void copy_n_and_update(A &, Iterator p, size_type n) const
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p = ::boost::move(v_);
@@ -186,50 +192,48 @@ struct insert_move_proxy
value_type &v_;
};
template<class It, class A>
insert_move_proxy<A, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
template<class It, class Allocator>
insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
{
return insert_move_proxy<A, It>(v);
return insert_move_proxy<Allocator, It>(v);
}
template<class It, class A>
insert_copy_proxy<A, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
template<class It, class Allocator>
insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
{
return insert_copy_proxy<A, It>(v);
return insert_copy_proxy<Allocator, It>(v);
}
}}} //namespace boost { namespace container { namespace container_detail {
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/variadic_templates_tools.hpp>
#include <boost/move/utility_core.hpp>
#include <typeinfo>
//#include <iostream> //For debugging purposes
namespace boost {
namespace container {
namespace container_detail {
template<class A, class Iterator, class ...Args>
struct insert_non_movable_emplace_proxy
template<class Allocator, class Iterator, class ...Args>
struct insert_nonmovable_emplace_proxy
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
explicit insert_non_movable_emplace_proxy(Args&&... args)
explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
: args_(args...)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
private:
template<int ...IdxPack>
void priv_uninitialized_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
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_))... );
@@ -239,30 +243,30 @@ struct insert_non_movable_emplace_proxy
tuple<Args&...> args_;
};
template<class A, class Iterator, class ...Args>
template<class Allocator, class Iterator, class ...Args>
struct insert_emplace_proxy
: public insert_non_movable_emplace_proxy<A, Iterator, Args...>
: public insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...>
{
typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
typedef boost::container::allocator_traits<A> alloc_traits;
typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t;
typedef boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename base_t::value_type value_type;
typedef typename base_t::size_type size_type;
typedef typename base_t::index_tuple_t index_tuple_t;
explicit insert_emplace_proxy(Args&&... args)
explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
: base_t(::boost::forward<Args>(args)...)
{}
void copy_n_and_update(A &a, Iterator p, size_type n)
void copy_n_and_update(Allocator &a, Iterator p, size_type n)
{ this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
private:
template<int ...IdxPack>
void priv_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
{
BOOST_ASSERT(n ==1); (void)n;
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
alloc_traits::construct(a, vp,
::boost::forward<Args>(get<IdxPack>(this->args_))...);
@@ -279,191 +283,182 @@ struct insert_emplace_proxy
};
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type>
: public insert_move_proxy<A, Iterator>
template<class Allocator, class Iterator>
struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
: public insert_move_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy(typename boost::container::allocator_traits<A>::value_type &&v)
: insert_move_proxy<A, Iterator>(v)
explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
: insert_move_proxy<Allocator, Iterator>(v)
{}
};
//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
//compiler error C2752 (<28>more than one partial specialization matches<65>).
//Any problem is solvable with an extra layer of indirection? ;-)
template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type
template<class Allocator, class Iterator>
struct insert_emplace_proxy<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
>
: public insert_copy_proxy<A, Iterator>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type &>
: public insert_copy_proxy<A, Iterator>
template<class Allocator, class Iterator>
struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
template<class A, class Iterator>
struct insert_emplace_proxy<A, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type &
template<class Allocator, class Iterator>
struct insert_emplace_proxy<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
>
: public insert_copy_proxy<A, Iterator>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
}}} //namespace boost { namespace container { namespace container_detail {
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/value_init.hpp>
namespace boost {
namespace container {
namespace container_detail {
#define BOOST_PP_LOCAL_MACRO(N) \
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
{ \
typedef boost::container::allocator_traits<A> alloc_traits; \
typedef typename alloc_traits::size_type size_type; \
typedef typename alloc_traits::value_type value_type; \
\
explicit BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
BOOST_PP_EXPR_IF(N, :) BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \
{} \
\
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) \
{ \
BOOST_ASSERT(n == 1); (void)n; \
alloc_traits::construct \
( a, iterator_to_raw_pointer(p) \
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
} \
\
void copy_n_and_update(A &, Iterator, size_type) \
{ BOOST_ASSERT(false); } \
\
protected: \
BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
\
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
: BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
< A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \
{ \
typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \
typedef typename base_t::value_type value_type; \
typedef typename base_t::size_type size_type; \
typedef boost::container::allocator_traits<A> alloc_traits; \
\
explicit BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
: base_t(BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
{} \
\
void copy_n_and_update(A &a, Iterator p, size_type n) \
{ \
BOOST_ASSERT(n == 1); (void)n; \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
alloc_traits::construct(a, vp \
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
BOOST_TRY{ \
*p = ::boost::move(*vp); \
} \
BOOST_CATCH(...){ \
alloc_traits::destroy(a, vp); \
BOOST_RETHROW \
} \
BOOST_CATCH_END \
alloc_traits::destroy(a, vp); \
} \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
struct insert_nonmovable_emplace_proxy##N\
{\
typedef boost::container::allocator_traits<Allocator> alloc_traits;\
typedef typename alloc_traits::size_type size_type;\
typedef typename alloc_traits::value_type value_type;\
\
explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##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);\
}\
\
void copy_n_and_update(Allocator &, Iterator, size_type)\
{ BOOST_ASSERT(false); }\
\
protected:\
BOOST_MOVE_MREF##N\
};\
\
template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
struct insert_emplace_proxy_arg##N\
: insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
{\
typedef insert_nonmovable_emplace_proxy##N\
< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
typedef typename base_t::value_type value_type;\
typedef typename base_t::size_type size_type;\
typedef boost::container::allocator_traits<Allocator> alloc_traits;\
\
explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
: base_t(BOOST_MOVE_FWD##N){}\
\
void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
{\
BOOST_ASSERT(n == 1); (void)n;\
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));\
alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
BOOST_TRY{\
*p = ::boost::move(*vp);\
}\
BOOST_CATCH(...){\
alloc_traits::destroy(a, vp);\
BOOST_RETHROW\
}\
BOOST_CATCH_END\
alloc_traits::destroy(a, vp);\
}\
};\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, ::boost::rv<typename boost::container::allocator_traits<A>::value_type> >
: public insert_move_proxy<A, Iterator>
template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
: public insert_move_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<A>::value_type &v)
: insert_move_proxy<A, Iterator>(v)
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_move_proxy<Allocator, Iterator>(v)
{}
};
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type>
: public insert_copy_proxy<A, Iterator>
template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
#else //e.g. MSVC10 & MSVC11
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type>
: public insert_move_proxy<A, Iterator>
template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
: public insert_move_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<A>::value_type &&v)
: insert_move_proxy<A, Iterator>(v)
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
: insert_move_proxy<Allocator, Iterator>(v)
{}
};
//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
//compiler error C2752 (<28>more than one partial specialization matches<65>).
//Any problem is solvable with an extra layer of indirection? ;-)
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type
template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
>
: public insert_copy_proxy<A, Iterator>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type &>
: public insert_copy_proxy<A, Iterator>
template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
template<class A, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type &
template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
>
: public insert_copy_proxy<A, Iterator>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
: insert_copy_proxy<A, Iterator>(v)
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -471,7 +466,7 @@ struct insert_emplace_proxy_arg1<A, Iterator
}}} //namespace boost { namespace container { namespace container_detail {
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,56 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_ALLOC_TRAITS_HPP
#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
#if defined(_MSC_VER)
# pragma once
#endif
// move
#include <boost/move/adl_move_swap.hpp>
#include <boost/move/utility_core.hpp>
namespace boost {
namespace container {
namespace container_detail {
template<class AllocatorType>
inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
{ boost::adl_move_swap(l, r); }
template<class AllocatorType>
inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type)
{ l = r; }
template<class AllocatorType>
inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
{ l = ::boost::move(r); }
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP

View File

@@ -36,7 +36,7 @@ enum allocation_type_v
try_shrink_in_place_v = 0x40
};
typedef int allocation_type;
typedef unsigned int allocation_type;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
static const allocation_type allocate_new = (allocation_type)allocate_new_v;
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;

View File

@@ -25,56 +25,50 @@
#include <boost/container/detail/allocation_type.hpp> //allocation_type
#include <boost/container/detail/mpl.hpp> //integral_constant
#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
#include <utility> //pair
#include <boost/core/no_exceptions_support.hpp> //BOOST_TRY
namespace boost {
namespace container {
namespace container_detail {
template<class A, unsigned Version = boost::container::container_detail::version<A>::value>
template<class Allocator, unsigned Version = boost::container::container_detail::version<Allocator>::value>
struct allocator_version_traits
{
typedef ::boost::container::container_detail::integral_constant
<unsigned, Version> alloc_version;
typedef typename A::multiallocation_chain multiallocation_chain;
typedef typename Allocator::multiallocation_chain multiallocation_chain;
typedef typename boost::container::allocator_traits<A>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::size_type size_type;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
//Node allocation interface
static pointer allocate_one(A &a)
static pointer allocate_one(Allocator &a)
{ return a.allocate_one(); }
static void deallocate_one(A &a, const pointer &p)
static void deallocate_one(Allocator &a, const pointer &p)
{ a.deallocate_one(p); }
static void allocate_individual(A &a, size_type n, multiallocation_chain &m)
static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
{ return a.allocate_individual(n, m); }
static void deallocate_individual(A &a, multiallocation_chain &holder)
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{ a.deallocate_individual(holder); }
static std::pair<pointer, bool>
allocation_command(A &a, allocation_type command,
size_type limit_size, size_type preferred_size,
size_type &received_size, const pointer &reuse)
{
return a.allocation_command
(command, limit_size, preferred_size, received_size, reuse);
}
static pointer allocation_command(Allocator &a, allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{ return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
};
template<class A>
struct allocator_version_traits<A, 1>
template<class Allocator>
struct allocator_version_traits<Allocator, 1>
{
typedef ::boost::container::container_detail::integral_constant
<unsigned, 1> alloc_version;
typedef typename boost::container::allocator_traits<A>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::value_type value_type;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
typedef typename boost::intrusive::pointer_traits<pointer>::
template rebind_pointer<void>::type void_ptr;
@@ -85,13 +79,13 @@ struct allocator_version_traits<A, 1>
< multialloc_cached_counted, value_type> multiallocation_chain;
//Node allocation interface
static pointer allocate_one(A &a)
static pointer allocate_one(Allocator &a)
{ return a.allocate(1); }
static void deallocate_one(A &a, const pointer &p)
static void deallocate_one(Allocator &a, const pointer &p)
{ a.deallocate(p, 1); }
static void deallocate_individual(A &a, multiallocation_chain &holder)
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{
size_type n = holder.size();
typename multiallocation_chain::iterator it = holder.begin();
@@ -104,7 +98,7 @@ struct allocator_version_traits<A, 1>
struct allocate_individual_rollback
{
allocate_individual_rollback(A &a, multiallocation_chain &chain)
allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
: mr_a(a), mp_chain(&chain)
{}
@@ -119,11 +113,11 @@ struct allocator_version_traits<A, 1>
mp_chain = 0;
}
A &mr_a;
Allocator &mr_a;
multiallocation_chain * mp_chain;
};
static void allocate_individual(A &a, size_type n, multiallocation_chain &m)
static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
{
allocate_individual_rollback rollback(a, m);
while(n--){
@@ -132,21 +126,16 @@ struct allocator_version_traits<A, 1>
rollback.release();
}
static std::pair<pointer, bool>
allocation_command(A &a, allocation_type command,
size_type, size_type preferred_size,
size_type &received_size, const pointer &)
static pointer allocation_command(Allocator &a, allocation_type command,
size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
std::pair<pointer, bool> ret(pointer(), false);
if(!(command & allocate_new)){
if(!(command & nothrow_allocation)){
throw_logic_error("version 1 allocator without allocate_new flag");
}
pointer ret = pointer();
if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
throw_logic_error("version 1 allocator without allocate_new flag");
}
else{
received_size = preferred_size;
BOOST_TRY{
ret.first = a.allocate(received_size);
ret = a.allocate(prefer_in_recvd_out_size);
}
BOOST_CATCH(...){
if(!(command & nothrow_allocation)){
@@ -154,6 +143,7 @@ struct allocator_version_traits<A, 1>
}
}
BOOST_CATCH_END
reuse = pointer();
}
return ret;
}

View File

@@ -18,10 +18,10 @@
namespace boost {
namespace container {
template<class A>
template<class Allocator>
class equal_to_value
{
typedef typename A::value_type value_type;
typedef typename Allocator::value_type value_type;
const value_type &t_;
public:

View File

@@ -17,32 +17,33 @@
#ifdef BOOST_MSVC
#pragma warning (push)
#pragma warning (disable : 4702) // unreachable code
#pragma warning (disable : 4706) // assignment within conditional expression
#pragma warning (disable : 4127) // conditional expression is constant
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
#pragma warning (disable : 4284) // odd return type for operator->
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
#pragma warning (disable : 4244) // possible loss of data
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
#pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
#pragma warning (disable : 4284) // odd return type for operator->
#pragma warning (disable : 4324) // structure was padded due to __declspec(align())
#pragma warning (disable : 4355) // "this" : used in base member initializer list
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
#pragma warning (disable : 4510) // default constructor could not be generated
#pragma warning (disable : 4511) // copy constructor could not be generated
#pragma warning (disable : 4512) // assignment operator could not be generated
#pragma warning (disable : 4514) // unreferenced inline removed
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
#pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result
#pragma warning (disable : 4584) // X is already a base-class of Y
#pragma warning (disable : 4610) // struct can never be instantiated - user defined constructor required
#pragma warning (disable : 4671) // the copy constructor is inaccessible
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
#pragma warning (disable : 4702) // unreachable code
#pragma warning (disable : 4706) // assignment within conditional expression
#pragma warning (disable : 4710) // function not inlined
#pragma warning (disable : 4711) // function selected for automatic inline expansion
#pragma warning (disable : 4786) // identifier truncated in debug info
#pragma warning (disable : 4996) // "function": was declared deprecated
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
#pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
// with /GR-; unpredictable behavior may result
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible
#pragma warning (disable : 4584) // X is already a base-class of Y
#pragma warning (disable : 4510) // default constructor could not be generated
#endif //BOOST_MSVC

View File

@@ -23,30 +23,30 @@
namespace boost {
namespace container {
template<class A, class T, class InpIt>
inline void construct_in_place(A &a, T* dest, InpIt source)
{ boost::container::allocator_traits<A>::construct(a, dest, *source); }
template<class Allocator, class T, class InpIt>
inline void construct_in_place(Allocator &a, T* dest, InpIt source)
{ boost::container::allocator_traits<Allocator>::construct(a, dest, *source); }
template<class A, class T, class U, class D>
inline void construct_in_place(A &a, T *dest, value_init_construct_iterator<U, D>)
template<class Allocator, class T, class U, class D>
inline void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
{
boost::container::allocator_traits<A>::construct(a, dest);
boost::container::allocator_traits<Allocator>::construct(a, dest);
}
template <class T, class Difference>
class default_init_construct_iterator;
template<class A, class T, class U, class D>
inline void construct_in_place(A &a, T *dest, default_init_construct_iterator<U, D>)
template<class Allocator, class T, class U, class D>
inline void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
{
boost::container::allocator_traits<A>::construct(a, dest, default_init);
boost::container::allocator_traits<Allocator>::construct(a, dest, default_init);
}
template <class T, class EmplaceFunctor, class Difference>
class emplace_iterator;
template<class A, class T, class U, class EF, class D>
inline void construct_in_place(A &a, T *dest, emplace_iterator<U, EF, D> ei)
template<class Allocator, class T, class U, class EF, class D>
inline void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
{
ei.construct_in_place(a, dest);
}

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
@@ -15,167 +14,26 @@
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <cstdio>
#include <cstring> //for ::memmove / ::memcpy
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
// container
#include <boost/container/allocator_traits.hpp>
// container/detail
#include <boost/container/detail/iterator.hpp>
#include <boost/type_traits/is_pod.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
#include <boost/assert.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/to_raw_pointer.hpp>
#include <boost/aligned_storage.hpp>
// move
#include <boost/move/adl_move_swap.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/utility_core.hpp>
// other
#include <boost/core/no_exceptions_support.hpp>
// std
#include <cstring> //for emmove/memcpy
namespace boost {
namespace container {
//////////////////////////////////////////////////////////////////////////////
//
// swap
//
//////////////////////////////////////////////////////////////////////////////
namespace container_detail {
template <typename T>
inline T* addressof(T& obj)
{
return static_cast<T*>(
static_cast<void*>(
const_cast<char*>(
&reinterpret_cast<const char&>(obj)
)));
}
template<class T>
const T &max_value(const T &a, const T &b)
{ return a > b ? a : b; }
template<class T>
const T &min_value(const T &a, const T &b)
{ return a < b ? a : b; }
enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
template<class SizeType, NextCapacityOption Option>
struct next_capacity_calculator;
template<class SizeType>
struct next_capacity_calculator<SizeType, NextCapacityDouble>
{
static SizeType get(const SizeType max_size
,const SizeType capacity
,const SizeType n)
{
const SizeType remaining = max_size - capacity;
if ( remaining < n )
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
const SizeType additional = max_value(n, capacity);
return ( remaining < additional ) ? max_size : ( capacity + additional );
}
};
template<class SizeType>
struct next_capacity_calculator<SizeType, NextCapacity60Percent>
{
static SizeType get(const SizeType max_size
,const SizeType capacity
,const SizeType n)
{
const SizeType remaining = max_size - capacity;
if ( remaining < n )
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
const SizeType m3 = max_size/3;
if (capacity < m3)
return capacity + max_value(3*(capacity+1)/5, n);
if (capacity < m3*2)
return capacity + max_value((capacity+1)/2, n);
return max_size;
}
};
using ::boost::intrusive::detail::to_raw_pointer;
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>
inline
typename boost::intrusive::pointer_traits
<typename boost::container::iterator_traits<Iterator>::pointer>::element_type*
iterator_to_raw_pointer(const Iterator &i)
{ return (to_raw_pointer)((iterator_to_pointer)(i)); }
template<class AllocatorType>
inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
{ boost::adl_move_swap(l, r); }
template<class AllocatorType>
inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type)
{ l = r; }
template<class AllocatorType>
inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
{ l = ::boost::move(r); }
//Rounds "orig_size" by excess to round_to bytes
template<class SizeType>
inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
{
return ((orig_size-1)/round_to+1)*round_to;
}
template <std::size_t OrigSize, std::size_t RoundTo>
struct ct_rounded_size
{
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
};
template<class I>
struct are_elements_contiguous
{
@@ -266,34 +124,34 @@ template <typename I, typename O>
struct is_memtransfer_copy_assignable
{
static const bool value = are_contiguous_and_same<I, O>::value &&
boost::has_trivial_assign< typename ::boost::container::iterator_traits<I>::value_type >::value;
container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >::value;
};
template <typename I, typename O>
struct is_memtransfer_copy_constructible
{
static const bool value = are_contiguous_and_same<I, O>::value &&
boost::has_trivial_copy< typename ::boost::container::iterator_traits<I>::value_type >::value;
container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >::value;
};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_constructible
: public enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
: enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_constructible
: public enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
: enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
{};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_assignable
: public enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
: enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_assignable
: public enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
: enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
{};
template
@@ -347,32 +205,45 @@ struct is_memzero_initializable
{
typedef typename ::boost::container::iterator_traits<O>::value_type value_type;
static const bool value = are_elements_contiguous<O>::value &&
( ::boost::is_integral<value_type>::value || ::boost::is_enum<value_type>::value
( container_detail::is_integral<value_type>::value || container_detail::is_enum<value_type>::value
#if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
|| ::boost::is_pointer<value_type>::value
|| container_detail::is_pointer<value_type>::value
#endif
#if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO)
|| ::boost::is_floating_point<value_type>::value
|| container_detail::is_floating_point<value_type>::value
#endif
#if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
|| ::boost::is_pod<value_type>::value
|| container_detail::is_pod<value_type>::value
#endif
);
};
template <typename O, typename R>
struct enable_if_memzero_initializable
: public enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
: enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
{};
template <typename O, typename R>
struct disable_if_memzero_initializable
: public enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
: enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
{};
template <typename I, typename R>
struct enable_if_trivially_destructible
: enable_if_c < false/*container_detail::is_trivially_destructible
<typename boost::container::iterator_traits<I>::value_type>::value*/
, R>
{};
template <typename I, typename R>
struct disable_if_trivially_destructible
: enable_if_c <true/*!container_detail::is_trivially_destructible
<typename boost::container::iterator_traits<I>::value_type>::value*/
, R>
{};
} //namespace container_detail {
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_move_alloc
@@ -388,22 +259,22 @@ struct disable_if_memzero_initializable
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_move_alloc(A &a, I f, I l, F r)
uninitialized_move_alloc(Allocator &a, I f, I l, F r)
{
F back = r;
BOOST_TRY{
while (f != l) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -412,11 +283,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_move_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove(f, l, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -433,22 +304,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_move_alloc_n(A &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -457,11 +328,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_move_alloc_n(A &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -478,22 +349,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: f (after incremented)
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
uninitialized_move_alloc_n_source(A &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -502,11 +373,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
uninitialized_move_alloc_n_source(A &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n_source(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -523,22 +394,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_copy_alloc(A &a, I f, I l, F r)
uninitialized_copy_alloc(Allocator &a, I f, I l, F r)
{
F back = r;
BOOST_TRY{
while (f != l) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -547,11 +418,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_copy_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove(f, l, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -568,22 +439,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_copy_alloc_n(A &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -592,11 +463,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_copy_alloc_n(A &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -613,22 +484,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: f (after incremented)
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
uninitialized_copy_alloc_n_source(A &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -637,11 +508,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
<typename A,
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
uninitialized_copy_alloc_n_source(A &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n_source(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -658,21 +529,21 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memzero_initializable<F, F>::type
uninitialized_value_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
uninitialized_value_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r));
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r));
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -681,10 +552,10 @@ inline typename container_detail::disable_if_memzero_initializable<F, F>::type
}
template
<typename A,
<typename Allocator,
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memzero_initializable<F, F>::type
uninitialized_value_init_alloc_n(A &, typename allocator_traits<A>::difference_type n, F r)
uninitialized_value_init_alloc_n(Allocator &, typename allocator_traits<Allocator>::difference_type n, F r)
{
typedef typename boost::container::iterator_traits<F>::value_type value_type;
::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
@@ -706,20 +577,20 @@ inline typename container_detail::enable_if_memzero_initializable<F, F>::type
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename F> // F models ForwardIterator
inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
inline F uninitialized_default_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -741,21 +612,21 @@ inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename F, // F models ForwardIterator
typename T>
inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t)
{
F back = f;
BOOST_TRY{
while (f != l) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
++f;
}
}
BOOST_CATCH(...){
for (; back != l; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -777,21 +648,21 @@ inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
//!
//! <b>Returns</b>: r
template
<typename A,
<typename Allocator,
typename T,
typename F> // F models ForwardIterator
inline F uninitialized_fill_alloc_n(A &a, const T &v, typename allocator_traits<A>::difference_type n, F r)
inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename allocator_traits<Allocator>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -955,31 +826,38 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>
move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
//
// move_n_source
// move_backward
//
//////////////////////////////////////////////////////////////////////////////
template
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
<typename I, // I models BidirectionalIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
move_backward(I f, I l, F r)
{
while (n--) {
*r = ::boost::move(*f);
++f; ++r;
while (f != l) {
--l; --r;
*r = ::boost::move(*l);
}
return f;
return r;
}
template
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n_source(f, n, r); }
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
move_backward(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
{
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;
::memmove((container_detail::iterator_to_raw_pointer)(r), (container_detail::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
return r;
}
//////////////////////////////////////////////////////////////////////////////
//
@@ -1009,28 +887,55 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>
//////////////////////////////////////////////////////////////////////////////
//
// destroy_n
// move_n_source
//
//////////////////////////////////////////////////////////////////////////////
template
<typename A
,typename I> // I models InputIterator
inline void destroy_alloc_n(A &a, I f, typename boost::container::iterator_traits<I>::difference_type n
,typename boost::container::container_detail::enable_if_c
< !boost::has_trivial_destructor<typename boost::container::iterator_traits<I>::value_type>::value >::type* = 0)
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
while (n--) {
*r = ::boost::move(*f);
++f; ++r;
}
return f;
}
template
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n_source(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
//
// destroy_alloc_n
//
//////////////////////////////////////////////////////////////////////////////
template
<typename Allocator
,typename I // I models InputIterator
,typename U> // U models unsigned integral constant
inline typename container_detail::disable_if_trivially_destructible<I, void>::type
destroy_alloc_n(Allocator &a, I f, U n)
{
while(n--){
allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(f++));
allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(f));
++f;
}
}
template
<typename A
,typename I> // I models InputIterator
inline void destroy_alloc_n(A &, I, typename boost::container::iterator_traits<I>::difference_type
,typename boost::container::container_detail::enable_if_c
< boost::has_trivial_destructor<typename boost::container::iterator_traits<I>::value_type>::value >::type* = 0)
<typename Allocator
,typename I // I models InputIterator
,typename U> // U models unsigned integral constant
inline typename container_detail::enable_if_trivially_destructible<I, void>::type
destroy_alloc_n(Allocator &, I, U)
{}
//////////////////////////////////////////////////////////////////////////////
@@ -1041,15 +946,15 @@ inline void destroy_alloc_n(A &, I, typename boost::container::iterator_traits<I
template
<std::size_t MaxTmpBytes
,typename A
,typename Allocator
,typename F // F models ForwardIterator
,typename G // G models ForwardIterator
>
inline typename container_detail::disable_if_memtransfer_copy_assignable<F, G, void>::type
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
, G large_range_f, typename allocator_traits<A>::size_type n_j)
deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
, G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{
typename allocator_traits<A>::size_type n = 0;
typename allocator_traits<Allocator>::size_type n = 0;
for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){
boost::adl_move_swap(*short_range_f, *large_range_f);
}
@@ -1061,18 +966,18 @@ static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_
template
<std::size_t MaxTmpBytes
,typename A
,typename Allocator
,typename F // F models ForwardIterator
,typename G // G models ForwardIterator
>
inline typename container_detail::enable_if_c
< container_detail::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
, void>::type
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
, G large_range_f, typename allocator_traits<A>::size_type n_j)
deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
, G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{
typedef typename allocator_traits<A>::value_type value_type;
typedef typename boost::aligned_storage
typedef typename allocator_traits<Allocator>::value_type value_type;
typedef typename container_detail::aligned_storage
<MaxTmpBytes, container_detail::alignment_of<value_type>::value>::type storage_type;
storage_type storage;
@@ -1091,18 +996,18 @@ inline typename container_detail::enable_if_c
template
<std::size_t MaxTmpBytes
,typename A
,typename Allocator
,typename F // F models ForwardIterator
,typename G // G models ForwardIterator
>
inline typename container_detail::enable_if_c
< container_detail::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
, void>::type
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
, G large_range_f, typename allocator_traits<A>::size_type n_j)
deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
, G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{
typedef typename allocator_traits<A>::value_type value_type;
typedef typename boost::aligned_storage
typedef typename allocator_traits<Allocator>::value_type value_type;
typedef typename container_detail::aligned_storage
<DeepSwapAllocNMaxStorage, container_detail::alignment_of<value_type>::value>::type storage_type;
storage_type storage;
const std::size_t sizeof_storage = sizeof(storage);
@@ -1168,12 +1073,12 @@ inline typename container_detail::enable_if_c
//////////////////////////////////////////////////////////////////////////////
template
<typename A
<typename Allocator
,typename I // F models InputIterator
,typename O // G models OutputIterator
>
void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i
, O out_start, typename allocator_traits<A>::size_type n_o )
void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
, O out_start, typename allocator_traits<Allocator>::size_type n_o )
{
if (n_o < n_i){
inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw
@@ -1192,12 +1097,12 @@ void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>:
//////////////////////////////////////////////////////////////////////////////
template
<typename A
<typename Allocator
,typename I // F models InputIterator
,typename O // G models OutputIterator
>
void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i
, O out_start, typename allocator_traits<A>::size_type n_o )
void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
, O out_start, typename allocator_traits<Allocator>::size_type n_o )
{
if (n_o < n_i){
inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw
@@ -1212,6 +1117,4 @@ void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>:
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP

View File

@@ -20,9 +20,9 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/version_type.hpp>
namespace boost {
namespace container {
@@ -30,22 +30,20 @@ namespace container_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
template <class A>
template <class Allocator>
struct scoped_deallocator
{
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<A>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
version<Allocator>::value> alloc_version;
private:
void priv_deallocate(allocator_v1)
void priv_deallocate(version_1)
{ m_alloc.deallocate(m_ptr, 1); }
void priv_deallocate(allocator_v2)
void priv_deallocate(version_2)
{ m_alloc.deallocate_one(m_ptr); }
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
@@ -53,9 +51,9 @@ struct scoped_deallocator
public:
pointer m_ptr;
A& m_alloc;
Allocator& m_alloc;
scoped_deallocator(pointer p, A& a)
scoped_deallocator(pointer p, Allocator& a)
: m_ptr(p), m_alloc(a)
{}
@@ -76,14 +74,14 @@ struct scoped_deallocator
{ m_ptr = 0; }
};
template <class A>
template <class Allocator>
struct null_scoped_deallocator
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
null_scoped_deallocator(pointer, A&, size_type)
null_scoped_deallocator(pointer, Allocator&, size_type)
{}
void release()
@@ -98,14 +96,14 @@ struct null_scoped_deallocator
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an array of objects using a STL allocator.
template <class A>
template <class Allocator>
struct scoped_array_deallocator
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
scoped_array_deallocator(pointer p, A& a, size_type length)
scoped_array_deallocator(pointer p, Allocator& a, size_type length)
: m_ptr(p), m_alloc(a), m_length(length) {}
~scoped_array_deallocator()
@@ -116,37 +114,35 @@ struct scoped_array_deallocator
private:
pointer m_ptr;
A& m_alloc;
Allocator& m_alloc;
size_type m_length;
};
template <class A>
template <class Allocator>
struct null_scoped_array_deallocator
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
null_scoped_array_deallocator(pointer, A&, size_type)
null_scoped_array_deallocator(pointer, Allocator&, size_type)
{}
void release()
{}
};
template <class A>
template <class Allocator>
struct scoped_destroy_deallocator
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<A>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
version<Allocator>::value> alloc_version;
scoped_destroy_deallocator(pointer p, A& a)
scoped_destroy_deallocator(pointer p, Allocator& a)
: m_ptr(p), m_alloc(a) {}
~scoped_destroy_deallocator()
@@ -162,28 +158,28 @@ struct scoped_destroy_deallocator
private:
void priv_deallocate(const pointer &p, allocator_v1)
void priv_deallocate(const pointer &p, version_1)
{ AllocTraits::deallocate(m_alloc, p, 1); }
void priv_deallocate(const pointer &p, allocator_v2)
void priv_deallocate(const pointer &p, version_2)
{ m_alloc.deallocate_one(p); }
pointer m_ptr;
A& m_alloc;
Allocator& m_alloc;
};
//!A deleter for scoped_ptr that destroys
//!an object using a STL allocator.
template <class A>
template <class Allocator>
struct scoped_destructor_n
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::value_type value_type;
typedef typename AllocTraits::size_type size_type;
scoped_destructor_n(pointer p, A& a, size_type n)
scoped_destructor_n(pointer p, Allocator& a, size_type n)
: m_p(p), m_a(a), m_n(n)
{}
@@ -210,20 +206,20 @@ struct scoped_destructor_n
private:
pointer m_p;
A & m_a;
Allocator & m_a;
size_type m_n;
};
//!A deleter for scoped_ptr that destroys
//!an object using a STL allocator.
template <class A>
template <class Allocator>
struct null_scoped_destructor_n
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
null_scoped_destructor_n(pointer, A&, size_type)
null_scoped_destructor_n(pointer, Allocator&, size_type)
{}
void increment_size(size_type)
@@ -239,13 +235,13 @@ struct null_scoped_destructor_n
{}
};
template<class A>
template<class Allocator>
class scoped_destructor
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
public:
typedef typename A::value_type value_type;
scoped_destructor(A &a, value_type *pv)
typedef typename Allocator::value_type value_type;
scoped_destructor(Allocator &a, value_type *pv)
: pv_(pv), a_(a)
{}
@@ -266,17 +262,17 @@ class scoped_destructor
private:
value_type *pv_;
A &a_;
Allocator &a_;
};
template<class A>
template<class Allocator>
class value_destructor
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
public:
typedef typename A::value_type value_type;
value_destructor(A &a, value_type &rv)
typedef typename Allocator::value_type value_type;
value_destructor(Allocator &a, value_type &rv)
: rv_(rv), a_(a)
{}
@@ -287,33 +283,31 @@ class value_destructor
private:
value_type &rv_;
A &a_;
Allocator &a_;
};
template <class A>
template <class Allocator>
class allocator_destroyer
{
typedef boost::container::allocator_traits<A> AllocTraits;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::value_type value_type;
typedef typename AllocTraits::pointer pointer;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<A>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
version<Allocator>::value> alloc_version;
private:
A & a_;
Allocator & a_;
private:
void priv_deallocate(const pointer &p, allocator_v1)
void priv_deallocate(const pointer &p, version_1)
{ AllocTraits::deallocate(a_,p, 1); }
void priv_deallocate(const pointer &p, allocator_v2)
void priv_deallocate(const pointer &p, version_2)
{ a_.deallocate_one(p); }
public:
allocator_destroyer(A &a)
allocator_destroyer(Allocator &a)
: a_(a)
{}
@@ -324,41 +318,41 @@ class allocator_destroyer
}
};
template <class A>
template <class Allocator>
class allocator_destroyer_and_chain_builder
{
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
typedef typename Allocator::multiallocation_chain multiallocation_chain;
A & a_;
Allocator & a_;
multiallocation_chain &c_;
public:
allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
: a_(a), c_(c)
{}
void operator()(const typename A::pointer &p)
void operator()(const typename Allocator::pointer &p)
{
allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
allocator_traits<Allocator>::destroy(a_, container_detail::to_raw_pointer(p));
c_.push_back(p);
}
};
template <class A>
template <class Allocator>
class allocator_multialloc_chain_node_deallocator
{
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
typedef typename Allocator::multiallocation_chain multiallocation_chain;
typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;
A & a_;
Allocator & a_;
multiallocation_chain c_;
public:
allocator_multialloc_chain_node_deallocator(A &a)
allocator_multialloc_chain_node_deallocator(Allocator &a)
: a_(a), c_()
{}

View File

@@ -20,10 +20,8 @@
#include <boost/container/container_fwd.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/detail/value_init.hpp>
@@ -34,11 +32,14 @@
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
#include <boost/intrusive/pointer_traits.hpp>
#endif
#include <boost/aligned_storage.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/make_unique.hpp>
#include <boost/move/adl_move_swap.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <utility> //std::pair
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
namespace boost {
namespace container {
@@ -94,11 +95,11 @@ struct get_flat_tree_iterators
};
template <class Key, class Value, class KeyOfValue,
class Compare, class A>
class Compare, class Allocator>
class flat_tree
{
typedef boost::container::vector<Value, A> vector_t;
typedef A allocator_t;
typedef boost::container::vector<Value, Allocator> vector_t;
typedef Allocator allocator_t;
public:
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
@@ -123,11 +124,11 @@ class flat_tree
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
{}
Data(const Data &d, const A &a)
Data(const Data &d, const Allocator &a)
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
{}
Data(BOOST_RV_REF(Data) d, const A &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)
{}
@@ -496,12 +497,12 @@ class flat_tree
)
{ this->priv_insert_ordered_range(true, first, last); }
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class... Args>
std::pair<iterator, bool> emplace_unique(Args&&... args)
std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
{
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -510,9 +511,9 @@ class flat_tree
}
template <class... Args>
iterator emplace_hint_unique(const_iterator hint, Args&&... args)
iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -521,9 +522,9 @@ class flat_tree
}
template <class... Args>
iterator emplace_equal(Args&&... args)
iterator emplace_equal(BOOST_FWD_REF(Args)... args)
{
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -532,9 +533,9 @@ class flat_tree
}
template <class... Args>
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -542,64 +543,57 @@ class flat_tree
return this->insert_equal(hint, ::boost::move(val));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
std::pair<iterator, bool> \
emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
value_destructor<stored_allocator_type> d(a, val); \
return this->insert_unique(::boost::move(val)); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_unique(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
value_destructor<stored_allocator_type> d(a, val); \
return this->insert_unique(hint, ::boost::move(val)); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
value_destructor<stored_allocator_type> d(a, val); \
return this->insert_equal(::boost::move(val)); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_equal(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
value_destructor<stored_allocator_type> d(a, val); \
return this->insert_equal(hint, ::boost::move(val)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\
{\
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
stored_allocator_type &a = this->get_stored_allocator();\
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
value_destructor<stored_allocator_type> d(a, val);\
return this->insert_unique(::boost::move(val));\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
stored_allocator_type &a = this->get_stored_allocator();\
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
value_destructor<stored_allocator_type> d(a, val);\
return this->insert_unique(hint, ::boost::move(val));\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_equal(BOOST_MOVE_UREF##N)\
{\
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
stored_allocator_type &a = this->get_stored_allocator();\
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
value_destructor<stored_allocator_type> d(a, val);\
return this->insert_equal(::boost::move(val));\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
typename aligned_storage <sizeof(value_type), alignment_of<value_type>::value>::type v;\
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
stored_allocator_type &a = this->get_stored_allocator();\
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
value_destructor<stored_allocator_type> d(a, val);\
return this->insert_equal(hint, ::boost::move(val));\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE)
#undef BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
iterator erase(const_iterator position)
{ return this->m_data.m_vect.erase(position); }
@@ -965,7 +959,7 @@ class flat_tree
for(; checked != burst; ++checked){
//Get the insertion position for each key, use iterator_traits<BidirIt>::value_type
//because it can be different from container::value_type
//(e.g. conversion between std::pair<A, B> -> boost::container::pair<A, B>
//(e.g. conversion between std::pair<T1, T2> -> boost::container::pair<T1, T2>
const typename boost::container::iterator_traits<BidirIt>::value_type & val = *first;
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
//Check if already present
@@ -1012,16 +1006,18 @@ class flat_tree
} //namespace container_detail {
} //namespace container {
/*
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class V, class KOV,
class C, class A>
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<K, V, KOV, C, A> >
template <class Key, class T, class KeyOfValue,
class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<Key, T, KeyOfValue, Compare, Allocator> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};
*/
} //namespace boost {
#include <boost/container/detail/config_end.hpp>

View File

@@ -1,6 +1,6 @@
/*
template <class Value, unsigned int Options = 0, class Hash = hash<Value>, class Pred = equal_to<Value>,
class Alloc = allocator<Value> >
class Allocator = allocator<Value> >
class hash_set
{
public:
@@ -9,7 +9,7 @@ public:
typedef key_type value_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Alloc allocator_type;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename allocator_traits<allocator_type>::pointer pointer;
@@ -37,13 +37,13 @@ public:
const allocator_type& a = allocator_type());
explicit hash_set(const allocator_type&);
hash_set(const hash_set&);
hash_set(const hash_set&, const A&);
hash_set(const hash_set&, const Allocator&);
hash_set(hash_set&&)
noexcept(
is_nothrow_move_constructible<hasher>::value &&
is_nothrow_move_constructible<key_equal>::value &&
is_nothrow_move_constructible<allocator_type>::value);
hash_set(hash_set&&, const A&);
hash_set(hash_set&&, const Allocator&);
hash_set(initializer_list<value_type>, size_type n = 0,
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
@@ -71,9 +71,9 @@ public:
const_iterator cend() const noexcept;
template <class... Args>
pair<iterator, bool> emplace(Args&&... args);
pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... Args>
iterator emplace_hint(const_iterator position, Args&&... args);
iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args);
pair<iterator, bool> insert(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const value_type& obj);
@@ -124,7 +124,7 @@ public:
};
template <class Key, class T, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
class Alloc = allocator<pair<const Key, T> > >
class Allocator = allocator<pair<const Key, T> > >
class hash_map
{
public:
@@ -133,7 +133,7 @@ public:
typedef T mapped_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Alloc allocator_type;
typedef Allocator allocator_type;
typedef pair<const key_type, mapped_type> value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
@@ -162,13 +162,13 @@ public:
const allocator_type& a = allocator_type());
explicit hash_map(const allocator_type&);
hash_map(const hash_map&);
hash_map(const hash_map&, const A&);
hash_map(const hash_map&, const Allocator&);
hash_map(hash_map&&)
noexcept(
is_nothrow_move_constructible<hasher>::value &&
is_nothrow_move_constructible<key_equal>::value &&
is_nothrow_move_constructible<allocator_type>::value);
hash_map(hash_map&&, const A&);
hash_map(hash_map&&, const Allocator&);
hash_map(initializer_list<value_type>, size_type n = 0,
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
@@ -196,9 +196,9 @@ public:
const_iterator cend() const noexcept;
template <class... Args>
pair<iterator, bool> emplace(Args&&... args);
pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... Args>
iterator emplace_hint(const_iterator position, Args&&... args);
iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args);
pair<iterator, bool> insert(const value_type& obj);
template <class P>
pair<iterator, bool> insert(P&& obj);
@@ -259,7 +259,7 @@ public:
*/
template <class Key, class Value, class KeyOfValue, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
class Alloc = allocator<Value> >
class Allocator = allocator<Value> >
class hash_table
{
public:
@@ -268,7 +268,7 @@ public:
typedef key_type value_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Alloc allocator_type;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename allocator_traits<allocator_type>::pointer pointer;
@@ -296,13 +296,13 @@ public:
const allocator_type& a = allocator_type());
explicit hash_set(const allocator_type&);
hash_set(const hash_set&);
hash_set(const hash_set&, const A&);
hash_set(const hash_set&, const Allocator&);
hash_set(hash_set&&)
noexcept(
is_nothrow_move_constructible<hasher>::value &&
is_nothrow_move_constructible<key_equal>::value &&
is_nothrow_move_constructible<allocator_type>::value);
hash_set(hash_set&&, const A&);
hash_set(hash_set&&, const Allocator&);
hash_set(initializer_list<value_type>, size_type n = 0,
const hasher& hf = hasher(), const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
@@ -330,9 +330,9 @@ public:
const_iterator cend() const noexcept;
template <class... Args>
pair<iterator, bool> emplace(Args&&... args);
pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... Args>
iterator emplace_hint(const_iterator position, Args&&... args);
iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args);
pair<iterator, bool> insert(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const value_type& obj);

View File

@@ -0,0 +1,54 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
#define BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/intrusive/pointer_traits.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) );
}
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP

View File

@@ -26,12 +26,11 @@
#include <boost/move/utility_core.hpp>
#include <boost/intrusive/detail/reverse_iterator.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#else
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/variadic_templates_tools.hpp>
#endif
#include <boost/container/detail/iterator.hpp>
namespace boost {
@@ -564,8 +563,8 @@ class emplace_iterator
//const T& operator[](difference_type) const;
//const T* operator->() const;
template<class A>
void construct_in_place(A &a, T* ptr)
template<class Allocator>
void construct_in_place(Allocator &a, T* ptr)
{ (*m_pe)(a, ptr); }
private:
@@ -597,54 +596,49 @@ class emplace_iterator
{ return difference_type(m_num - other.m_num); }
};
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class ...Args>
struct emplace_functor
{
typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
emplace_functor(Args&&... args)
emplace_functor(BOOST_FWD_REF(Args)... args)
: args_(args...)
{}
template<class A, class T>
void operator()(A &a, T *ptr)
template<class Allocator, class T>
void operator()(Allocator &a, T *ptr)
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
template<class A, class T, int ...IdxPack>
void inplace_impl(A &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
template<class Allocator, class T, int ...IdxPack>
void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
{
allocator_traits<A>::construct
allocator_traits<Allocator>::construct
(a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
}
container_detail::tuple<Args&...> args_;
};
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template <) \
BOOST_PP_ENUM_PARAMS(n, class P) \
BOOST_PP_EXPR_IF(n, >) \
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
{ \
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
\
template<class A, class T> \
void operator()(A &a, T *ptr) \
{ \
allocator_traits<A>::construct \
(a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
} \
BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
struct emplace_functor##N\
{\
explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
\
template<class Allocator, class T>\
void operator()(Allocator &a, T *ptr)\
{ allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
\
BOOST_MOVE_MREF##N\
};\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
#endif

View File

@@ -1,62 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-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_ALLOCATOR_MEMORY_UTIL_HPP
#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/preprocessor.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (2, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME max_size
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME select_on_container_copy_construction
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#ifdef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_SINGLE_ITERATION
# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#else
# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#endif
#include BOOST_PP_ITERATE()
#include <boost/container/detail/config_end.hpp>
#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP)

View File

@@ -0,0 +1,33 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_DETAIL_MIN_MAX_HPP
#define BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
#if defined(_MSC_VER)
# pragma once
#endif
namespace boost {
namespace container {
namespace container_detail {
template<class T>
const T &max_value(const T &a, const T &b)
{ return a > b ? a : b; }
template<class T>
const T &min_value(const T &a, const T &b)
{ return a < b ? a : b; }
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP

View File

@@ -169,6 +169,12 @@ struct ls_zeros<1>
static const std::size_t value = 0;
};
template <std::size_t OrigSize, std::size_t RoundTo>
struct ct_rounded_size
{
static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo;
};
template <typename T> struct unvoid { typedef T type; };
template <> struct unvoid<void> { struct type { }; };
template <> struct unvoid<const void> { struct type { }; };

View File

@@ -17,14 +17,16 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp>
// container/detail
#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/transform_iterator.hpp>
#include <boost/container/detail/type_traits.hpp>
// intrusive
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/type_traits/make_unsigned.hpp>
// move
#include <boost/move/utility_core.hpp>
namespace boost {
@@ -47,7 +49,7 @@ class basic_multiallocation_chain
typedef bi::slist< node
, bi::linear<true>
, bi::cache_last<true>
, bi::size_type<typename boost::make_unsigned<difference_type>::type>
, bi::size_type<typename boost::container::container_detail::make_unsigned<difference_type>::type>
> slist_impl_t;
slist_impl_t slist_impl_;

View File

@@ -162,7 +162,7 @@
#define BOOST_CONTAINER_TRY_LOCK(sl) !BOOST_CONTAINER_CAS_LOCK(sl)
#define BOOST_CONTAINER_RELEASE_LOCK(sl) BOOST_CONTAINER_CLEAR_LOCK(sl)
#define BOOST_CONTAINER_ACQUIRE_LOCK(sl) (BOOST_CONTAINER_CAS_LOCK(sl)? boost_interprocess_spin_acquire_lock(sl) : 0)
#define BOOST_CONTAINER_INITIAL_LOCK(sl) (*sl = 0)
#define BOOST_MOVE_INITIAL_LOCK(sl) (*sl = 0)
#define BOOST_CONTAINER_DESTROY_LOCK(sl) (0)
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
//
@@ -199,7 +199,7 @@ namespace container_detail {
void operator=(const spin_mutex &);
public:
spin_mutex() { BOOST_CONTAINER_INITIAL_LOCK(&sl); }
spin_mutex() { BOOST_MOVE_INITIAL_LOCK(&sl); }
void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); }
void unlock() { BOOST_CONTAINER_RELEASE_LOCK(&sl); }

View File

@@ -0,0 +1,71 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_NEXT_CAPACITY_HPP
#define BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
#if defined(_MSC_VER)
# pragma once
#endif
// container
#include <boost/container/throw_exception.hpp>
// container/detail
#include <boost/container/detail/min_max.hpp>
namespace boost {
namespace container {
namespace container_detail {
enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
template<class SizeType, NextCapacityOption Option>
struct next_capacity_calculator;
template<class SizeType>
struct next_capacity_calculator<SizeType, NextCapacityDouble>
{
static SizeType get(const SizeType max_size
,const SizeType capacity
,const SizeType n)
{
const SizeType remaining = max_size - capacity;
if ( remaining < n )
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
const SizeType additional = max_value(n, capacity);
return ( remaining < additional ) ? max_size : ( capacity + additional );
}
};
template<class SizeType>
struct next_capacity_calculator<SizeType, NextCapacity60Percent>
{
static SizeType get(const SizeType max_size
,const SizeType capacity
,const SizeType n)
{
const SizeType remaining = max_size - capacity;
if ( remaining < n )
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
const SizeType m3 = max_size/3;
if (capacity < m3)
return capacity + max_value(3*(capacity+1)/5, n);
if (capacity < m3*2)
return capacity + max_value((capacity+1)/2, n);
return max_size;
}
};
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP

View File

@@ -18,29 +18,30 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <utility>
#include <functional>
#include <boost/move/utility_core.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/utilities.hpp>
// container
#include <boost/container/allocator_traits.hpp>
// container/detail
#include <boost/container/detail/addressof.hpp>
#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/placement_new.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/core/no_exceptions_support.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
#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/container/detail/mpl.hpp>
#include <boost/container/detail/placement_new.hpp>
#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/version_type.hpp>
// intrusive
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/options.hpp>
// move
#include <boost/move/utility_core.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
// other
#include <boost/core/no_exceptions_support.hpp>
namespace boost {
@@ -50,7 +51,7 @@ namespace container_detail {
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
template<class A, class ICont>
template<class Allocator, class ICont>
struct node_alloc_holder
{
//If the intrusive container is an associative container, obtain the predicate, which will
@@ -62,7 +63,7 @@ struct node_alloc_holder
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
predicate_type, container_detail::nat) value_compare;
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef ICont intrusive_container;
typedef typename ICont::value_type Node;
@@ -70,13 +71,11 @@ struct node_alloc_holder
portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
typedef A ValAlloc;
typedef Allocator ValAlloc;
typedef typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
typedef typename node_allocator_traits_type::size_type size_type;
typedef typename node_allocator_traits_type::difference_type difference_type;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<NodeAlloc>::value> alloc_version;
@@ -152,7 +151,7 @@ struct node_alloc_holder
void deallocate_one(const NodePtr &p)
{ AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class ...Args>
NodePtr create_node(Args &&...args)
@@ -169,28 +168,90 @@ struct node_alloc_holder
return (p);
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
NodePtr create_node()
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::addressof(p->m_data));
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;
return (p);
}
#define BOOST_PP_LOCAL_MACRO(n) \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr p = this->allocate_one(); \
Deallocator node_deallocator(p, this->node_alloc()); \
allocator_traits<NodeAlloc>::construct \
(this->node_alloc(), container_detail::addressof(p->m_data) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
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; \
return (p); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
template<BOOST_MOVE_CLASS1>
NodePtr create_node(BOOST_MOVE_UREF1)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::addressof(p->m_data)
, BOOST_MOVE_FWD1);
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;
return (p);
}
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template<BOOST_MOVE_CLASS2>
NodePtr create_node(BOOST_MOVE_UREF2)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::addressof(p->m_data)
, BOOST_MOVE_FWD2);
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;
return (p);
}
template<BOOST_MOVE_CLASS3>
NodePtr create_node(BOOST_MOVE_UREF3)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::addressof(p->m_data)
, BOOST_MOVE_FWD3);
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;
return (p);
}
template<BOOST_MOVE_CLASS4>
NodePtr create_node(BOOST_MOVE_UREF4)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::addressof(p->m_data)
, BOOST_MOVE_FWD4);
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;
return (p);
}
template<BOOST_MOVE_CLASS5>
NodePtr create_node(BOOST_MOVE_UREF5)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::addressof(p->m_data)
, BOOST_MOVE_FWD5);
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;
return (p);
}
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class It>
NodePtr create_node_from_it(const It &it)
@@ -237,7 +298,7 @@ struct node_alloc_holder
Deallocator node_deallocator(NodePtr(), nalloc);
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
while(n--){
p = container_detail::to_raw_pointer(iterator_to_pointer(itbeg));
p = container_detail::iterator_to_raw_pointer(itbeg);
node_deallocator.set(p);
++itbeg;
//This can throw
@@ -264,10 +325,10 @@ struct node_alloc_holder
}
}
void clear(allocator_v1)
void clear(version_1)
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
void clear(allocator_v2)
void clear(version_2)
{
typename NodeAlloc::multiallocation_chain chain;
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
@@ -277,10 +338,10 @@ struct node_alloc_holder
this->node_alloc().deallocate_individual(chain);
}
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1)
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2)
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
{
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
NodeAlloc & nalloc = this->node_alloc();
@@ -292,11 +353,11 @@ struct node_alloc_holder
}
template<class Key, class Comparator>
size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
size_type erase_key(const Key& k, const Comparator &comp, version_1)
{ return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
template<class Key, class Comparator>
size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
size_type erase_key(const Key& k, const Comparator &comp, version_2)
{
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
@@ -17,16 +16,18 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/container/detail/type_traits.hpp>
#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/container/detail/type_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/assert.hpp>
#include <cstddef>
@@ -57,6 +58,10 @@ class private_node_pool_impl
< node_t, bi::base_hook<slist_hook_t>
, bi::linear<true>
, bi::constant_time_size<false> >::type blockslist_t;
static size_type get_rounded_size(size_type orig_size, size_type round_to)
{ return ((orig_size-1)/round_to+1)*round_to; }
public:
//!Segment manager typedef
@@ -145,7 +150,7 @@ class private_node_pool_impl
nodelist_iterator backup_list_last = backup_list.before_begin();
//Execute the algorithm and get an iterator to the last value
size_type blocksize = get_rounded_size
size_type blocksize = (get_rounded_size)
(m_real_node_size*m_nodes_per_block, (size_type) alignment_of<node_t>::value);
while(it != itend){
@@ -205,7 +210,7 @@ class private_node_pool_impl
{
//check for memory leaks
BOOST_ASSERT(m_allocated==0);
size_type blocksize = get_rounded_size
size_type blocksize = (get_rounded_size)
(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
//We iterate though the NodeBlock list to free the memory
@@ -298,7 +303,7 @@ class private_node_pool_impl
{
BOOST_ASSERT(num_blocks > 0);
size_type blocksize =
get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
(get_rounded_size)(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
BOOST_TRY{
for(size_type i = 0; i != num_blocks; ++i){

View File

@@ -26,16 +26,9 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/adl_move_swap.hpp> //swap
#include <utility> //std::pair
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/move/utility_core.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
namespace boost {
namespace container {
namespace container_detail {
@@ -167,37 +160,7 @@ struct pair
//template <class... Args1, class... Args2>
// pair(piecewise_construct_t, tuple<Args1...> first_args,
// tuple<Args2...> second_args);
/*
//Variadic versions
template<class U>
pair(BOOST_CONTAINER_PP_PARAM(U, u), typename container_detail::disable_if
< container_detail::is_pair< typename container_detail::remove_ref_const<U>::type >, pair_nat>::type* = 0)
: first(::boost::forward<U>(u))
, second()
{}
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template<class U, class V, class ...Args>
pair(U &&u, V &&v)
: first(::boost::forward<U>(u))
, second(::boost::forward<V>(v), ::boost::forward<Args>(args)...)
{}
#else
#define BOOST_PP_LOCAL_MACRO(n) \
template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
pair(BOOST_CONTAINER_PP_PARAM(U, u) \
,BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: first(::boost::forward<U>(u)) \
, second(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif
*/
//pair copy assignment
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
{

View File

@@ -1,228 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-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_DETAIL_PREPROCESSOR_HPP
#define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/utility_core.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//#error "This file is not needed when perfect forwarding is available"
#endif //BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/punctuation/paren_if.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#define BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS 10
//Note:
//We define template parameters as const references to
//be able to bind temporaries. After that we will un-const them.
//This cast is ugly but it is necessary until "perfect forwarding"
//is achieved in C++0x. Meanwhile, if we want to be able to
//bind rvalues with non-const references, we have to be ugly
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
//!
#else
#define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
//!
#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
//!
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM(U, u) \
U && u \
//!
#else
#define BOOST_CONTAINER_PP_PARAM(U, u) \
const U & u \
//!
#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
//!
#else //BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
//!
#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
namespace boost {
namespace container {
namespace container_detail {
template<class T>
struct ref_holder;
template<class T>
struct ref_holder<T &>
{
explicit ref_holder(T &t)
: t_(t)
{}
T &t_;
T & get() { return t_; }
};
template<class T>
struct ref_holder<const T>
{
explicit ref_holder(const T &t)
: t_(t)
{}
const T &t_;
const T & get() { return t_; }
};
template<class T>
struct ref_holder<const T &&>
{
explicit ref_holder(const T &t)
: t_(t)
{}
const T &t_;
const T & get() { return t_; }
};
template<class T>
struct ref_holder
{
explicit ref_holder(T &&t)
: t_(t)
{}
T &t_;
T && get() { return ::boost::move(t_); }
};
template<class T>
struct ref_holder<T &&>
{
explicit ref_holder(T &&t)
: t_(t)
{}
T &t_;
T && get() { return ::boost::move(t_); }
};
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
::boost::container::container_detail::ref_holder<BOOST_PP_CAT(P, n)> BOOST_PP_CAT(m_p, n); \
//!
#else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
//!
#endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#else //BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
//!
#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) BOOST_PP_CAT(this->m_p, n).get() \
//!
#else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
//!
#endif //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_PARAM_INC(z, n, data) \
BOOST_PP_CAT(++this->m_p, n) \
//!
#define BOOST_CONTAINER_PP_IDENTITY(z, n, data) data
#define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!
#define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
::boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
//!
#define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
BOOST_PP_CAT(*this->m_p, n) \
//!
#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
BOOST_PP_CAT(class P, n) = void \
//!
#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
BOOST_PP_CAT(class P, n) = default_type \
//!
#define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
static BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n); \
//!
#define BOOST_CONTAINER_PP_PARAM_PASS(z, n, data) \
BOOST_PP_CAT(p, n) \
//!
#define BOOST_CONTAINER_PP_FWD_TYPE(z, n, data) \
typename ::boost::move_detail::forward_type< BOOST_PP_CAT(P, n) >::type \
//!
#include <boost/container/detail/config_end.hpp>
//#else
//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//#error "This file is not needed when perfect forwarding is available"
//#endif //BOOST_CONTAINER_PERFECT_FORWARDING
#endif //#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP

View File

@@ -0,0 +1,29 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_TO_RAW_POINTER_HPP
#define BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/intrusive/detail/to_raw_pointer.hpp>
namespace boost {
namespace container {
namespace container_detail {
using ::boost::intrusive::detail::to_raw_pointer;
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP

View File

@@ -21,6 +21,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/iterator.hpp>
namespace boost {
namespace container {

View File

@@ -17,55 +17,56 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/options.hpp>
#include <boost/container/detail/utilities.hpp>
// container/detail
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#include <boost/container/detail/compare_functors.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#include <boost/container/allocator_traits.hpp>
#include <boost/container/options.hpp>
#include <boost/container/detail/compare_functors.hpp>
#include <boost/container/detail/iterator.hpp>
//
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/rbtree.hpp>
#include <boost/intrusive/avltree.hpp>
#include <boost/intrusive/splaytree.hpp>
#include <boost/intrusive/sgtree.hpp>
//
// intrusive/detail
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
// move
#include <boost/move/utility_core.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/core/no_exceptions_support.hpp>
//
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
// move/detail
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <utility> //std::pair
// other
#include <boost/core/no_exceptions_support.hpp>
namespace boost {
namespace container {
namespace container_detail {
template<class Key, class Value, class KeyCompare, class KeyOfValue>
template<class Key, class T, class Compare, class KeyOfValue>
struct tree_value_compare
: public KeyCompare
: public Compare
{
typedef Value value_type;
typedef KeyCompare key_compare;
typedef T value_type;
typedef Compare key_compare;
typedef KeyOfValue key_of_value;
typedef Key key_type;
explicit tree_value_compare(const key_compare &kcomp)
: KeyCompare(kcomp)
: Compare(kcomp)
{}
tree_value_compare()
: KeyCompare()
: Compare()
{}
const key_compare &key_comp() const
@@ -74,20 +75,20 @@ struct tree_value_compare
key_compare &key_comp()
{ return static_cast<key_compare &>(*this); }
template<class T>
template<class U>
struct is_key
{
static const bool value = is_same<const T, const key_type>::value;
static const bool value = is_same<const U, const key_type>::value;
};
template<class T>
typename enable_if_c<is_key<T>::value, const key_type &>::type
key_forward(const T &key) const
template<class U>
typename enable_if_c<is_key<U>::value, const key_type &>::type
key_forward(const U &key) const
{ return key; }
template<class T>
typename enable_if_c<!is_key<T>::value, const key_type &>::type
key_forward(const T &key) const
template<class U>
typename enable_if_c<!is_key<U>::value, const key_type &>::type
key_forward(const U &key) const
{ return KeyOfValue()(key); }
template<class KeyType, class KeyType2>
@@ -186,17 +187,17 @@ struct tree_node
internal_type m_data;
template<class A, class B>
void do_assign(const std::pair<const A, B> &p)
template<class T1, class T2>
void do_assign(const std::pair<const T1, T2> &p)
{
const_cast<A&>(m_data.first) = p.first;
const_cast<T1&>(m_data.first) = p.first;
m_data.second = p.second;
}
template<class A, class B>
void do_assign(const pair<const A, B> &p)
template<class T1, class T2>
void do_assign(const pair<const T1, T2> &p)
{
const_cast<A&>(m_data.first) = p.first;
const_cast<T1&>(m_data.first) = p.first;
m_data.second = p.second;
}
@@ -204,17 +205,17 @@ struct tree_node
void do_assign(const V &v)
{ m_data = v; }
template<class A, class B>
void do_move_assign(std::pair<const A, B> &p)
template<class T1, class T2>
void do_move_assign(std::pair<const T1, T2> &p)
{
const_cast<A&>(m_data.first) = ::boost::move(p.first);
const_cast<T1&>(m_data.first) = ::boost::move(p.first);
m_data.second = ::boost::move(p.second);
}
template<class A, class B>
void do_move_assign(pair<const A, B> &p)
template<class T1, class T2>
void do_move_assign(pair<const T1, T2> &p)
{
const_cast<A&>(m_data.first) = ::boost::move(p.first);
const_cast<T1&>(m_data.first) = ::boost::move(p.first);
m_data.second = ::boost::move(p.second);
}
@@ -317,16 +318,16 @@ struct intrusive_tree_dispatch
>::type type;
};
template<class A, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
template<class Allocator, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
struct intrusive_tree_type
{
private:
typedef typename boost::container::
allocator_traits<A>::value_type value_type;
allocator_traits<Allocator>::value_type value_type;
typedef typename boost::container::
allocator_traits<A>::void_pointer void_pointer;
allocator_traits<Allocator>::void_pointer void_pointer;
typedef typename boost::container::
allocator_traits<A>::size_type size_type;
allocator_traits<Allocator>::size_type size_type;
typedef typename container_detail::tree_node
< value_type, void_pointer
, tree_type_value, OptimizeSize> node_type;
@@ -429,7 +430,7 @@ class RecyclingCloner
};
template<class KeyValueCompare, class Node>
//where KeyValueCompare is tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
//where KeyValueCompare is tree_value_compare<Key, T, Compare, KeyOfValue>
struct key_node_compare
: private KeyValueCompare
{
@@ -458,35 +459,33 @@ struct key_node_compare
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
};
template <class Key, class Value, class KeyOfValue,
class KeyCompare, class A,
template <class Key, class T, class KeyOfValue,
class Compare, class Allocator,
class Options = tree_assoc_defaults>
class tree
: protected container_detail::node_alloc_holder
< A
< Allocator
, typename container_detail::intrusive_tree_type
< A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue> //ValComp
< Allocator, tree_value_compare<Key, T, Compare, KeyOfValue> //ValComp
, Options::tree_type, Options::optimize_size>::type
>
{
typedef tree_value_compare
<Key, Value, KeyCompare, KeyOfValue> ValComp;
<Key, T, Compare, KeyOfValue> ValComp;
typedef typename container_detail::intrusive_tree_type
< A, ValComp, Options::tree_type
< Allocator, ValComp, Options::tree_type
, Options::optimize_size>::type Icont;
typedef container_detail::node_alloc_holder
<A, Icont> AllocHolder;
<Allocator, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef tree < Key, Value, KeyOfValue
, KeyCompare, A, Options> ThisType;
typedef tree < Key, T, KeyOfValue
, Compare, Allocator, Options> ThisType;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef typename Icont::iterator iiterator;
typedef typename Icont::const_iterator iconst_iterator;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef intrusive_tree_proxy<Options::tree_type> intrusive_tree_proxy_t;
@@ -495,22 +494,22 @@ class tree
public:
typedef Key key_type;
typedef Value value_type;
typedef A allocator_type;
typedef KeyCompare key_compare;
typedef T value_type;
typedef Allocator allocator_type;
typedef Compare key_compare;
typedef ValComp value_compare;
typedef typename boost::container::
allocator_traits<A>::pointer pointer;
allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::
allocator_traits<A>::const_pointer const_pointer;
allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::
allocator_traits<A>::reference reference;
allocator_traits<Allocator>::reference reference;
typedef typename boost::container::
allocator_traits<A>::const_reference const_reference;
allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::
allocator_traits<A>::size_type size_type;
allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::
allocator_traits<A>::difference_type difference_type;
allocator_traits<Allocator>::difference_type difference_type;
typedef difference_type tree_difference_type;
typedef pointer tree_pointer;
typedef const_pointer tree_const_pointer;
@@ -546,7 +545,7 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< container_detail::is_input_iterator<InputIterator>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value
|| container_detail::is_same<alloc_version, version_1>::value
>::type * = 0
#endif
)
@@ -574,7 +573,7 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !(container_detail::is_input_iterator<InputIterator>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value)
|| container_detail::is_same<alloc_version, version_1>::value)
>::type * = 0
#endif
)
@@ -603,7 +602,7 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< container_detail::is_input_iterator<InputIterator>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value
|| container_detail::is_same<alloc_version, version_1>::value
>::type * = 0
#endif
)
@@ -620,7 +619,7 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !(container_detail::is_input_iterator<InputIterator>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value)
|| container_detail::is_same<alloc_version, version_1>::value)
>::type * = 0
#endif
)
@@ -929,18 +928,18 @@ class tree
public:
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class... Args>
std::pair<iterator, bool> emplace_unique(Args&&... args)
std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
{ return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); }
template <class... Args>
iterator emplace_hint_unique(const_iterator hint, Args&&... args)
iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
{ return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); }
template <class... Args>
iterator emplace_equal(Args&&... args)
iterator emplace_equal(BOOST_FWD_REF(Args)... args)
{
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
@@ -950,7 +949,7 @@ class tree
}
template <class... Args>
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
@@ -959,49 +958,41 @@ class tree
return ret;
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
std::pair<iterator, bool> emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
return this->emplace_unique_impl \
(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_unique(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
return this->emplace_unique_hint_impl \
(hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \
destroy_deallocator.release(); \
return ret; \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_equal(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \
destroy_deallocator.release(); \
return ret; \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_TREE_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\
{ return this->emplace_unique_impl(AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_equal(BOOST_MOVE_UREF##N)\
{\
NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));\
destroy_deallocator.release();\
return ret;\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
iterator ret(this->icont().insert_equal(hint.get(), *tmp));\
destroy_deallocator.release();\
return ret;\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_TREE_EMPLACE_CODE)
#undef BOOST_CONTAINER_TREE_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
iterator insert_unique(const_iterator hint, const value_type& v)
{
@@ -1168,17 +1159,25 @@ class tree
} //namespace container_detail {
} //namespace container {
/*
template <class T>
struct has_trivial_destructor_after_move;
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class V, class KOV,
class C, class A>
template <class Key, class T, class KeyOfValue, class Compare, class Allocator, class Options>
struct has_trivial_destructor_after_move
<boost::container::container_detail::tree<K, V, KOV, C, A> >
<
::boost::container::container_detail::tree
<Key, T, KeyOfValue, Compare, Allocator, Options>
>
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
*/
} //namespace boost {
#include <boost/container/detail/config_end.hpp>

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000.
// (C) Copyright Ion Gaztanaga 2005-2013.
// (C) Copyright Ion Gaztanaga 2005-2015.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -8,10 +8,11 @@
//
// See http://www.boost.org/libs/container for documentation.
//
// The alignment_of implementation comes from John Maddock's boost::alignment_of code
// The alignment and Type traits implementation comes from
// John Maddock's TypeTraits library.
//
// Some other tricks come from Howard Hinnant's papers and StackOverflow replies
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
@@ -19,219 +20,41 @@
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/detail/type_traits.hpp>
namespace boost {
namespace container {
namespace container_detail {
struct nat{};
using ::boost::move_detail::is_same;
using ::boost::move_detail::is_pointer;
using ::boost::move_detail::add_reference;
using ::boost::move_detail::add_const;
using ::boost::move_detail::add_const_reference;
using ::boost::move_detail::remove_const;
using ::boost::move_detail::remove_reference;
using ::boost::move_detail::make_unsigned;
using ::boost::move_detail::is_floating_point;
using ::boost::move_detail::is_integral;
using ::boost::move_detail::is_enum;
using ::boost::move_detail::is_pod;
using ::boost::move_detail::is_trivially_destructible;
using ::boost::move_detail::is_trivially_default_constructible;
using ::boost::move_detail::is_trivially_copy_constructible;
using ::boost::move_detail::is_trivially_move_constructible;
using ::boost::move_detail::is_trivially_copy_assignable;
using ::boost::move_detail::is_trivially_move_assignable;
using ::boost::move_detail::is_nothrow_default_constructible;
using ::boost::move_detail::is_nothrow_copy_constructible;
using ::boost::move_detail::is_nothrow_move_constructible;
using ::boost::move_detail::is_nothrow_copy_assignable;
using ::boost::move_detail::is_nothrow_move_assignable;
using ::boost::move_detail::alignment_of;
using ::boost::move_detail::aligned_storage;
using ::boost::move_detail::nat;
template <typename U>
struct LowPriorityConversion
{
// Convertible from T with user-defined-conversion rank.
LowPriorityConversion(const U&) { }
};
//boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative
template <typename T> struct alignment_of;
template <typename T>
struct alignment_of_hack
{
char c;
T t;
alignment_of_hack();
};
template <unsigned A, unsigned S>
struct alignment_logic
{
enum{ value = A < S ? A : S };
};
template< typename T >
struct alignment_of
{
enum{ value = alignment_logic
< sizeof(alignment_of_hack<T>) - sizeof(T)
, sizeof(T)>::value };
};
//This is not standard, but should work with all compilers
union max_align
{
char char_;
short short_;
int int_;
long long_;
#ifdef BOOST_HAS_LONG_LONG
::boost::long_long_type long_long_;
#endif
float float_;
double double_;
long double long_double_;
void * void_ptr_;
};
template<class T>
struct remove_reference
{
typedef T type;
};
template<class T>
struct remove_reference<T&>
{
typedef T type;
};
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class T>
struct remove_reference<T&&>
{
typedef T type;
};
#else
} // namespace container_detail {
} //namespace container {
template<class T>
class rv;
namespace container {
namespace container_detail {
template<class T>
struct remove_reference< ::boost::rv<T> >
{
typedef T type;
};
#endif
template<class T>
struct is_reference
{
enum { value = false };
};
template<class T>
struct is_reference<T&>
{
enum { value = true };
};
template<class T>
struct is_pointer
{
enum { value = false };
};
template<class T>
struct is_pointer<T*>
{
enum { value = true };
};
template <typename T>
struct add_reference
{
typedef T& type;
};
template<class T>
struct add_reference<T&>
{
typedef T& type;
};
template<>
struct add_reference<void>
{
typedef nat &type;
};
template<>
struct add_reference<const void>
{
typedef const nat &type;
};
template <class T>
struct add_const_reference
{ typedef const T &type; };
template <class T>
struct add_const_reference<T&>
{ typedef T& type; };
template <class T>
struct add_const
{ typedef const T type; };
template <typename T, typename U>
struct is_same
{
typedef char yes_type;
struct no_type
{
char padding[8];
};
template <typename V>
static yes_type is_same_tester(V*, V*);
static no_type is_same_tester(...);
static T *t;
static U *u;
static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
};
template<class T>
struct remove_const
{
typedef T type;
};
template<class T>
struct remove_const< const T>
{
typedef T type;
};
template<class T>
struct remove_ref_const
{
typedef typename remove_const< typename remove_reference<T>::type >::type type;
};
template <class T>
struct make_unsigned
{
typedef T type;
};
template <> struct make_unsigned<bool> {};
template <> struct make_unsigned<signed char> {typedef unsigned char type;};
template <> struct make_unsigned<signed short> {typedef unsigned short type;};
template <> struct make_unsigned<signed int> {typedef unsigned int type;};
template <> struct make_unsigned<signed long> {typedef unsigned long type;};
#ifdef BOOST_HAS_LONG_LONG
template <> struct make_unsigned< ::boost::long_long_type > {typedef ::boost::ulong_long_type type;};
#endif
} // namespace container_detail
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP

View File

@@ -30,8 +30,6 @@ namespace boost{
namespace container {
namespace container_detail {
//using namespace boost;
template <class T, unsigned V>
struct version_type
: public container_detail::integral_constant<unsigned, V>
@@ -95,6 +93,11 @@ struct is_version
};
} //namespace container_detail {
typedef container_detail::integral_constant<unsigned, 0> version_0;
typedef container_detail::integral_constant<unsigned, 1> version_1;
typedef container_detail::integral_constant<unsigned, 2> version_2;
} //namespace container {
} //namespace boost{

View File

@@ -46,7 +46,7 @@
#endif
//Macros for documentation purposes. For code, expands to the argument
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
#define BOOST_MOVE_IMPDEF(TYPE) TYPE
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
//Macros for memset optimization. In most platforms
@@ -63,7 +63,7 @@
#endif
#define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2
#define BOOST_CONTAINER_I ,
#define BOOST_MOVE_I ,
#define BOOST_CONTAINER_DOCIGN(T) T
#define BOOST_CONTAINER_DOCONLY(T)

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_FLAT_MAP_HPP
#define BOOST_CONTAINER_FLAT_MAP_HPP
@@ -17,23 +16,30 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
// container/detail
#include <boost/container/detail/flat_tree.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/algorithm.hpp> //equal()
#include <boost/container/allocator_traits.hpp>
#include <boost/container/throw_exception.hpp>
// move
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/detail/move_helpers.hpp>
// intrusive
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
//others
#include <boost/core/no_exceptions_support.hpp>
#include <utility> //pair
#include <functional> //less
#include <memory> //allocator
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -72,7 +78,7 @@ static D force_copy(S s)
//!
//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
//!
//! A is the allocator to allocate the value_types
//! Allocator is the allocator to allocate the value_types
//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
//!
//! flat_map is similar to std::map but it's implemented like an ordered vector.
@@ -87,12 +93,12 @@ static D force_copy(S s)
//! \tparam Key is the key_type of the map
//! \tparam Value is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
//! \tparam A is the allocator to allocate the <code>value_type</code>s
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class Key, class T, class Compare = std::less<Key>, class A = std::allocator< std::pair< Key, T> > >
template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
#else
template <class Key, class T, class Compare, class A>
template <class Key, class T, class Compare, class Allocator>
#endif
class flat_map
{
@@ -104,14 +110,14 @@ class flat_map
std::pair<Key, T>,
container_detail::select1st< std::pair<Key, T> >,
Compare,
A> tree_t;
Allocator> tree_t;
//This is the real tree stored here. It's based on a movable pair
typedef container_detail::flat_tree<Key,
container_detail::pair<Key, T>,
container_detail::select1st<container_detail::pair<Key, T> >,
Compare,
typename allocator_traits<A>::template portable_rebind_alloc
typename allocator_traits<Allocator>::template portable_rebind_alloc
<container_detail::pair<Key, T> >::type> impl_tree_t;
impl_tree_t m_flat_tree; // flat tree representing flat_map
@@ -124,13 +130,13 @@ class flat_map
, container_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::iterator iterator_impl;
<typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::const_iterator const_iterator_impl;
<typename allocator_traits<Allocator>::pointer>::const_iterator const_iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::reverse_iterator reverse_iterator_impl;
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -143,22 +149,22 @@ class flat_map
typedef Key key_type;
typedef T mapped_type;
typedef std::pair<Key, T> value_type;
typedef ::boost::container::allocator_traits<A> allocator_traits_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef BOOST_CONTAINER_IMPDEF(A) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef BOOST_MOVE_IMPDEF(Allocator) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator;
typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_MOVE_IMPDEF(reverse_iterator_impl) reverse_iterator;
typedef BOOST_MOVE_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
typedef BOOST_MOVE_IMPDEF(impl_value_type) movable_value_type;
public:
//////////////////////////////////////////////
@@ -174,7 +180,7 @@ class flat_map
: m_flat_tree()
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
@@ -185,7 +191,7 @@ class flat_map
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
@@ -195,7 +201,7 @@ class flat_map
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
@@ -209,7 +215,7 @@ class flat_map
: m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
@@ -228,7 +234,7 @@ class flat_map
: m_flat_tree(ordered_range, first, last, comp, a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -242,7 +248,7 @@ class flat_map
: m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
@@ -260,7 +266,7 @@ class flat_map
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -271,7 +277,7 @@ class flat_map
: m_flat_tree(x.m_flat_tree)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a flat_map.
@@ -284,7 +290,7 @@ class flat_map
: m_flat_tree(boost::move(x.m_flat_tree))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
@@ -294,7 +300,7 @@ class flat_map
: m_flat_tree(x.m_flat_tree, a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
@@ -305,7 +311,7 @@ class flat_map
: m_flat_tree(boost::move(x.m_flat_tree), a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -609,7 +615,7 @@ class flat_map
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container
@@ -624,7 +630,7 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
std::pair<iterator,bool> emplace(Args&&... args)
std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return container_detail::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -640,32 +646,34 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return container_detail::force_copy<iterator>
(m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
, boost::forward<Args>(args)...));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy< std::pair<iterator, bool> > \
(m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique \
(container_detail::force_copy<impl_const_iterator>(hint) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{\
return container_detail::force_copy< std::pair<iterator, bool> >\
(m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
(container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
#undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
//! with key equivalent to the key of x.
@@ -679,7 +687,7 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
std::pair<iterator,bool> insert(const value_type& x)
{ return container_detail::force_copy<std::pair<iterator,bool> >(
{ return container_detail::force_copy<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); }
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
@@ -1039,10 +1047,13 @@ class flat_map
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class A>
struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, A> >
template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, Allocator> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -1061,7 +1072,7 @@ namespace container {
//!
//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
//!
//! A is the allocator to allocate the value_types
//! Allocator is the allocator to allocate the value_types
//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
//!
//! flat_multimap is similar to std::multimap but it's implemented like an ordered vector.
@@ -1076,12 +1087,12 @@ namespace container {
//! \tparam Key is the key_type of the map
//! \tparam Value is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
//! \tparam A is the allocator to allocate the <code>value_type</code>s
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class Key, class T, class Compare = std::less<Key>, class A = std::allocator< std::pair< Key, T> > >
template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
#else
template <class Key, class T, class Compare, class A>
template <class Key, class T, class Compare, class Allocator>
#endif
class flat_multimap
{
@@ -1092,13 +1103,13 @@ class flat_multimap
std::pair<Key, T>,
container_detail::select1st< std::pair<Key, T> >,
Compare,
A> tree_t;
Allocator> tree_t;
//This is the real tree stored here. It's based on a movable pair
typedef container_detail::flat_tree<Key,
container_detail::pair<Key, T>,
container_detail::select1st<container_detail::pair<Key, T> >,
Compare,
typename allocator_traits<A>::template portable_rebind_alloc
typename allocator_traits<Allocator>::template portable_rebind_alloc
<container_detail::pair<Key, T> >::type> impl_tree_t;
impl_tree_t m_flat_tree; // flat tree representing flat_map
@@ -1111,13 +1122,13 @@ class flat_multimap
, container_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::iterator iterator_impl;
<typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::const_iterator const_iterator_impl;
<typename allocator_traits<Allocator>::pointer>::const_iterator const_iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::reverse_iterator reverse_iterator_impl;
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<A>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -1130,22 +1141,22 @@ class flat_multimap
typedef Key key_type;
typedef T mapped_type;
typedef std::pair<Key, T> value_type;
typedef ::boost::container::allocator_traits<A> allocator_traits_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef BOOST_CONTAINER_IMPDEF(A) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef BOOST_MOVE_IMPDEF(Allocator) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator;
typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_MOVE_IMPDEF(reverse_iterator_impl) reverse_iterator;
typedef BOOST_MOVE_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
typedef BOOST_MOVE_IMPDEF(impl_value_type) movable_value_type;
//////////////////////////////////////////////
//
@@ -1160,7 +1171,7 @@ class flat_multimap
: m_flat_tree()
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
@@ -1172,7 +1183,7 @@ class flat_multimap
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
@@ -1182,7 +1193,7 @@ class flat_multimap
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
@@ -1197,7 +1208,7 @@ class flat_multimap
: m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
@@ -1216,7 +1227,7 @@ class flat_multimap
: m_flat_tree(ordered_range, first, last, comp, a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -1229,7 +1240,7 @@ class flat_multimap
: m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
@@ -1246,7 +1257,7 @@ class flat_multimap
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -1257,7 +1268,7 @@ class flat_multimap
: m_flat_tree(x.m_flat_tree)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
@@ -1269,7 +1280,7 @@ class flat_multimap
: m_flat_tree(boost::move(x.m_flat_tree))
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
@@ -1279,7 +1290,7 @@ class flat_multimap
: m_flat_tree(x.m_flat_tree, a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
@@ -1290,7 +1301,7 @@ class flat_multimap
: m_flat_tree(boost::move(x.m_flat_tree), a)
{
//A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -1529,7 +1540,7 @@ class flat_multimap
size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1540,7 +1551,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
iterator emplace(Args&&... args)
iterator emplace(BOOST_FWD_REF(Args)... args)
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -1556,31 +1567,30 @@ class flat_multimap
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
(container_detail::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal \
(container_detail::force_copy<impl_const_iterator>(hint) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(BOOST_MOVE_UREF##N)\
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal\
(container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE)
#undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
//! newly inserted element.
@@ -1917,10 +1927,13 @@ namespace boost {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class A>
struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T, C, A> >
template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, Allocator> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
} //namespace boost {

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_FLAT_SET_HPP
#define BOOST_CONTAINER_FLAT_SET_HPP
@@ -18,17 +17,25 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
// container/detail
#include <boost/container/detail/flat_tree.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/move_helpers.hpp>
// move
#include <boost/move/traits.hpp>
#include <utility> //pair
#include <functional> //less
#include <memory> //allocator
#include <boost/move/utility_core.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/detail/move_helpers.hpp>
// intrusive/detail
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -50,21 +57,21 @@ namespace container {
//!
//! \tparam Key is the type to be inserted in the set, which is also the key_type
//! \tparam Compare is the comparison functor used to order keys
//! \tparam A is the allocator to be used to allocate memory for this container
//! \tparam Allocator is the allocator to be used to allocate memory for this container
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class Key, class Compare = std::less<Key>, class A = std::allocator<Key> >
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key> >
#else
template <class Key, class Compare, class A>
template <class Key, class Compare, class Allocator>
#endif
class flat_set
///@cond
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, A>
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator>
///@endcond
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(flat_set)
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, A> base_t;
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> base_t;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -77,19 +84,19 @@ class flat_set
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef ::boost::container::allocator_traits<A> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
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 ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
public:
//////////////////////////////////////////////
@@ -411,7 +418,7 @@ class flat_set
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type Key constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container
@@ -426,7 +433,7 @@ class flat_set
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
std::pair<iterator,bool> emplace(Args&&... args)
std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -442,26 +449,24 @@ class flat_set
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
iterator emplace_hint(const_iterator p, Args&&... args)
iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_hint_unique \
(p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE)
#undef BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
@@ -802,10 +807,13 @@ class flat_set
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class A>
struct has_trivial_destructor_after_move<boost::container::flat_set<Key, C, A> >
template <class Key, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_set<Key, Compare, Allocator> >
{
static const bool value = has_trivial_destructor_after_move<A>::value &&has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -827,21 +835,21 @@ namespace container {
//!
//! \tparam Key is the type to be inserted in the multiset, which is also the key_type
//! \tparam Compare is the comparison functor used to order keys
//! \tparam A is the allocator to be used to allocate memory for this container
//! \tparam Allocator is the allocator to be used to allocate memory for this container
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class Key, class Compare = std::less<Key>, class A = std::allocator<Key> >
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key> >
#else
template <class Key, class Compare, class A>
template <class Key, class Compare, class Allocator>
#endif
class flat_multiset
///@cond
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, A>
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator>
///@endcond
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, A> base_t;
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> base_t;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -854,19 +862,19 @@ class flat_multiset
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef ::boost::container::allocator_traits<A> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
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 ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
//! @copydoc ::boost::container::flat_set::flat_set()
explicit flat_multiset()
@@ -1034,7 +1042,7 @@ class flat_multiset
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type Key constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1045,7 +1053,7 @@ class flat_multiset
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
iterator emplace(Args&&... args)
iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -1060,26 +1068,24 @@ class flat_multiset
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
iterator emplace_hint(const_iterator p, Args&&... args)
iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_hint_equal \
(p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE)
#undef BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
@@ -1297,10 +1303,13 @@ class flat_multiset
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class A>
struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C, A> >
template <class Key, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, Compare, Allocator> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {

View File

@@ -6,7 +6,7 @@
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_LIST_HPP
#define BOOST_CONTAINER_LIST_HPP
@@ -16,32 +16,35 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
// container/detail
#include <boost/container/detail/algorithm.hpp>
#include <boost/container/detail/compare_functors.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/algorithm.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/version_type.hpp>
// move
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/compare_functors.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#else
//Preprocessor library to emulate perfect forwarding
#include <boost/container/detail/preprocessor.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
# include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/detail/move_helpers.hpp>
#include <memory> //std::allocator
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/list.hpp>
// other
#include <boost/assert.hpp>
// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -84,10 +87,10 @@ struct iiterator_node_value_type< list_node<T,VoidPointer> > {
typedef T type;
};
template<class A>
template<class Allocator>
struct intrusive_list_type
{
typedef boost::container::allocator_traits<A> allocator_traits_type;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>::template
@@ -120,30 +123,28 @@ struct intrusive_list_type
//! or mutation is explicit.
//!
//! \tparam T The type of object that is stored in the list
//! \tparam A The allocator used for all internal memory management
//! \tparam Allocator The allocator used for all internal memory management
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> >
template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class A>
template <class T, class Allocator>
#endif
class list
: protected container_detail::node_alloc_holder
<A, typename container_detail::intrusive_list_type<A>::type>
<Allocator, typename container_detail::intrusive_list_type<Allocator>::type>
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef typename
container_detail::intrusive_list_type<A>::type Icont;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder;
container_detail::intrusive_list_type<Allocator>::type Icont;
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<A> allocator_traits_type;
typedef boost::container::equal_to_value<A> equal_to_value_type;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef boost::container::equal_to_value<Allocator> equal_to_value_type;
BOOST_COPYABLE_AND_MOVABLE(list)
@@ -159,18 +160,18 @@ class list
//////////////////////////////////////////////
typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef BOOST_MOVE_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator;
typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
//////////////////////////////////////////////
//
@@ -204,7 +205,7 @@ class list
//!
//! <b>Complexity</b>: Linear to n.
explicit list(size_type n)
: AllocHolder(A())
: AllocHolder(Allocator())
{ this->resize(n); }
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
@@ -214,7 +215,7 @@ class list
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
list(size_type n, const T& value, const A& a = A())
list(size_type n, const T& value, const Allocator& a = Allocator())
: AllocHolder(a)
{ this->insert(this->cbegin(), n, value); }
@@ -274,7 +275,7 @@ class list
//!
//! <b>Complexity</b>: Linear to the range [first, last).
template <class InpIt>
list(InpIt first, InpIt last, const A &a = A())
list(InpIt first, InpIt last, const Allocator &a = Allocator())
: AllocHolder(a)
{ this->insert(this->cbegin(), first, last); }
@@ -288,7 +289,7 @@ class list
//! std::initializer_list iterator throws.
//!
//! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
list(std::initializer_list<value_type> il, const A &a = A())
list(std::initializer_list<value_type> il, const Allocator &a = Allocator())
: AllocHolder(a)
{ this->insert(this->cbegin(), il.begin(), il.end()); }
#endif
@@ -677,7 +678,7 @@ class list
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the end of the list.
@@ -687,7 +688,7 @@ class list
//!
//! <b>Complexity</b>: Constant
template <class... Args>
void emplace_back(Args&&... args)
void emplace_back(BOOST_FWD_REF(Args)... args)
{ this->emplace(this->cend(), boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -698,7 +699,7 @@ class list
//!
//! <b>Complexity</b>: Constant
template <class... Args>
void emplace_front(Args&&... args)
void emplace_front(BOOST_FWD_REF(Args)... args)
{ this->emplace(this->cbegin(), boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -709,42 +710,34 @@ class list
//!
//! <b>Complexity</b>: Constant
template <class... Args>
iterator emplace(const_iterator p, Args&&... args)
iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{
NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert(p.get(), *pnode));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
this->emplace(this->cend() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
this->emplace(this->cbegin() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr pnode (AllocHolder::create_node \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert(p.get(), *pnode)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void emplace_back(BOOST_MOVE_UREF##N)\
{ this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void emplace_front(BOOST_MOVE_UREF##N)\
{ this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
return iterator(this->icont().insert(p.get(), *pnode));\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE)
#undef BOOST_CONTAINER_LIST_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
@@ -843,7 +836,7 @@ class list
, typename container_detail::enable_if_c
< !container_detail::is_convertible<InpIt, size_type>::value
&& (container_detail::is_input_iterator<InpIt>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value
|| container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
#endif
@@ -867,7 +860,7 @@ class list
, typename container_detail::enable_if_c
< !container_detail::is_convertible<FwdIt, size_type>::value
&& !(container_detail::is_input_iterator<FwdIt>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value
|| container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
)
@@ -1403,10 +1396,13 @@ class list
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class A>
struct has_trivial_destructor_after_move<boost::container::list<T, A> >
: public ::boost::has_trivial_destructor_after_move<A>
{};
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};
namespace container {

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_MAP_HPP
#define BOOST_CONTAINER_MAP_HPP
@@ -18,25 +17,31 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/tree.hpp>
#include <boost/container/detail/value_init.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
#include <boost/static_assert.hpp>
// container/detail
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/tree.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/value_init.hpp>
#include <boost/container/detail/pair.hpp>
// move
#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/detail/move_helpers.hpp>
// intrusive/detail
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
// other
#include <boost/static_assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <utility> //pair
#include <functional> //less
#include <memory> //allocator
// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -55,22 +60,22 @@ namespace container {
//! by this container is the value_type is std::pair<const Key, T>.
//!
//! \tparam Key is the key_type of the map
//! \tparam Value is the <code>mapped_type</code>
//! \tparam T is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
//! \tparam A is the allocator to allocate the <code>value_type</code>s
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
//! \tparam MapOptions is an packed option type generated using using boost::container::tree_assoc_options.
template < class Key, class T, class Compare = std::less<Key>
, class A = std::allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults >
, class Allocator = new_allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults >
#else
template <class Key, class T, class Compare, class A, class MapOptions>
template <class Key, class T, class Compare, class Allocator, class MapOptions>
#endif
class map
///@cond
: public container_detail::tree
< Key, std::pair<const Key, T>
, container_detail::select1st< std::pair<const Key, T> >
, Compare, A, MapOptions>
, Compare, Allocator, MapOptions>
///@endcond
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -79,7 +84,7 @@ class map
typedef std::pair<const Key, T> value_type_impl;
typedef container_detail::tree
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, A, MapOptions> base_t;
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, MapOptions> base_t;
typedef container_detail::pair <Key, T> movable_value_type_impl;
typedef container_detail::tree_value_compare
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
@@ -94,25 +99,25 @@ class map
//////////////////////////////////////////////
typedef Key key_type;
typedef ::boost::container::allocator_traits<A> allocator_traits_type;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef T mapped_type;
typedef std::pair<const Key, T> value_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
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_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
typedef std::pair<key_type, mapped_type> nonconst_value_type;
typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type;
typedef BOOST_MOVE_IMPDEF(movable_value_type_impl) movable_value_type;
//////////////////////////////////////////////
//
@@ -127,7 +132,7 @@ class map
: base_t()
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object
@@ -139,7 +144,7 @@ class map
: base_t(comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty map using the specified allocator.
@@ -149,7 +154,7 @@ class map
: base_t(a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
@@ -163,7 +168,7 @@ class map
: base_t(true, first, last, comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
@@ -182,7 +187,7 @@ class map
: base_t(ordered_range, first, last, comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -195,7 +200,7 @@ class map
: base_t(true, il.begin(), il.end(), comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
@@ -203,7 +208,7 @@ class map
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -214,7 +219,7 @@ class map
: base_t(static_cast<const base_t&>(x))
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
@@ -226,7 +231,7 @@ class map
: base_t(BOOST_MOVE_BASE(base_t, x))
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a map using the specified allocator.
@@ -236,7 +241,7 @@ class map
: base_t(static_cast<const base_t&>(x), a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a map using the specified allocator.
@@ -249,7 +254,7 @@ class map
: base_t(BOOST_MOVE_BASE(base_t, x), a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -598,7 +603,7 @@ class map
{ this->base_t::insert_unique(il.begin(), il.end()); }
#endif
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... in the container if and only if there is
@@ -612,7 +617,7 @@ class map
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
std::pair<iterator,bool> emplace(Args&&... args)
std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -626,26 +631,24 @@ class map
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
iterator emplace_hint(const_iterator p, Args&&... args)
iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_hint_unique(p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE)
#undef BOOST_CONTAINER_MAP_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -835,10 +838,13 @@ class map
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class A>
struct has_trivial_destructor_after_move<boost::container::map<K, T, C, A> >
template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -859,20 +865,20 @@ namespace container {
//! \tparam Key is the key_type of the map
//! \tparam Value is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
//! \tparam A is the allocator to allocate the <code>value_type</code>s
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
//! \tparam MultiMapOptions is an packed option type generated using using boost::container::tree_assoc_options.
template < class Key, class T, class Compare = std::less<Key>
, class A = std::allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults>
, class Allocator = new_allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults>
#else
template <class Key, class T, class Compare, class A, class MultiMapOptions>
template <class Key, class T, class Compare, class Allocator, class MultiMapOptions>
#endif
class multimap
///@cond
: public container_detail::tree
< Key, std::pair<const Key, T>
, container_detail::select1st< std::pair<const Key, T> >
, Compare, A, MultiMapOptions>
, Compare, Allocator, MultiMapOptions>
///@endcond
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -881,7 +887,7 @@ class multimap
typedef std::pair<const Key, T> value_type_impl;
typedef container_detail::tree
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, A, MultiMapOptions> base_t;
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, MultiMapOptions> base_t;
typedef container_detail::pair <Key, T> movable_value_type_impl;
typedef container_detail::tree_value_compare
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
@@ -898,22 +904,22 @@ class multimap
typedef Key key_type;
typedef T mapped_type;
typedef std::pair<const Key, T> value_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
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_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
typedef std::pair<key_type, mapped_type> nonconst_value_type;
typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type;
typedef BOOST_MOVE_IMPDEF(movable_value_type_impl) movable_value_type;
//////////////////////////////////////////////
//
@@ -928,7 +934,7 @@ class multimap
: base_t()
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified allocator.
@@ -938,7 +944,7 @@ class multimap
: base_t(comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison
@@ -949,7 +955,7 @@ class multimap
: base_t(a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
@@ -964,7 +970,7 @@ class multimap
: base_t(false, first, last, comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
@@ -993,7 +999,7 @@ class multimap
: base_t(false, il.begin(), il.end(), comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
@@ -1001,7 +1007,7 @@ class multimap
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -1012,7 +1018,7 @@ class multimap
: base_t(static_cast<const base_t&>(x))
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
@@ -1024,7 +1030,7 @@ class multimap
: base_t(BOOST_MOVE_BASE(base_t, x))
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a multimap.
@@ -1034,7 +1040,7 @@ class multimap
: base_t(static_cast<const base_t&>(x), a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Move constructs a multimap using the specified allocator.
@@ -1046,7 +1052,7 @@ class multimap
: base_t(BOOST_MOVE_BASE(base_t, x), a)
{
//A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -1130,7 +1136,7 @@ class multimap
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container.
@@ -1142,7 +1148,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
iterator emplace(Args&&... args)
iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -1155,26 +1161,24 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
iterator emplace_hint(const_iterator p, Args&&... args)
iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_hint_equal(p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE)
#undef BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
//! newly inserted element.
@@ -1388,10 +1392,13 @@ class multimap
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class A>
struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, A> >
template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {

View File

@@ -0,0 +1,164 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015. 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_NEW_ALLOCATOR_HPP
#define BOOST_CONTAINER_NEW_ALLOCATOR_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/throw_exception.hpp>
#include <cstddef>
//!\file
namespace boost {
namespace container {
template<bool Value>
struct new_allocator_bool
{ static const bool value = Value; };
template<class T>
class new_allocator;
template<>
class new_allocator<void>
{
public:
typedef void value_type;
typedef void * pointer;
typedef const void* const_pointer;
typedef new_allocator_bool<true> propagate_on_container_move_assignment;
// reference-to-void members are impossible
//!Obtains an new_allocator that allocates
//!objects of type T2
template<class T2>
struct rebind
{
typedef new_allocator< T2> other;
};
//!Default constructor
//!Never throws
new_allocator() BOOST_CONTAINER_NOEXCEPT
{}
//!Constructor from other new_allocator.
//!Never throws
new_allocator(const new_allocator &) BOOST_CONTAINER_NOEXCEPT
{}
//!Constructor from related new_allocator.
//!Never throws
template<class T2>
new_allocator(const new_allocator<T2> &) BOOST_CONTAINER_NOEXCEPT
{}
//!Swaps two allocators, does nothing
//!because this new_allocator is stateless
friend void swap(new_allocator &, new_allocator &) BOOST_CONTAINER_NOEXCEPT
{}
//!An new_allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
friend bool operator==(const new_allocator &, const new_allocator &) BOOST_CONTAINER_NOEXCEPT
{ return true; }
//!An new_allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_CONTAINER_NOEXCEPT
{ return false; }
};
//! This class is a reduced STL-compatible allocator that allocates memory using operator new
template<class T>
class new_allocator
{
public:
typedef T value_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef T & reference;
typedef const T & const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef new_allocator_bool<true> propagate_on_container_move_assignment;
//!Obtains an new_allocator that allocates
//!objects of type T2
template<class T2>
struct rebind
{
typedef new_allocator<T2> other;
};
//!Default constructor
//!Never throws
new_allocator() BOOST_CONTAINER_NOEXCEPT
{}
//!Constructor from other new_allocator.
//!Never throws
new_allocator(const new_allocator &) BOOST_CONTAINER_NOEXCEPT
{}
//!Constructor from related new_allocator.
//!Never throws
template<class T2>
new_allocator(const new_allocator<T2> &) BOOST_CONTAINER_NOEXCEPT
{}
//!Allocates memory for an array of count elements.
//!Throws std::bad_alloc if there is no enough memory
pointer allocate(size_type count)
{
if(BOOST_UNLIKELY(count > this->max_size()))
throw_bad_alloc();
return static_cast<T*>(::operator new(count*sizeof(T)));
}
//!Deallocates previously allocated memory.
//!Never throws
void deallocate(pointer ptr, size_type) BOOST_CONTAINER_NOEXCEPT
{ ::operator delete((void*)ptr); }
//!Returns the maximum number of elements that could be allocated.
//!Never throws
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return size_type(-1)/sizeof(T); }
//!Swaps two allocators, does nothing
//!because this new_allocator is stateless
friend void swap(new_allocator &, new_allocator &) BOOST_CONTAINER_NOEXCEPT
{}
//!An new_allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
friend bool operator==(const new_allocator &, const new_allocator &) BOOST_CONTAINER_NOEXCEPT
{ return true; }
//!An new_allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_CONTAINER_NOEXCEPT
{ return false; }
};
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_ALLOCATOR_HPP

View File

@@ -26,9 +26,7 @@
#include <boost/container/detail/singleton.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/static_assert.hpp>
#include <utility>
#include <cstddef>
namespace boost {
@@ -145,7 +143,7 @@ class node_allocator
//!Throws std::bad_alloc if there is no enough memory
pointer allocate(size_type count, const void * = 0)
{
if(count > this->max_size())
if(BOOST_UNLIKELY(count > this->max_size()))
boost::container::throw_bad_alloc();
if(Version == 1 && count == 1){
@@ -156,7 +154,7 @@ class node_allocator
}
else{
void *ret = boost_cont_malloc(count*sizeof(T));
if(!ret)
if(BOOST_UNLIKELY(!ret))
boost::container::throw_bad_alloc();
return static_cast<pointer>(ret);
}
@@ -187,16 +185,12 @@ class node_allocator
singleton_t::instance().deallocate_free_blocks();
}
std::pair<pointer, bool>
allocation_command(allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, pointer reuse = pointer())
pointer allocation_command
(allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
BOOST_STATIC_ASSERT(( Version > 1 ));
std::pair<pointer, bool> ret =
priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
boost::container::throw_bad_alloc();
return ret;
}
@@ -263,7 +257,7 @@ class node_allocator
BOOST_STATIC_ASSERT(( Version > 1 ));
boost_cont_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after( chain.before_begin()
@@ -279,7 +273,7 @@ class node_allocator
BOOST_STATIC_ASSERT(( Version > 1 ));
boost_cont_memchain ch;
boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch);
if(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch)){
if(BOOST_UNLIKELY(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after( chain.before_begin()
@@ -315,23 +309,26 @@ class node_allocator
{ return false; }
private:
std::pair<pointer, bool> priv_allocation_command
pointer priv_allocation_command
(allocation_type command, std::size_t limit_size
,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
,size_type &prefer_in_recvd_out_size
,pointer &reuse)
{
std::size_t const preferred_size = prefer_in_recvd_out_size;
boost_cont_command_ret_t ret = {0 , 0};
if(limit_size > this->max_size() || preferred_size > this->max_size()){
//ret.first = 0;
return std::pair<pointer, bool>(pointer(), false);
if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
return pointer();
}
std::size_t l_size = limit_size*sizeof(T);
std::size_t p_size = preferred_size*sizeof(T);
std::size_t r_size;
{
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
void* reuse_ptr_void = reuse;
ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
reuse = static_cast<T*>(reuse_ptr_void);
}
received_size = r_size/sizeof(T);
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
prefer_in_recvd_out_size = r_size/sizeof(T);
return (pointer)ret.first;
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -23,8 +23,7 @@
#include <boost/container/detail/workaround.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/detail/fwd_macros.hpp>
#endif
namespace boost { namespace container {
@@ -51,10 +50,7 @@ namespace boost { namespace container {
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename OuterAlloc
BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
, BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
>
template <typename OuterAlloc, BOOST_MOVE_CLASSDFLT9>
class scoped_allocator_adaptor;
#endif
@@ -77,7 +73,7 @@ struct constructible_with_allocator_suffix;
template <class T>
struct constructible_with_allocator_prefix;
template <typename T, typename Alloc>
template <typename T, typename Allocator>
struct uses_allocator;
}} // namespace boost { namespace container {

View File

@@ -17,21 +17,24 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
// container/detail
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/tree.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
// intrusive/detail
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
// move
#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
// move/detail
#include <boost/move/detail/move_helpers.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <utility> //pair
#include <functional> //less
#include <memory> //allocator
// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -51,23 +54,23 @@ namespace container {
//!
//! \tparam Key is the type to be inserted in the set, which is also the key_type
//! \tparam Compare is the comparison functor used to order keys
//! \tparam A is the allocator to be used to allocate memory for this container
//! \tparam Allocator is the allocator to be used to allocate memory for this container
//! \tparam SetOptions is an packed option type generated using using boost::container::tree_assoc_options.
template <class Key, class Compare = std::less<Key>, class A = std::allocator<Key>, class SetOptions = tree_assoc_defaults >
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class SetOptions = tree_assoc_defaults >
#else
template <class Key, class Compare, class A, class SetOptions>
template <class Key, class Compare, class Allocator, class SetOptions>
#endif
class set
///@cond
: public container_detail::tree
< Key, Key, container_detail::identity<Key>, Compare, A, SetOptions>
< Key, Key, container_detail::identity<Key>, Compare, Allocator, SetOptions>
///@endcond
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(set)
typedef container_detail::tree
< Key, Key, container_detail::identity<Key>, Compare, A, SetOptions> base_t;
< Key, Key, container_detail::identity<Key>, Compare, Allocator, SetOptions> base_t;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -80,19 +83,19 @@ class set
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef ::boost::container::allocator_traits<A> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
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 ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
//////////////////////////////////////////////
//
@@ -371,7 +374,7 @@ class set
size_type max_size() const;
#endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type Key constructed with
//! std::forward<Args>(args)... if and only if there is
@@ -388,7 +391,7 @@ class set
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
std::pair<iterator,bool> emplace(Args&&... args)
std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -401,26 +404,24 @@ class set
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
iterator emplace_hint(const_iterator p, Args&&... args)
iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_hint_unique(p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE)
#undef BOOST_CONTAINER_SET_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
@@ -680,10 +681,13 @@ class set
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class SetOptions, class A>
struct has_trivial_destructor_after_move<boost::container::set<Key, C, A, SetOptions> >
template <class Key, class Compare, class SetOptions, class Allocator>
struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, SetOptions> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -702,23 +706,23 @@ namespace container {
//!
//! \tparam Key is the type to be inserted in the set, which is also the key_type
//! \tparam Compare is the comparison functor used to order keys
//! \tparam A is the allocator to be used to allocate memory for this container
//! \tparam Allocator is the allocator to be used to allocate memory for this container
//! \tparam MultiSetOptions is an packed option type generated using using boost::container::tree_assoc_options.
template <class Key, class Compare = std::less<Key>, class A = std::allocator<Key>, class MultiSetOptions = tree_assoc_defaults >
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class MultiSetOptions = tree_assoc_defaults >
#else
template <class Key, class Compare, class A, class MultiSetOptions>
template <class Key, class Compare, class Allocator, class MultiSetOptions>
#endif
class multiset
/// @cond
: public container_detail::tree
<Key, Key,container_detail::identity<Key>, Compare, A, MultiSetOptions>
<Key, Key,container_detail::identity<Key>, Compare, Allocator, MultiSetOptions>
/// @endcond
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(multiset)
typedef container_detail::tree
<Key, Key,container_detail::identity<Key>, Compare, A, MultiSetOptions> base_t;
<Key, Key,container_detail::identity<Key>, Compare, Allocator, MultiSetOptions> base_t;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -732,19 +736,19 @@ class multiset
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef ::boost::container::allocator_traits<A> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
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 ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator;
typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
//////////////////////////////////////////////
//
@@ -900,7 +904,7 @@ class multiset
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type Key constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -908,7 +912,7 @@ class multiset
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
iterator emplace(Args&&... args)
iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -920,26 +924,24 @@ class multiset
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
iterator emplace_hint(const_iterator p, Args&&... args)
iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return this->base_t::emplace_hint_equal(p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE)
#undef BOOST_CONTAINER_MULTISET_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
@@ -1108,10 +1110,13 @@ class multiset
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class A, class MultiSetOptions>
struct has_trivial_destructor_after_move<boost::container::multiset<Key, C, A, MultiSetOptions> >
template <class Key, class Compare, class Allocator, class MultiSetOptions>
struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, MultiSetOptions> >
{
static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value &&
::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {

View File

@@ -18,46 +18,43 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/utilities.hpp>
// container/detail
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#include <boost/container/detail/compare_functors.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/compare_functors.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#include <boost/core/no_exceptions_support.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
#include <boost/container/detail/type_traits.hpp>
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//Preprocessor library to emulate perfect forwarding
#else
#include <boost/container/detail/preprocessor.hpp>
#include <boost/intrusive/slist.hpp>
// move
#include <boost/move/iterator.hpp>
#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <memory> //std::allocator
#include <boost/move/detail/move_helpers.hpp>
// other
#include <boost/core/no_exceptions_support.hpp>
// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
namespace boost {
namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A>
template <class T, class Allocator>
class slist;
namespace container_detail {
@@ -94,10 +91,10 @@ struct iiterator_node_value_type< slist_node<T,VoidPointer> > {
typedef T type;
};
template<class A>
template<class Allocator>
struct intrusive_slist_type
{
typedef boost::container::allocator_traits<A> allocator_traits_type;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>::template
@@ -154,31 +151,29 @@ struct intrusive_slist_type
//! then you should probably use list instead of slist.
//!
//! \tparam T The type of object that is stored in the list
//! \tparam A The allocator used for all internal memory management
//! \tparam Allocator The allocator used for all internal memory management
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> >
template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class A>
template <class T, class Allocator>
#endif
class slist
: protected container_detail::node_alloc_holder
<A, typename container_detail::intrusive_slist_type<A>::type>
<Allocator, typename container_detail::intrusive_slist_type<Allocator>::type>
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef typename
container_detail::intrusive_slist_type<A>::type Icont;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder;
container_detail::intrusive_slist_type<Allocator>::type Icont;
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::
allocator_traits<A> allocator_traits_type;
typedef boost::container::equal_to_value<A> equal_to_value_type;
allocator_traits<Allocator> allocator_traits_type;
typedef boost::container::equal_to_value<Allocator> equal_to_value_type;
BOOST_COPYABLE_AND_MOVABLE(slist)
typedef container_detail::iterator_from_iiterator<typename Icont::iterator, false> iterator_impl;
@@ -193,16 +188,16 @@ class slist
//////////////////////////////////////////////
typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef BOOST_MOVE_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator;
typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator;
public:
@@ -687,7 +682,7 @@ class slist
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the front of the list
@@ -697,7 +692,7 @@ class slist
//!
//! <b>Complexity</b>: Amortized constant time.
template <class... Args>
void emplace_front(Args&&... args)
void emplace_front(BOOST_FWD_REF(Args)... args)
{ this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -708,35 +703,30 @@ class slist
//!
//! <b>Complexity</b>: Constant
template <class... Args>
iterator emplace_after(const_iterator prev, Args&&... args)
iterator emplace_after(const_iterator prev, BOOST_FWD_REF(Args)... args)
{
NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_after(prev.get(), *pnode));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
this->emplace(this->cbegin() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_after(const_iterator prev \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr pnode (AllocHolder::create_node \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_after(prev.get(), *pnode)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void emplace_front(BOOST_MOVE_UREF##N)\
{ this->emplace_after(this->cbefore_begin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_after(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
return iterator(this->icont().insert_after(p.get(), *pnode));\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
#undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
@@ -830,7 +820,7 @@ class slist
, typename container_detail::enable_if_c
< !container_detail::is_convertible<InpIt, size_type>::value
&& (container_detail::is_input_iterator<InpIt>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value
|| container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
#endif
@@ -868,7 +858,7 @@ class slist
, typename container_detail::enable_if_c
< !container_detail::is_convertible<FwdIt, size_type>::value
&& !(container_detail::is_input_iterator<FwdIt>::value
|| container_detail::is_same<alloc_version, allocator_v1>::value
|| container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
)
@@ -1269,7 +1259,7 @@ class slist
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... before p
@@ -1279,24 +1269,22 @@ class slist
//!
//! <b>Complexity</b>: Linear to the elements before p
template <class... Args>
iterator emplace(const_iterator p, Args&&... args)
iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->emplace_after(this->previous(p), boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#else
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace (const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
return this->emplace_after \
(this->previous(p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
return this->emplace_after(this->previous(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
#undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: p must be a valid iterator of *this.
@@ -1631,10 +1619,13 @@ namespace boost {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class A>
struct has_trivial_destructor_after_move<boost::container::slist<T, A> >
: public ::boost::has_trivial_destructor_after_move<A>
{};
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};
namespace container {
@@ -1651,11 +1642,14 @@ namespace container {
//there is no other way
namespace std {
template <class T, class A>
class insert_iterator<boost::container::slist<T, A> >
template <class T>
class insert_iterator;
template <class T, class Allocator>
class insert_iterator<boost::container::slist<T, Allocator> >
{
protected:
typedef boost::container::slist<T, A> Container;
typedef boost::container::slist<T, Allocator> Container;
Container* container;
typename Container::iterator iter;
public:

View File

@@ -25,29 +25,37 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/assert.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/construct_in_place.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
// container/detail
#include <boost/container/detail/addressof.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/construct_in_place.hpp>
#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/container/detail/type_traits.hpp>
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/aligned_storage.hpp>
// intrusive/detail
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
// move
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/container/detail/placement_new.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <utility> //std::pair
#include <memory>
// move/detail
#include <boost/move/detail/move_helpers.hpp>
// other
#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -407,16 +415,16 @@ class stable_vector_iterator
//! operations provide stronger exception safety guarantees than in std::vector.
//!
//! \tparam T The type of object that is stored in the stable_vector
//! \tparam A The allocator used for all internal memory management
//! \tparam Allocator The allocator used for all internal memory management
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> >
template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class A>
template <class T, class Allocator>
#endif
class stable_vector
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
typedef boost::intrusive::
pointer_traits
<typename allocator_traits_type::pointer> ptr_traits;
@@ -452,13 +460,9 @@ class stable_vector
typedef typename node_ptr_traits::reference node_reference;
typedef typename const_node_ptr_traits::reference const_node_reference;
typedef ::boost::container::container_detail::
integral_constant<unsigned, 1> allocator_v1;
typedef ::boost::container::container_detail::
integral_constant<unsigned, 2> allocator_v2;
typedef ::boost::container::container_detail::integral_constant
<unsigned, boost::container::container_detail::
version<A>::value> alloc_version;
version<Allocator>::value> alloc_version;
typedef typename allocator_traits_type::
template portable_rebind_alloc
<node_type>::type node_allocator_type;
@@ -481,10 +485,10 @@ class stable_vector
friend class stable_vector_detail::clear_on_destroy<stable_vector>;
typedef stable_vector_iterator
< typename allocator_traits<A>::pointer
< typename allocator_traits<Allocator>::pointer
, false> iterator_impl;
typedef stable_vector_iterator
< typename allocator_traits<A>::pointer
< typename allocator_traits<Allocator>::pointer
, false> const_iterator_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -495,18 +499,18 @@ class stable_vector
//
//////////////////////////////////////////////
typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef node_allocator_type stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator;
typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
@@ -1315,7 +1319,7 @@ class stable_vector
//
//////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the end of the stable_vector.
@@ -1354,40 +1358,33 @@ class stable_vector
#else
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
size_type pos_n = p - this->cbegin(); \
this->insert(p, EmplaceIterator(ef), EmplaceIterator()); \
return iterator(this->begin() + pos_n); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void emplace_back(BOOST_MOVE_UREF##N)\
{\
typedef emplace_functor##N\
BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
typedef emplace_functor##N\
BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
const size_type pos_n = p - this->cbegin();\
this->insert(p, EmplaceIterator(ef), EmplaceIterator());\
return this->begin() += pos_n;\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE)
#undef BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
@@ -1997,20 +1994,23 @@ class stable_vector
#undef STABLE_VECTOR_CHECK_INVARIANT
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
/*
} //namespace container {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class A>
struct has_trivial_destructor_after_move<boost::container::stable_vector<T, A> >
: public has_trivial_destructor_after_move<A>::value
{};
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};
*/
namespace container {
}}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}} //namespace boost{ namespace container {
#include <boost/container/detail/config_end.hpp>

View File

@@ -17,8 +17,8 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/vector.hpp>
#include <boost/aligned_storage.hpp>
#include <cstddef>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -63,8 +63,7 @@ class static_storage_allocator
{ return true; }
private:
typename boost::aligned_storage
<sizeof(T)*N, boost::alignment_of<T>::value>::type storage;
typename aligned_storage<sizeof(T)*N, alignment_of<T>::value>::type storage;
};
} //namespace container_detail {
@@ -264,8 +263,8 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
//! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//!
//! @par Complexity
//! Linear O(N).
@@ -280,14 +279,14 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
//! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//!
//! @par Complexity
//! Linear O(N).
template <std::size_t C>
static_vector(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
: base_t(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_CONTAINER_I C>::base_t, other))
: base_t(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other))
{}
//! @brief Copy assigns Values stored in the other static_vector to this one.
@@ -341,8 +340,8 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//!
//! @par Complexity
//! Linear O(N).
@@ -358,8 +357,8 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//!
//! @par Complexity
//! Linear O(N).
@@ -367,7 +366,7 @@ public:
static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
{
return static_cast<static_vector&>(base_t::operator=
(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_CONTAINER_I C>::base_t, other)));
(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other)));
}
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -386,8 +385,8 @@ public:
//! @param other The static_vector which content will be swapped with this one's content.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//!
//! @par Complexity
//! Linear O(N).
@@ -400,8 +399,8 @@ public:
//! @param other The static_vector which content will be swapped with this one's content.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//!
//! @par Complexity
//! Linear O(N).

View File

@@ -16,31 +16,37 @@
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/allocation_type.hpp>
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
// container/detail
#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#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/container/detail/version_type.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <boost/static_assert.hpp>
#include <boost/functional/hash.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/functional/hash.hpp>
#include <algorithm>
#include <functional>
#include <functional> //bind2nd, etc.
#include <string>
#include <utility>
#include <memory>
#include <iosfwd>
#include <istream>
#include <ostream>
@@ -49,8 +55,6 @@
#include <cstddef>
#include <climits>
#include <boost/container/detail/type_traits.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/move/traits.hpp>
namespace boost {
@@ -68,15 +72,15 @@ namespace container_detail {
// memory. The destructor assumes that the memory either is the internal buffer,
// or else points to a block of memory that was allocated using string_base's
// allocator and whose size is this->m_storage.
template <class A>
template <class Allocator>
class basic_string_base
{
basic_string_base & operator=(const basic_string_base &);
basic_string_base(const basic_string_base &);
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
public:
typedef A allocator_type;
typedef Allocator allocator_type;
typedef allocator_type stored_allocator_type;
typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::value_type value_type;
@@ -152,8 +156,8 @@ class basic_string_base
//This type has the same alignment and size as long_t but it's POD
//so, unlike long_t, it can be placed in a union
typedef typename boost::aligned_storage< sizeof(long_t),
container_detail::alignment_of<long_t>::value>::type long_raw_t;
typedef typename container_detail::aligned_storage
<sizeof(long_t), container_detail::alignment_of<long_t>::value>::type long_raw_t;
protected:
static const size_type MinInternalBufferChars = 8;
@@ -192,24 +196,24 @@ class basic_string_base
};
struct members_holder
: public A
: public Allocator
{
members_holder()
: A()
: Allocator()
{}
template<class AllocatorConvertible>
explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a)
: A(boost::forward<AllocatorConvertible>(a))
: Allocator(boost::forward<AllocatorConvertible>(a))
{}
repr_t m_repr;
} members_;
const A &alloc() const
const Allocator &alloc() const
{ return members_; }
A &alloc()
Allocator &alloc()
{ return members_; }
static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
@@ -250,23 +254,20 @@ class basic_string_base
protected:
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::version<A>::value> alloc_version;
boost::container::container_detail::version<Allocator>::value> alloc_version;
std::pair<pointer, bool>
allocation_command(allocation_type command,
pointer allocation_command(allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, pointer reuse = 0)
size_type &prefer_in_recvd_out_size,
pointer &reuse)
{
if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
reuse = pointer();
reuse = 0;
command &= ~(expand_fwd | expand_bwd);
}
return container_detail::allocator_version_traits<A>::allocation_command
(this->alloc(), command, limit_size, preferred_size, received_size, reuse);
return container_detail::allocator_version_traits<Allocator>::allocation_command
(this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
@@ -313,7 +314,8 @@ class basic_string_base
if (n <= this->max_size()) {
if(n > InternalBufferChars){
size_type new_cap = this->next_capacity(n);
pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;
pointer reuse = 0;
pointer p = this->allocation_command(allocate_new, n, new_cap, reuse);
this->is_short(false);
this->priv_long_addr(p);
this->priv_long_size(0);
@@ -475,24 +477,24 @@ class basic_string_base
//!
//! \tparam CharT The type of character it contains.
//! \tparam Traits The Character Traits type, which encapsulates basic character operations
//! \tparam A The allocator, used for internal memory management.
//! \tparam Allocator The allocator, used for internal memory management.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class CharT, class Traits = std::char_traits<CharT>, class A = std::allocator<CharT> >
template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = new_allocator<CharT> >
#else
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
#endif
class basic_string
: private container_detail::basic_string_base<A>
: private container_detail::basic_string_base<Allocator>
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
typedef allocator_traits<A> allocator_traits_type;
typedef allocator_traits<Allocator> allocator_traits_type;
BOOST_COPYABLE_AND_MOVABLE(basic_string)
typedef container_detail::basic_string_base<A> base_t;
typedef container_detail::basic_string_base<Allocator> base_t;
static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
protected:
// A helper class to use a char_traits as a function object.
// Allocator helper class to use a char_traits as a function object.
template <class Tr>
struct Eq_traits
@@ -535,25 +537,23 @@ class basic_string
//////////////////////////////////////////////
typedef Traits traits_type;
typedef CharT value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
typedef A allocator_type;
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(pointer) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef Allocator allocator_type;
typedef BOOST_MOVE_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_MOVE_IMPDEF(pointer) iterator;
typedef BOOST_MOVE_IMPDEF(const_pointer) const_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
static const size_type npos = size_type(-1);
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
typedef constant_iterator<CharT, difference_type> cvalue_iterator;
typedef typename base_t::allocator_v1 allocator_v1;
typedef typename base_t::allocator_v2 allocator_v2;
typedef typename base_t::alloc_version alloc_version;
typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -1465,22 +1465,23 @@ class basic_string
const size_type remaining = this->capacity() - old_size;
const pointer old_start = this->priv_addr();
bool enough_capacity = false;
std::pair<pointer, bool> allocation_ret;
size_type new_cap = 0;
//Check if we have enough capacity
pointer hint = pointer();
pointer allocation_ret = pointer();
if (remaining >= n){
enough_capacity = true;
}
else {
//Otherwise expand current buffer or allocate new storage
new_cap = this->next_capacity(n);
hint = old_start;
allocation_ret = this->allocation_command
(allocate_new | expand_fwd | expand_bwd, old_size + n + 1,
new_cap, new_cap, old_start);
(allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);
//Check forward expansion
if(old_start == allocation_ret.first){
if(old_start == allocation_ret){
enough_capacity = true;
this->priv_storage(new_cap);
}
@@ -1516,8 +1517,8 @@ class basic_string
}
}
else{
pointer new_start = allocation_ret.first;
if(!allocation_ret.second){
pointer new_start = allocation_ret;
if(!hint){
//Copy data to new buffer
size_type new_length = 0;
//This can't throw, since characters are POD
@@ -1941,7 +1942,7 @@ class basic_string
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: find(basic_string<CharT,traits,A>(s,n),pos).
//! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(s,n),pos).
size_type find(const CharT* s, size_type pos, size_type n) const
{
if (pos + n > this->size())
@@ -1967,7 +1968,7 @@ class basic_string
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: find(basic_string<CharT,traits,A>(1,c), pos).
//! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(1,c), pos).
size_type find(CharT c, size_type pos = 0) const
{
const size_type sz = this->size();
@@ -2027,7 +2028,7 @@ class basic_string
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: rfind(basic_string<CharT,traits,A>(1,c),pos).
//! <b>Returns</b>: rfind(basic_string<CharT,traits,Allocator>(1,c),pos).
size_type rfind(CharT c, size_type pos = npos) const
{
const size_type len = this->size();
@@ -2084,7 +2085,7 @@ class basic_string
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: find_first_of(basic_string<CharT,traits,A>(1,c), pos).
//! <b>Returns</b>: find_first_of(basic_string<CharT,traits,Allocator>(1,c), pos).
size_type find_first_of(CharT c, size_type pos = 0) const
{ return find(c, pos); }
@@ -2123,7 +2124,7 @@ class basic_string
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: find_last_of(basic_string<CharT,traits,A>(1,c),pos).
//! <b>Returns</b>: find_last_of(basic_string<CharT,traits,Allocator>(1,c),pos).
size_type find_last_of(const CharT* s, size_type pos = npos) const
{ return find_last_of(s, pos, Traits::length(s)); }
@@ -2250,7 +2251,7 @@ class basic_string
//!
//! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size().
//!
//! <b>Returns</b>: basic_string<CharT,traits,A>(data()+pos,rlen).
//! <b>Returns</b>: basic_string<CharT,traits,Allocator>(data()+pos,rlen).
basic_string substr(size_type pos = 0, size_type n = npos) const
{
if (pos > this->size())
@@ -2359,8 +2360,8 @@ class basic_string
if (this->capacity() < res_arg){
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
size_type new_cap = this->next_capacity(n);
pointer new_start = this->allocation_command
(allocate_new, n, new_cap, new_cap).first;
pointer reuse = 0;
pointer new_start = this->allocation_command(allocate_new, n, new_cap, reuse);
size_type new_length = 0;
const pointer addr = this->priv_addr();
@@ -2391,7 +2392,7 @@ class basic_string
template<class AllocVersion>
void priv_shrink_to_fit_dynamic_buffer
( AllocVersion
, typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v1> >::type* = 0)
, typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_1> >::type* = 0)
{
//Allocate a new buffer.
size_type real_cap = 0;
@@ -2400,13 +2401,14 @@ class basic_string
const size_type long_storage = this->priv_long_storage();
//We can make this nothrow as chars are always NoThrowCopyables
BOOST_TRY{
const std::pair<pointer, bool> ret = this->allocation_command
(allocate_new, long_size+1, long_size+1, real_cap, long_addr);
pointer reuse = 0;
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.first)
Traits::copy( container_detail::to_raw_pointer(ret)
, container_detail::to_raw_pointer(this->priv_long_addr())
, long_size+1);
this->priv_long_addr(ret.first);
this->priv_long_addr(ret);
this->priv_storage(real_cap);
//And release old buffer
this->alloc().deallocate(long_addr, long_storage);
@@ -2420,13 +2422,12 @@ class basic_string
template<class AllocVersion>
void priv_shrink_to_fit_dynamic_buffer
( AllocVersion
, typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v2> >::type* = 0)
, typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_2> >::type* = 0)
{
size_type received_size;
size_type received_size = this->priv_long_size()+1;
pointer hint = this->priv_long_addr();
if(this->alloc().allocation_command
( shrink_in_place | nothrow_allocation
, this->priv_long_storage(), this->priv_long_size()+1
, received_size, this->priv_long_addr()).first){
( shrink_in_place | nothrow_allocation, this->priv_long_storage(), received_size, hint)){
this->priv_storage(received_size);
}
}
@@ -2520,7 +2521,7 @@ class basic_string
typedef basic_string
<char
,std::char_traits<char>
,std::allocator<char> >
,new_allocator<char> >
string;
//!Typedef for a basic_string of
@@ -2528,7 +2529,7 @@ string;
typedef basic_string
<wchar_t
,std::char_traits<wchar_t>
,std::allocator<wchar_t> >
,new_allocator<wchar_t> >
wstring;
#endif
@@ -2538,12 +2539,12 @@ wstring;
// Operator+
template <class CharT, class Traits, class A> inline
basic_string<CharT,Traits,A>
operator+(const basic_string<CharT,Traits,A>& x
,const basic_string<CharT,Traits,A>& y)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT,Traits,Allocator>
operator+(const basic_string<CharT,Traits,Allocator>& x
,const basic_string<CharT,Traits,Allocator>& y)
{
typedef basic_string<CharT,Traits,A> str_t;
typedef basic_string<CharT,Traits,Allocator> str_t;
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
str_t result(reserve, x.size() + y.size(), x.get_stored_allocator());
@@ -2552,60 +2553,60 @@ template <class CharT, class Traits, class A> inline
return result;
}
template <class CharT, class Traits, class A> inline
basic_string<CharT, Traits, A> operator+
( BOOST_RV_REF_BEG basic_string<CharT, Traits, A> BOOST_RV_REF_END x
, BOOST_RV_REF_BEG basic_string<CharT, Traits, A> BOOST_RV_REF_END y)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT, Traits, Allocator> operator+
( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
, BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
{
x += y;
return boost::move(x);
}
template <class CharT, class Traits, class A> inline
basic_string<CharT, Traits, A> operator+
( BOOST_RV_REF_BEG basic_string<CharT, Traits, A> BOOST_RV_REF_END x
, const basic_string<CharT,Traits,A>& y)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT, Traits, Allocator> operator+
( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
, const basic_string<CharT,Traits,Allocator>& y)
{
x += y;
return boost::move(x);
}
template <class CharT, class Traits, class A> inline
basic_string<CharT, Traits, A> operator+
(const basic_string<CharT,Traits,A>& x
,BOOST_RV_REF_BEG basic_string<CharT, Traits, A> BOOST_RV_REF_END y)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT, Traits, Allocator> operator+
(const basic_string<CharT,Traits,Allocator>& x
,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
{
y.insert(y.begin(), x.begin(), x.end());
return boost::move(y);
}
template <class CharT, class Traits, class A> inline
basic_string<CharT, Traits, A> operator+
(const CharT* s, basic_string<CharT, Traits, A> y)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT, Traits, Allocator> operator+
(const CharT* s, basic_string<CharT, Traits, Allocator> y)
{
y.insert(y.begin(), s, s + Traits::length(s));
return y;
}
template <class CharT, class Traits, class A> inline
basic_string<CharT,Traits,A> operator+
(basic_string<CharT,Traits,A> x, const CharT* s)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT,Traits,Allocator> operator+
(basic_string<CharT,Traits,Allocator> x, const CharT* s)
{
x += s;
return x;
}
template <class CharT, class Traits, class A> inline
basic_string<CharT,Traits,A> operator+
(CharT c, basic_string<CharT,Traits,A> y)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT,Traits,Allocator> operator+
(CharT c, basic_string<CharT,Traits,Allocator> y)
{
y.insert(y.begin(), c);
return y;
}
template <class CharT, class Traits, class A> inline
basic_string<CharT,Traits,A> operator+
(basic_string<CharT,Traits,A> x, const CharT c)
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT,Traits,Allocator> operator+
(basic_string<CharT,Traits,Allocator> x, const CharT c)
{
x += c;
return x;
@@ -2613,137 +2614,137 @@ template <class CharT, class Traits, class A> inline
// Operator== and operator!=
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator==(const basic_string<CharT,Traits,A>& x,
const basic_string<CharT,Traits,A>& y)
operator==(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y)
{
return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator==(const CharT* s, const basic_string<CharT,Traits,A>& y)
operator==(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{
typename basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
return n == y.size() && Traits::compare(s, y.data(), n) == 0;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator==(const basic_string<CharT,Traits,A>& x, const CharT* s)
operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{
typename basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
return x.size() == n && Traits::compare(x.data(), s, n) == 0;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator!=(const basic_string<CharT,Traits,A>& x,
const basic_string<CharT,Traits,A>& y)
operator!=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y)
{ return !(x == y); }
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator!=(const CharT* s, const basic_string<CharT,Traits,A>& y)
operator!=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ return !(s == y); }
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator!=(const basic_string<CharT,Traits,A>& x, const CharT* s)
operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(x == s); }
// Operator< (and also >, <=, and >=).
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator<(const basic_string<CharT,Traits,A>& x, const basic_string<CharT,Traits,A>& y)
operator<(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
{
return x.compare(y) < 0;
// return basic_string<CharT,Traits,A>
// return basic_string<CharT,Traits,Allocator>
// ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator<(const CharT* s, const basic_string<CharT,Traits,A>& y)
operator<(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{
return y.compare(s) > 0;
// basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,A>
// basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,Allocator>
// ::s_compare(s, s + n, y.begin(), y.end()) < 0;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator<(const basic_string<CharT,Traits,A>& x,
operator<(const basic_string<CharT,Traits,Allocator>& x,
const CharT* s)
{
return x.compare(s) < 0;
// basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,A>
// basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,Allocator>
// ::s_compare(x.begin(), x.end(), s, s + n) < 0;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator>(const basic_string<CharT,Traits,A>& x,
const basic_string<CharT,Traits,A>& y) {
operator>(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y) {
return y < x;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator>(const CharT* s, const basic_string<CharT,Traits,A>& y) {
operator>(const CharT* s, const basic_string<CharT,Traits,Allocator>& y) {
return y < s;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator>(const basic_string<CharT,Traits,A>& x, const CharT* s)
operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{
return s < x;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator<=(const basic_string<CharT,Traits,A>& x,
const basic_string<CharT,Traits,A>& y)
operator<=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y)
{
return !(y < x);
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator<=(const CharT* s, const basic_string<CharT,Traits,A>& y)
operator<=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ return !(y < s); }
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator<=(const basic_string<CharT,Traits,A>& x, const CharT* s)
operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(s < x); }
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator>=(const basic_string<CharT,Traits,A>& x,
const basic_string<CharT,Traits,A>& y)
operator>=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y)
{ return !(x < y); }
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator>=(const CharT* s, const basic_string<CharT,Traits,A>& y)
operator>=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ return !(s < y); }
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline bool
operator>=(const basic_string<CharT,Traits,A>& x, const CharT* s)
operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(x < s); }
// Swap.
template <class CharT, class Traits, class A>
inline void swap(basic_string<CharT,Traits,A>& x, basic_string<CharT,Traits,A>& y)
template <class CharT, class Traits, class Allocator>
inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
{ x.swap(y); }
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -2768,17 +2769,17 @@ string_fill(std::basic_ostream<CharT, Traits>& os,
} //namespace container_detail {
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,A>& s)
operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,Allocator>& s)
{
typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
bool ok = false;
if (sentry) {
ok = true;
typename basic_string<CharT,Traits,A>::size_type n = s.size();
typename basic_string<CharT,Traits,A>::size_type pad_len = 0;
typename basic_string<CharT,Traits,Allocator>::size_type n = s.size();
typename basic_string<CharT,Traits,Allocator>::size_type pad_len = 0;
const bool left = (os.flags() & std::ios::left) != 0;
const std::size_t w = os.width(0);
std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
@@ -2803,9 +2804,9 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Trait
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s)
operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
{
typename std::basic_istream<CharT, Traits>::sentry sentry(is);
@@ -2850,11 +2851,11 @@ operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>&
return is;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>&
getline(std::istream& is, basic_string<CharT,Traits,A>& s,CharT delim)
getline(std::istream& is, basic_string<CharT,Traits,Allocator>& s,CharT delim)
{
typename basic_string<CharT,Traits,A>::size_type nread = 0;
typename basic_string<CharT,Traits,Allocator>::size_type nread = 0;
typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
if (sentry) {
std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
@@ -2882,15 +2883,15 @@ getline(std::istream& is, basic_string<CharT,Traits,A>& s,CharT delim)
return is;
}
template <class CharT, class Traits, class A>
template <class CharT, class Traits, class Allocator>
inline std::basic_istream<CharT, Traits>&
getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s)
getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
{
return getline(is, s, '\n');
}
template <class Ch, class A>
inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, A> const& v)
template <class Ch, class Allocator>
inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator> const& v)
{
return hash_range(v.begin(), v.end());
}
@@ -2901,15 +2902,15 @@ inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, A> const& v
namespace boost {
template <class T>
struct has_trivial_destructor_after_move;
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class C, class T, class A>
struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, A> >
: public ::boost::has_trivial_destructor_after_move<A>
{};
template <class C, class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
{
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
::boost::has_trivial_destructor_after_move<pointer>::value;
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -107,76 +107,39 @@
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\..\..\boost\container\adaptive_pool.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\allocator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\node_allocator.hpp">
</File>
<Filter
Name="detail"
Name="Included Sources"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\detail\adaptive_node_pool.hpp">
RelativePath="..\..\src\dlmalloc_2_8_6.c">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\alloc_lib.h">
RelativePath="..\..\src\dlmalloc_ext_2_8_6.c">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\alloc_lib_auto_link.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\auto_link.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\mutex.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_pool.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\pool_common_alloc.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\singleton.hpp">
</File>
<Filter
Name="Included Sources"
Filter="">
<File
RelativePath="..\..\src\dlmalloc_2_8_6.c">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\dlmalloc_ext_2_8_6.c">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
</Filter>
</Filter>
</Filter>
<Filter

View File

@@ -1,135 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="allocator_traits_test"
ProjectGUID="{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/allocator_traits_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0"
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)/allocator_traits_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/allocator_traits_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/allocator_traits_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)/allocator_traits_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
ProjectType="Visual C++"
Version="7.10"
Name="allocator_traits_test"
ProjectGUID="{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/allocator_traits_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
KeepComments="FALSE"
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)/allocator_traits_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/allocator_traits_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>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\allocator_traits_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
<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/allocator_traits_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)/allocator_traits_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="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\allocator_traits_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -125,6 +125,9 @@
<File
RelativePath="..\..\..\..\boost\container\map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\new_allocator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\node_allocator.hpp">
</File>
@@ -170,12 +173,18 @@
<File
RelativePath="..\..\..\..\boost\container\detail\adaptive_node_pool_impl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\addressof.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\advanced_insert_int.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\algorithm.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\alloc_helpers.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\alloc_lib.h">
</File>
@@ -206,6 +215,9 @@
<File
RelativePath="..\..\test\container_common_tests.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\copy_move_algo.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\destroyers.hpp">
</File>
@@ -221,15 +233,15 @@
<File
RelativePath="..\..\..\..\boost\container\detail\iterator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\iterator_to_raw_pointer.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\iterators.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\memory_util.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
</File>
@@ -239,6 +251,9 @@
<File
RelativePath="..\..\..\..\boost\container\detail\mutex.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\next_capacity.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_alloc_holder.hpp">
</File>
@@ -257,18 +272,21 @@
<File
RelativePath="..\..\..\..\boost\container\detail\pool_common_alloc.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\preprocessor.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\singleton.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\std_fwd.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\detail\std_fwd.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\swap.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\to_raw_pointer.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\transform_iterator.hpp">
</File>
@@ -352,7 +370,7 @@
RelativePath="..\..\test\forward_to_input_iterator.hpp">
</File>
<File
RelativePath="..\..\test\heap_allocator_v1.hpp">
RelativePath="..\..\test\heap_version_1.hpp">
</File>
<File
RelativePath="..\..\test\insert_test.hpp">

View File

@@ -21,7 +21,6 @@
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0"
KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"

View File

@@ -1,136 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="scoped_allocator_adaptor_test"
ProjectGUID="{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/scoped_allocator_adaptor_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0"
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)/scoped_allocator_adaptor_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/scoped_allocator_adaptor_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/scoped_allocator_adaptor_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)/scoped_allocator_adaptor_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
ProjectType="Visual C++"
Version="7.10"
Name="scoped_allocator_adaptor_test"
ProjectGUID="{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/scoped_allocator_adaptor_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)/scoped_allocator_adaptor_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/scoped_allocator_adaptor_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>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\scoped_allocator_adaptor_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
<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/scoped_allocator_adaptor_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)/scoped_allocator_adaptor_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="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\scoped_allocator_adaptor_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,136 +1,136 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="throw_exception_test"
ProjectGUID="{5A8D91E0-FA57-284F-84FE-D3A6BA792002}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/throw_exception_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
ExceptionHandling="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)/throw_exception_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/throw_exception_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/throw_exception_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)/throw_exception_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
ProjectType="Visual C++"
Version="7.10"
Name="throw_exception_test"
ProjectGUID="{5A8D91E0-FA57-284F-84FE-D3A6BA792002}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/throw_exception_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
KeepComments="FALSE"
MinimalRebuild="TRUE"
ExceptionHandling="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)/throw_exception_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/throw_exception_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>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{A1735C4B-7AC5-3542-C626-3A2AF6C0D762}">
<File
RelativePath="..\..\test\throw_exception_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
<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/throw_exception_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)/throw_exception_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="{A1735C4B-7AC5-3542-C626-3A2AF6C0D762}">
<File
RelativePath="..\..\test\throw_exception_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -21,6 +21,7 @@
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
ExceptionHandling="TRUE"
BasicRuntimeChecks="3"

View File

@@ -15,7 +15,6 @@
#include <vector>
#include <iostream>
#include <utility>
#include <cstring>
#include <algorithm> //std::remove
#include <boost/container/detail/alloc_lib_auto_link.hpp>

View File

@@ -11,18 +11,22 @@
#include <cstddef>
#include <boost/container/allocator_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/function_detector.hpp>
#include <boost/move/utility_core.hpp>
#include <memory>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
template<class T>
class SimpleAllocator
{
public:
bool allocate_called_;
bool deallocate_called_;
public:
typedef T value_type;
template <class U>
@@ -73,6 +77,7 @@ class SimpleSmartPtr
template<class T>
class ComplexAllocator
{
public:
bool allocate_called_;
bool deallocate_called_;
bool allocate_hint_called_;
@@ -81,7 +86,6 @@ class ComplexAllocator
mutable bool select_on_container_copy_construction_called_;
bool construct_called_;
public:
typedef T value_type;
typedef SimpleSmartPtr<T> pointer;
typedef SimpleSmartPtr<const T> const_pointer;
@@ -93,9 +97,12 @@ class ComplexAllocator
typedef SimpleSmartPtr<const void> const_void_pointer;
typedef signed short difference_type;
typedef unsigned short size_type;
typedef boost::true_type propagate_on_container_copy_assignment;
typedef boost::true_type propagate_on_container_move_assignment;
typedef boost::true_type propagate_on_container_swap;
typedef boost::container::container_detail::
true_type propagate_on_container_copy_assignment;
typedef boost::container::container_detail::
true_type propagate_on_container_move_assignment;
typedef boost::container::container_detail::
true_type propagate_on_container_swap;
ComplexAllocator()
: allocate_called_(false)
@@ -127,23 +134,27 @@ class ComplexAllocator
size_type max_size() const
{ max_size_called_ = true; return size_type(size_type(0)-1); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<class U BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
void construct(U *p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
construct_called_ = true; \
::new (p) U (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL(N)\
\
template< class U BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
void construct(U *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
{ construct_called_ = true; ::new(p) U ( BOOST_MOVE_FWD##N ); }\
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL)
#undef BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL
#else
template< class U, class ...Args>
void construct(U *p, BOOST_FWD_REF(Args) ...args)
{ construct_called_ = true; ::new(p) U( ::boost::forward<Args>(args)...); }
#endif
template<class U>
void construct(U *p, boost::container::default_init_t)
{
construct_called_ = true;
::new (p) U;
}
{ construct_called_ = true; ::new(p)U; }
//getters
bool allocate_called() const
@@ -212,22 +223,23 @@ void test_void_allocator()
int main()
{
using namespace boost::container::container_detail;
test_void_allocator();
//SimpleAllocator
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::value_type, int>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::pointer, int*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::const_pointer, const int*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::void_pointer, void*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::const_void_pointer, const void*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::difference_type, std::ptrdiff_t>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::size_type, std::size_t>::value ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< SimpleAllocator<int> >::propagate_on_container_copy_assignment::value == false ));
@@ -235,27 +247,27 @@ int main()
< SimpleAllocator<int> >::propagate_on_container_move_assignment::value == false ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< SimpleAllocator<int> >::propagate_on_container_swap::value == false ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::rebind_traits<double>::allocator_type
, SimpleAllocator<double> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::rebind_alloc<double>::value_type
, double >::value ));
//ComplexAllocator
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::value_type, int>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::pointer, SimpleSmartPtr<int> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::const_pointer, SimpleSmartPtr<const int> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::void_pointer, SimpleSmartPtr<void> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::const_void_pointer, SimpleSmartPtr<const void> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::difference_type, signed short>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::size_type, unsigned short>::value ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int> >::propagate_on_container_copy_assignment::value == true ));
@@ -263,10 +275,10 @@ int main()
< ComplexAllocator<int> >::propagate_on_container_move_assignment::value == true ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int> >::propagate_on_container_swap::value == true ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::rebind_traits<double>::allocator_type
, ComplexAllocator<double> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
< ComplexAllocator<int> >::rebind_alloc<double>::value_type
, double >::value ));
@@ -279,51 +291,43 @@ int main()
//allocate
CAllocTraits::allocate(c_alloc, 1);
if(!c_alloc.allocate_called()){
return 1;
}
BOOST_TEST(c_alloc.allocate_called());
SAllocTraits::allocate(s_alloc, 1);
if(!s_alloc.allocate_called()){
return 1;
}
BOOST_TEST(s_alloc.allocate_called());
//deallocate
CAllocTraits::deallocate(c_alloc, CAllocTraits::pointer(), 1);
if(!c_alloc.deallocate_called()){
return 1;
}
BOOST_TEST(c_alloc.deallocate_called());
SAllocTraits::deallocate(s_alloc, SAllocTraits::pointer(), 1);
if(!s_alloc.deallocate_called()){
return 1;
}
BOOST_TEST(s_alloc.deallocate_called());
//allocate with hint
CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer());
if(!c_alloc.allocate_hint_called()){
return 1;
}
BOOST_TEST(c_alloc.allocate_hint_called());
s_alloc.allocate_called_ = false;
SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer());
BOOST_TEST(s_alloc.allocate_called());
//destroy
float dummy;
CAllocTraits::destroy(c_alloc, &dummy);
if(!c_alloc.destroy_called()){
return 1;
}
BOOST_TEST(c_alloc.destroy_called());
SAllocTraits::destroy(s_alloc, &dummy);
//max_size
CAllocTraits::max_size(c_alloc);
if(!c_alloc.max_size_called()){
return 1;
}
BOOST_TEST(c_alloc.max_size_called());
SAllocTraits::max_size(s_alloc);
//select_on_container_copy_construction
CAllocTraits::select_on_container_copy_construction(c_alloc);
if(!c_alloc.select_on_container_copy_construction_called()){
return 1;
}
BOOST_TEST(c_alloc.select_on_container_copy_construction_called());
SAllocTraits::select_on_container_copy_construction(s_alloc);
//construct
@@ -332,81 +336,61 @@ int main()
c.copymoveconstructed_ = true;
c.copymoveconstructed_ = true;
CAllocTraits::construct(c_alloc, &c);
if(!c_alloc.construct_called() || c.copymoveconstructed() || c.moved()){
return 1;
}
BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved());
}
{
int i = 5;
CAllocTraits::construct(c_alloc, &i, boost::container::default_init);
if(!c_alloc.construct_called() || i != 5){
return 1;
}
BOOST_TEST(c_alloc.construct_called() && i == 5);
}
{
copymovable c;
copymovable c2;
CAllocTraits::construct(c_alloc, &c, c2);
if(!c_alloc.construct_called() || !c.copymoveconstructed() || c.moved()){
return 1;
}
BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && !c.moved());
}
{
copymovable c;
copymovable c2;
CAllocTraits::construct(c_alloc, &c, ::boost::move(c2));
if(!c_alloc.construct_called() || !c.copymoveconstructed() || !c.moved()){
return 1;
}
BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && c.moved());
}
{
copymovable c;
c.copymoveconstructed_ = true;
c.copymoveconstructed_ = true;
SAllocTraits::construct(s_alloc, &c);
if(c.copymoveconstructed() || c.moved()){
return 1;
}
BOOST_TEST(!c.copymoveconstructed() && !c.moved());
}
{
int i = 4;
SAllocTraits::construct(s_alloc, &i, boost::container::default_init);
if(i != 4){
return 1;
}
BOOST_TEST(i == 4);
}
{
copymovable c;
copymovable c2;
SAllocTraits::construct(s_alloc, &c, c2);
if(!c.copymoveconstructed() || c.moved()){
return 1;
}
BOOST_TEST(c.copymoveconstructed() && !c.moved());
}
{
copymovable c;
copymovable c2;
SAllocTraits::construct(s_alloc, &c, ::boost::move(c2));
if(!c.copymoveconstructed() || !c.moved()){
return 1;
}
BOOST_TEST(c.copymoveconstructed() && c.moved());
}
{
copymovable c;
CAllocTraits::construct(c_alloc, &c, 0, 1, 2);
if(!c_alloc.construct_called() || c.copymoveconstructed() || c.moved()){
return 1;
}
BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved());
}
{
copymovable c;
copymovable c2;
SAllocTraits::construct(s_alloc, &c, 0, 1, 2);
if(c.copymoveconstructed() || c.moved()){
return 1;
}
BOOST_TEST(!c.copymoveconstructed() && !c.moved());
}
return 0;
return ::boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -12,27 +12,7 @@
#define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <list>
#include <boost/move/utility_core.hpp>
#include <boost/container/detail/mpl.hpp>
#include "print_container.hpp"
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include <string>
#include <vector>
#include "emplace_test.hpp"
#include "input_from_forward_iterator.hpp"
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/static_assert.hpp>
#include "insert_test.hpp"
#include <cstddef>
namespace boost{
namespace container {

View File

@@ -9,11 +9,9 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <deque>
#include <iostream>
#include <functional>
#include <list>
#include <boost/container/deque.hpp>

View File

@@ -17,18 +17,22 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/addressof.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <boost/assert.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
@@ -136,12 +140,8 @@ class dummy_test_allocator
//Experimental version 2 dummy_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::container::allocation_type,
size_type,
size_type,
size_type &, const pointer & = 0)
{ return std::pair<pointer, bool>(pointer(), true); }
pointer allocation_command(boost::container::allocation_type, size_type, size_type &, pointer &p)
{ p = pointer(); return pointer(); }
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.

View File

@@ -16,8 +16,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/container/detail/type_traits.hpp>
namespace boost{
namespace container {
@@ -147,7 +146,7 @@ bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, Em
static EmplaceInt expected [10];
typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
static boost::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
static boost::container::container_detail::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
static EmplaceIntPair* initialize_emplace_int_pair()
{

View File

@@ -17,14 +17,18 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/addressof.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <boost/assert.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
@@ -117,35 +121,33 @@ class expand_bwd_test_allocator
//Experimental version 2 expand_bwd_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::container::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
pointer allocation_command(boost::container::allocation_type command,
size_type limit_size,size_type &prefer_in_recvd_out_size,pointer &reuse)
{
(void)preferred_size; (void)reuse; (void)command;
(void)reuse; (void)command;
//This allocator only expands backwards!
assert(m_allocations == 0 || (command & boost::container::expand_bwd));
received_size = limit_size;
prefer_in_recvd_out_size = limit_size;
if(m_allocations == 0){
if((m_offset + limit_size) > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer + m_offset, false);
reuse = 0;
return (mp_buffer + m_offset);
}
else if(m_allocations == 1){
if(limit_size > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer, true);
return mp_buffer;
}
else{
throw_bad_alloc();
return std::pair<pointer, bool>(mp_buffer, true);
return mp_buffer;
}
}

View File

@@ -18,7 +18,6 @@
#include "expand_bwd_test_allocator.hpp"
#include <boost/container/detail/algorithm.hpp> //equal()
#include "movable_int.hpp"
#include <boost/type_traits/remove_volatile.hpp>
#include <boost/move/make_unique.hpp>
namespace boost { namespace container { namespace test {
@@ -79,6 +78,9 @@ bool test_insert_with_expand_bwd()
{ 0, 100, 200 };
for(unsigned int pos = 0; pos < sizeof(Position)/sizeof(Position[0]); ++pos){
if(!life_count<value_type>::check(0))
return false;
for(unsigned int iteration = 0; iteration < Iterations; ++iteration)
{
boost::movelib::unique_ptr<char[]> memptr =
@@ -122,6 +124,8 @@ bool test_insert_with_expand_bwd()
return false;
}
}
if(!life_count<value_type>::check(0))
return false;
}
return true;

View File

@@ -199,17 +199,17 @@ void test_move()
move_assign.swap(original);
}
template<class T, class A>
template<class T, class Allocator>
class flat_map_propagate_test_wrapper
: public boost::container::flat_map
< T, T, std::less<T>
, typename boost::container::allocator_traits<A>::template
, typename boost::container::allocator_traits<Allocator>::template
portable_rebind_alloc< std::pair<T, T> >::type>
{
BOOST_COPYABLE_AND_MOVABLE(flat_map_propagate_test_wrapper)
typedef boost::container::flat_map
< T, T, std::less<T>
, typename boost::container::allocator_traits<A>::template
, typename boost::container::allocator_traits<Allocator>::template
portable_rebind_alloc< std::pair<T, T> >::type> Base;
public:
flat_map_propagate_test_wrapper()
@@ -441,8 +441,8 @@ int main()
//Allocator argument container
{
flat_map<int, int> map_((std::allocator<std::pair<int, int> >()));
flat_multimap<int, int> multimap_((std::allocator<std::pair<int, int> >()));
flat_map<int, int> map_((flat_map<int, int>::allocator_type()));
flat_multimap<int, int> multimap_((flat_multimap<int, int>::allocator_type()));
}
//Now test move semantics
{

View File

@@ -227,12 +227,12 @@ void test_move()
move_assign.swap(original);
}
template<class T, class A>
template<class T, class Allocator>
class flat_set_propagate_test_wrapper
: public boost::container::flat_set<T, std::less<T>, A>
: public boost::container::flat_set<T, std::less<T>, Allocator>
{
BOOST_COPYABLE_AND_MOVABLE(flat_set_propagate_test_wrapper)
typedef boost::container::flat_set<T, std::less<T>, A> Base;
typedef boost::container::flat_set<T, std::less<T>, Allocator> Base;
public:
flat_set_propagate_test_wrapper()
: Base()
@@ -524,8 +524,8 @@ int main()
//Allocator argument container
{
flat_set<int> set_((std::allocator<int>()));
flat_multiset<int> multiset_((std::allocator<int>()));
flat_set<int> set_((flat_set<int>::allocator_type()));
flat_multiset<int> multiset_((flat_multiset<int>::allocator_type()));
}
//Now test move semantics
{

View File

@@ -207,3 +207,13 @@ int main ()
}
#include <boost/container/detail/config_end.hpp>
/*
#include <boost/container/list.hpp>
//#include <list>
int main()
{
return 0;
}
*/

View File

@@ -20,11 +20,8 @@
#include <boost/move/iterator.hpp>
#include <boost/move/make_unique.hpp>
#include <memory>
#include <list>
#include <vector>
#include <functional> //std::greater
#include <string>
namespace boost{
namespace container {

View File

@@ -13,7 +13,6 @@
#include <boost/container/node_allocator.hpp>
#include <boost/container/adaptive_pool.hpp>
#include <utility>
#include <map>
#include "print_container.hpp"
@@ -236,11 +235,11 @@ void test_move()
move_assign.swap(original);
}
template<class T, class A>
template<class T, class Allocator>
class map_propagate_test_wrapper
: public boost::container::map
< T, T, std::less<T>
, typename boost::container::allocator_traits<A>::template
, typename boost::container::allocator_traits<Allocator>::template
portable_rebind_alloc< std::pair<const T, T> >::type
//tree_assoc_defaults
>
@@ -248,7 +247,7 @@ class map_propagate_test_wrapper
BOOST_COPYABLE_AND_MOVABLE(map_propagate_test_wrapper)
typedef boost::container::map
< T, T, std::less<T>
, typename boost::container::allocator_traits<A>::template
, typename boost::container::allocator_traits<Allocator>::template
portable_rebind_alloc< std::pair<const T, T> >::type
> Base;
public:
@@ -399,8 +398,8 @@ int main ()
}
//Allocator argument container
{
map<int, int> map_((std::allocator<std::pair<const int, int> >()));
multimap<int, int> multimap_((std::allocator<std::pair<const int, int> >()));
map<int, int> map_((map<int, int>::allocator_type()));
multimap<int, int> multimap_((multimap<int, int>::allocator_type()));
}
//Now test move semantics
{

View File

@@ -14,22 +14,22 @@
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include "print_container.hpp"
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/make_unique.hpp>
#include <utility> //std::pair
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <string>
#include <iostream>
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#include <boost/intrusive/detail/mpl.hpp>
namespace boost { namespace container { namespace test {
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(has_member_rebalance, rebalance)
}}}
template<class T1, class T2, class T3, class T4>
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
@@ -534,13 +534,13 @@ int map_test()
return 1;
map_test_rebalanceable(boostmap
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMap>::value>());
, container_detail::bool_<has_member_rebalance<MyBoostMap>::value>());
if(!CheckEqualContainers(boostmap, stdmap)){
std::cout << "Error in boostmap.rebalance()" << std::endl;
return 1;
}
map_test_rebalanceable(boostmultimap
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMultiMap>::value>());
, container_detail::bool_<has_member_rebalance<MyBoostMap>::value>());
if(!CheckEqualContainers(boostmultimap, stdmultimap)){
std::cout << "Error in boostmultimap.rebalance()" << std::endl;
return 1;

View File

@@ -22,14 +22,13 @@
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/static_assert.hpp>
#include <cstring>
#include <new>
using namespace boost::container;
typedef boost::aligned_storage<sizeof(void*)*4>::type buffer_t;
typedef boost::container::container_detail::aligned_storage<sizeof(void*)*4>::type buffer_t;
static buffer_t buffer_0x00;
static buffer_t buffer_0xFF;

View File

@@ -12,33 +12,12 @@
#define BOOST_PRINTCONTAINER_HPP
#include <boost/container/detail/config_begin.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
namespace boost{
namespace container {
namespace test{
struct PrintValues
{
typedef int argument_type;
typedef void result_type;
void operator() (int value) const
{
std::cout << value << " ";
}
};
template<class Container>
void PrintContents(const Container &cont, const char *contName)
{
std::cout<< "Printing contents of " << contName << std::endl;
std::for_each(cont.begin(), cont.end(), PrintValues());
std::cout<< std::endl << std::endl;
}
//Function to dump data
template<class MyBoostCont
,class MyStdCont>

View File

@@ -9,7 +9,6 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/scoped_allocator_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <cstddef>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/utility_core.hpp>
@@ -237,21 +236,22 @@ namespace container {
template<unsigned int AllocatorTag>
struct constructible_with_allocator_prefix
< ::mark_on_scoped_allocation<ConstructiblePrefix, AllocatorTag> >
: ::boost::true_type
{};
{
static const bool value = true;
};
template<unsigned int AllocatorTag>
struct constructible_with_allocator_suffix
< ::mark_on_scoped_allocation<ConstructibleSuffix, AllocatorTag> >
: ::boost::true_type
{};
{
static const bool value = true;
};
} //namespace container {
} //namespace boost {
#include <boost/container/scoped_allocator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/detail/pair.hpp>

View File

@@ -1,3 +1,12 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-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/config_begin.hpp>
#include <memory>
@@ -136,26 +145,26 @@ struct is_unique_assoc
static const bool value = false;
};
template<class K, class V, class C, class A>
struct is_unique_assoc< map<K, V, C, A> >
template<class Key, class T, class Compare, class Allocator>
struct is_unique_assoc< map<Key, T, Compare, Allocator> >
{
static const bool value = true;
};
template<class K, class V, class C, class A>
struct is_unique_assoc< flat_map<K, V, C, A> >
template<class Key, class T, class Compare, class Allocator>
struct is_unique_assoc< flat_map<Key, T, Compare, Allocator> >
{
static const bool value = true;
};
template<class V, class C, class A>
struct is_unique_assoc< set<V, C, A> >
template<class Key, class Compare, class Allocator>
struct is_unique_assoc< set<Key, Compare, Allocator> >
{
static const bool value = true;
};
template<class V, class C, class A>
struct is_unique_assoc< flat_set<V, C, A> >
template<class Key, class Compare, class Allocator>
struct is_unique_assoc< flat_set<Key, Compare, Allocator> >
{
static const bool value = true;
};
@@ -171,26 +180,26 @@ struct is_map
static const bool value = false;
};
template<class K, class V, class C, class A>
struct is_map< map<K, V, C, A> >
template<class Key, class T, class Compare, class Allocator>
struct is_map< map<Key, T, Compare, Allocator> >
{
static const bool value = true;
};
template<class K, class V, class C, class A>
struct is_map< flat_map<K, V, C, A> >
template<class Key, class T, class Compare, class Allocator>
struct is_map< flat_map<Key, T, Compare, Allocator> >
{
static const bool value = true;
};
template<class K, class V, class C, class A>
struct is_map< multimap<K, V, C, A> >
template<class Key, class T, class Compare, class Allocator>
struct is_map< multimap<Key, T, Compare, Allocator> >
{
static const bool value = true;
};
template<class K, class V, class C, class A>
struct is_map< flat_multimap<K, V, C, A> >
template<class Key, class T, class Compare, class Allocator>
struct is_map< flat_multimap<Key, T, Compare, Allocator> >
{
static const bool value = true;
};
@@ -201,26 +210,26 @@ struct is_set
static const bool value = false;
};
template<class V, class C, class A>
struct is_set< set<V, C, A> >
template<class Key, class Compare, class Allocator>
struct is_set< set<Key, Compare, Allocator> >
{
static const bool value = true;
};
template<class V, class C, class A>
struct is_set< flat_set<V, C, A> >
template<class Key, class Compare, class Allocator>
struct is_set< flat_set<Key, Compare, Allocator> >
{
static const bool value = true;
};
template<class V, class C, class A>
struct is_set< multiset<V, C, A> >
template<class Key, class Compare, class Allocator>
struct is_set< multiset<Key, Compare, Allocator> >
{
static const bool value = true;
};
template<class V, class C, class A>
struct is_set< flat_multiset<V, C, A> >
template<class Key, class Compare, class Allocator>
struct is_set< flat_multiset<Key, Compare, Allocator> >
{
static const bool value = true;
};

View File

@@ -212,14 +212,14 @@ void test_move()
move_assign.swap(original);
}
template<class T, class A>
template<class T, class Allocator>
class set_propagate_test_wrapper
: public boost::container::set<T, std::less<T>, A
: public boost::container::set<T, std::less<T>, Allocator
//tree_assoc_defaults
>
{
BOOST_COPYABLE_AND_MOVABLE(set_propagate_test_wrapper)
typedef boost::container::set<T, std::less<T>, A > Base;
typedef boost::container::set<T, std::less<T>, Allocator > Base;
public:
set_propagate_test_wrapper()
: Base()
@@ -363,8 +363,8 @@ int main ()
}
//Allocator argument container
{
set<int> set_((std::allocator<int>()));
multiset<int> multiset_((std::allocator<int>()));
set<int> set_((set<int>::allocator_type()));
multiset<int> multiset_((multiset<int>::allocator_type()));
}
//Now test move semantics
{

View File

@@ -13,22 +13,17 @@
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <memory>
#include <set>
#include <functional>
#include "print_container.hpp"
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/make_unique.hpp>
#include <string>
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace test {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
namespace boost{
namespace container {

View File

@@ -9,11 +9,7 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/container/stable_vector.hpp>
#include <boost/container/allocator.hpp>

View File

@@ -78,6 +78,9 @@ private:
namespace boost {
template <class T>
struct has_nothrow_move;
template <>
struct has_nothrow_move<counting_value>
{

View File

@@ -432,12 +432,12 @@ bool test_expand_bwd()
return test::test_all_expand_bwd<string_type>();
}
template<class T, class A>
template<class T, class Allocator>
class string_propagate_test_wrapper
: public basic_string<T, std::char_traits<T>, A>
: public basic_string<T, std::char_traits<T>, Allocator>
{
BOOST_COPYABLE_AND_MOVABLE(string_propagate_test_wrapper)
typedef basic_string<T, std::char_traits<T>, A> Base;
typedef basic_string<T, std::char_traits<T>, Allocator> Base;
public:
string_propagate_test_wrapper()
: Base()

View File

@@ -7,10 +7,8 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <memory>
#include <iostream>
#include <functional>
#include <boost/container/vector.hpp>
#include <boost/container/allocator.hpp>
@@ -252,3 +250,14 @@ int main()
return 0;
}
/*
#include <vector>
//#include <boost/container/vector.hpp>
int main()
{
boost::container::vector<int> a;
return 0;
}
*/

View File

@@ -13,10 +13,8 @@
#include <boost/container/detail/config_begin.hpp>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <list>
#include <boost/move/utility_core.hpp>