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 , bc::NodeAlloc_nodes_per_block
, 2>; , 2>;
template<class A> struct get_allocator_name; template<class Allocator> struct get_allocator_name;
template<> struct get_allocator_name<StdAllocator> template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "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) 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; nanosecond_type tinsert, terase;
boost_cont_malloc_stats_t insert_stats, erase_stats; boost_cont_malloc_stats_t insert_stats, erase_stats;
std::size_t insert_inuse, erase_inuse; 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){ if(csv_output){
std::cout << get_allocator_name<A>::get() std::cout << get_allocator_name<Allocator>::get()
<< ";" << ";"
<< num_iterations << num_iterations
<< ";" << ";"
@@ -206,7 +206,7 @@ void list_test_template(std::size_t num_iterations, std::size_t num_elements, bo
} }
else{ else{
std::cout << std::endl std::cout << std::endl
<< "A: " << get_allocator_name<A>::get() << "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl << std::endl
<< " allocation/deallocation(ns): " << float(tinsert)/(num_iterations*num_elements) << '\t' << float(terase)/(num_iterations*num_elements) << " allocation/deallocation(ns): " << float(tinsert)/(num_iterations*num_elements) << '\t' << float(terase)/(num_iterations*num_elements)
<< std::endl << 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, 2, bc::expand_fwd> AllocatorPlusV2;
typedef bc::allocator<int, 1> AllocatorPlusV1; 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> template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } }; { static const char *get() { return "StdAllocator"; } };
@@ -90,14 +90,14 @@ struct has_trivial_destructor_after_move<MyInt>
void print_header() void print_header()
{ {
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";" std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
<< "Capacity" << ";" << "push_back(ns)" << ";" << "A calls" << ";" << "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";"
<< "New allocations" << ";" << "Bwd expansions" << std::endl; << "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) 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; unsigned int numalloc = 0, numexpand = 0;
cpu_timer timer; 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; nanosecond_type nseconds = timer.elapsed().wall;
if(csv_output){ if(csv_output){
std::cout << get_allocator_name<A>::get() std::cout << get_allocator_name<Allocator>::get()
<< ";" << ";"
<< num_iterations << num_iterations
<< ";" << ";"
@@ -151,7 +151,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
} }
else{ else{
std::cout << std::endl std::cout << std::endl
<< "A: " << get_allocator_name<A>::get() << "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl << std::endl
<< " push_back ns: " << " push_back ns: "
<< float(nseconds)/(num_iterations*num_elements) << 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, 2> AllocatorPlusV2;
typedef bc::allocator<int, 1> AllocatorPlusV1; 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> template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } }; { static const char *get() { return "StdAllocator"; } };
@@ -60,32 +60,32 @@ struct stats_traits;
template<> template<>
struct stats_traits<std::vector> struct stats_traits<std::vector>
{ {
template<class T, class A> template<class T, class Allocator>
static void reset_alloc_stats(std::vector<T, A> &) static void reset_alloc_stats(std::vector<T, Allocator> &)
{} {}
template<class T, class A> template<class T, class Allocator>
static std::size_t get_num_alloc(std::vector<T, A> &) static std::size_t get_num_alloc(std::vector<T, Allocator> &)
{ return 0; } { return 0; }
template<class T, class A> template<class T, class Allocator>
static std::size_t get_num_expand(std::vector<T, A> &) static std::size_t get_num_expand(std::vector<T, Allocator> &)
{ return 0; } { return 0; }
}; };
template<> template<>
struct stats_traits<bc::vector> struct stats_traits<bc::vector>
{ {
template<class T, class A> template<class T, class Allocator>
static void reset_alloc_stats(bc::vector<T, A> &v) static void reset_alloc_stats(bc::vector<T, Allocator> &v)
{ v.reset_alloc_stats(); } { v.reset_alloc_stats(); }
template<class T, class A> template<class T, class Allocator>
static std::size_t get_num_alloc(bc::vector<T, A> &v) static std::size_t get_num_alloc(bc::vector<T, Allocator> &v)
{ return v.num_alloc; } { return v.num_alloc; }
template<class T, class A> template<class T, class Allocator>
static std::size_t get_num_expand(bc::vector<T, A> &v) static std::size_t get_num_expand(bc::vector<T, Allocator> &v)
{ return v.num_expand_fwd; } { 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) 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; unsigned int numalloc = 0, numexpand = 0;
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #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; nanosecond_type nseconds = timer.elapsed().wall;
if(csv_output){ if(csv_output){
std::cout << get_allocator_name<A>::get() std::cout << get_allocator_name<Allocator>::get()
<< ";" << ";"
<< num_iterations << num_iterations
<< ";" << ";"
@@ -212,7 +212,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
} }
else{ else{
std::cout << std::endl std::cout << std::endl
<< "A: " << get_allocator_name<A>::get() << "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl << std::endl
<< " push_back ns: " << " push_back ns: "
<< float(nseconds)/(num_iterations*num_elements) << 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() void print_header()
{ {
std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";" std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
<< "Capacity" << ";" << "push_back(ns)" << ";" << "A calls" << ";" << "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";"
<< "New allocations" << ";" << "Fwd expansions" << std::endl; << "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, 2> AllocatorPlusV2;
typedef bc::allocator<int, 1> AllocatorPlusV1; 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> template<> struct get_allocator_name<StdAllocator>
{ static const char *get() { return "StdAllocator"; } }; { static const char *get() { return "StdAllocator"; } };
@@ -69,10 +69,10 @@ void print_header()
<< "num_shrink" << ";" << "shrink_to_fit(ns)" << std::endl; << "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) 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; unsigned int capacity = 0;
const std::size_t Step = 5; const std::size_t Step = 5;
@@ -84,7 +84,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
#ifndef NDEBUG #ifndef NDEBUG
typedef bc::container_detail::integral_constant 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 #endif
for(unsigned int r = 0; r != num_iterations; ++r){ 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; nanosecond_type nseconds = timer.elapsed().wall;
if(csv_output){ if(csv_output){
std::cout << get_allocator_name<A>::get() std::cout << get_allocator_name<Allocator>::get()
<< ";" << ";"
<< num_iterations << num_iterations
<< ";" << ";"
@@ -118,7 +118,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements
} }
else{ else{
std::cout << std::endl std::cout << std::endl
<< "A: " << get_allocator_name<A>::get() << "Allocator: " << get_allocator_name<Allocator>::get()
<< std::endl << std::endl
<< " num_shrink: " << num_shrink << " num_shrink: " << num_shrink
<< std::endl << std::endl

View File

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

View File

@@ -23,7 +23,6 @@
using boost::timer::cpu_timer; using boost::timer::cpu_timer;
using boost::timer::cpu_times; using boost::timer::cpu_times;
using boost::timer::nanosecond_type; using boost::timer::nanosecond_type;
using namespace boost::container;
#ifdef NDEBUG #ifdef NDEBUG
static const std::size_t NElements = 1000; 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; std::cout << "----------------------------------------------" << '\n' << std::endl;
} }
vector<int> sorted_unique_range_int; boost::container::vector<int> sorted_unique_range_int;
vector<int> sorted_range_int; boost::container::vector<int> sorted_range_int;
vector<int> random_unique_range_int; boost::container::vector<int> random_unique_range_int;
vector<int> random_range_int; boost::container::vector<int> random_range_int;
void fill_range_ints() 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()); std::random_shuffle(random_unique_range_int.begin(), random_unique_range_int.end());
} }
vector<string> sorted_unique_range_string; boost::container::vector<boost::container::string> sorted_unique_range_string;
vector<string> sorted_range_string; boost::container::vector<boost::container::string> sorted_range_string;
vector<string> random_unique_range_string; boost::container::vector<boost::container::string> random_unique_range_string;
vector<string> random_range_string; boost::container::vector<boost::container::string> random_range_string;
void fill_range_strings() void fill_range_strings()
{ {
string model_s; boost::container::string model_s;
model_s.append(sizeof(string), '*'); model_s.append(sizeof(boost::container::string), '*');
//sorted_unique_range_int //sorted_unique_range_int
sorted_unique_range_string.resize(NElements); sorted_unique_range_string.resize(NElements);
@@ -111,7 +110,7 @@ struct range_provider;
template<> template<>
struct range_provider<int> struct range_provider<int>
{ {
typedef vector<int> type; typedef boost::container::vector<int> type;
static type &sorted_unique() static type &sorted_unique()
{ return sorted_unique_range_int; } { return sorted_unique_range_int; }
@@ -127,9 +126,9 @@ struct range_provider<int>
}; };
template<> 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() static type &sorted_unique()
{ return sorted_unique_range_string; } { return sorted_unique_range_string; }
@@ -145,7 +144,7 @@ struct range_provider<string>
}; };
template<typename C> 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; 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> 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; 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> 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; cpu_timer ur_timer,r_timer;
ur_timer.stop();r_timer.stop(); 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> 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; std::size_t end_count = 0;
for(std::size_t i = 0, max = iterators.size(); i != max; ++i){ 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> 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){ for(std::size_t i = 0, max = iterator_pairs.size(); i != max; ++i){
if(iterator_pairs[i].first == iterator_pairs[i].second) 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> 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; 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; cpu_timer total_time;
total_time.resume(); total_time.resume();
vector<typename C::iterator> v_it(NElements); boost::container::vector<typename C::iterator> v_it(NElements);
vector< std::pair<typename C::iterator, typename C::iterator> > v_itp(NElements); boost::container::vector< std::pair<typename C::iterator, typename C::iterator> > v_itp(NElements);
for(std::size_t i = 0; i != NIter; ++i){ for(std::size_t i = 0; i != NIter; ++i){
//Find //Find
@@ -348,7 +351,7 @@ cpu_times search_time(vector<typename C::value_type> &unique_range, const char *
} }
template<typename C> 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; cpu_timer sur_timer,sur_opt_timer;
sur_timer.stop();sur_opt_timer.stop(); 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 "bench_set.hpp"
#include <boost/container/set.hpp>
#include <boost/container/allocator.hpp>
int main() int main()
{ {
@@ -19,7 +19,7 @@ int main()
fill_range_ints(); fill_range_ints();
fill_range_strings(); fill_range_strings();
//set<..., allocator_v2> vs. set //set<..., version_2> vs. set
launch_tests< set<int, std::less<int>, allocator<int> >, set<int> > launch_tests< set<int, std::less<int>, allocator<int> >, set<int> >
("set<int, ..., allocator<int>", "set<int>"); ("set<int, ..., allocator<int>", "set<int>");
launch_tests< set<string, std::less<string>, allocator<string> >, set<string> > 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/config_begin.hpp>
#include <boost/container/detail/workaround.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 #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/iterator.hpp>
#include <boost/container/detail/iterators.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 <boost/move/adl_move_swap.hpp> //adl_move_swap
#include "varray_util.hpp" #include "varray_util.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/integer.hpp> #include <boost/static_assert.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>
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
#include <stdexcept> #include <stdexcept>
@@ -84,17 +85,17 @@ struct def
//! //!
//! This strategy defines the same types that are defined in the Allocator. //! This strategy defines the same types that are defined in the Allocator.
//! //!
//! @tparam A The Allocator which will be adapted. //! @tparam Allocator The Allocator which will be adapted.
template <typename A> template <typename Allocator>
struct allocator_adaptor struct allocator_adaptor
{ {
typedef typename A::value_type value_type; typedef typename Allocator::value_type value_type;
typedef typename A::size_type size_type; typedef typename Allocator::size_type size_type;
typedef typename A::difference_type difference_type; typedef typename Allocator::difference_type difference_type;
typedef typename A::pointer pointer; typedef typename Allocator::pointer pointer;
typedef typename A::const_pointer const_pointer; typedef typename Allocator::const_pointer const_pointer;
typedef typename A::reference reference; typedef typename Allocator::reference reference;
typedef typename A::const_reference const_reference; typedef typename Allocator::const_reference const_reference;
static void allocate_failed() static void allocate_failed()
{ {
@@ -176,9 +177,9 @@ struct varray_traits
typedef varray_error_handler error_handler; typedef varray_error_handler error_handler;
typedef boost::false_type use_memop_in_swap_and_move; typedef false_type use_memop_in_swap_and_move;
typedef boost::false_type use_optimized_swap; typedef false_type use_optimized_swap;
typedef boost::false_type disable_trivial_init; typedef false_type disable_trivial_init;
}; };
/** /**
@@ -220,18 +221,10 @@ class varray
> vt; > vt;
typedef typename vt::error_handler errh; typedef typename vt::error_handler errh;
typedef typename aligned_storage<
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<
sizeof(Value[Capacity]), sizeof(Value[Capacity]),
boost::alignment_of<Value[Capacity]>::value boost::container::container_detail::alignment_of<Value[Capacity]>::value
> aligned_storage_type; >::type aligned_storage_type;
template <typename V, std::size_t C, typename S> template <typename V, std::size_t C, typename S>
friend class varray; friend class varray;
@@ -1004,7 +997,7 @@ public:
} }
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE) #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> //! @pre <tt>size() < capacity()</tt>
//! //!
//! @brief Inserts a Value constructed with //! @brief Inserts a Value constructed with
@@ -1075,8 +1068,9 @@ public:
++m_size; // update end ++m_size; // update end
sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; typename aligned_storage
value_type * val_p = static_cast<value_type *>(temp_storage.address()); <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::construct(dti(), val_p, ::boost::forward<Args>(args)...); // may throw
sv::scoped_destructor<value_type> d(val_p); sv::scoped_destructor<value_type> d(val_p);
sv::assign(position, ::boost::move(*val_p)); // may throw sv::assign(position, ::boost::move(*val_p)); // may throw
@@ -1085,63 +1079,51 @@ public:
return position; 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) \ #define BOOST_CONTAINER_VARRAY_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ void emplace_back(BOOST_MOVE_UREF##N)\
{ \ {\
typedef typename vt::disable_trivial_init dti; \ typedef typename vt::disable_trivial_init dti;\
\ errh::check_capacity(*this, m_size + 1);/*may throw*/\
errh::check_capacity(*this, m_size + 1); /*may throw*/\ \
\ namespace sv = varray_detail;\
namespace sv = varray_detail; \ sv::construct(dti(), this->end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
sv::construct(dti(), this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\ ++m_size; /*update end*/\
++m_size; /*update end*/ \ }\
} \ \
// BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) iterator emplace(iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
#include BOOST_PP_LOCAL_ITERATE() {\
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) \ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_CONTAINER_DOXYGEN_INVOKED
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 // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
//! @brief Removes all elements from the container. //! @brief Removes all elements from the container.
@@ -1321,7 +1303,7 @@ public:
//! Constant O(1). //! Constant O(1).
Value * data() 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. //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
@@ -1334,7 +1316,7 @@ public:
//! Constant O(1). //! Constant O(1).
const Value * data() const const Value * data() const
{ {
return boost::addressof(*(this->ptr())); return (addressof)(*(this->ptr()));
} }
@@ -1528,7 +1510,7 @@ private:
// @par Complexity // @par Complexity
// Linear O(N). // Linear O(N).
template <std::size_t C, typename S> 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); ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
m_size = other.m_size; m_size = other.m_size;
@@ -1540,7 +1522,7 @@ private:
// @par Complexity // @par Complexity
// Linear O(N). // Linear O(N).
template <std::size_t C, typename S> 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; namespace sv = varray_detail;
sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
@@ -1552,7 +1534,7 @@ private:
// @par Complexity // @par Complexity
// Linear O(N). // Linear O(N).
template <std::size_t C, typename S> 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(); this->clear();
@@ -1566,7 +1548,7 @@ private:
// @par Complexity // @par Complexity
// Linear O(N). // Linear O(N).
template <std::size_t C, typename S> 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; namespace sv = varray_detail;
if ( m_size <= static_cast<size_type>(other.size()) ) if ( m_size <= static_cast<size_type>(other.size()) )
@@ -1588,18 +1570,18 @@ private:
// @par Complexity // @par Complexity
// Linear O(N). // Linear O(N).
template <std::size_t C, typename S> 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 typedef typename
boost::mpl::if_c< if_c<
Capacity < C, Capacity < C,
aligned_storage_type, aligned_storage_type,
typename varray<value_type, C, S>::aligned_storage_type typename varray<value_type, C, S>::aligned_storage_type
>::type >::type
storage_type; storage_type;
storage_type temp; storage_type temp_storage;
Value * temp_ptr = reinterpret_cast<Value*>(temp.address()); value_type * temp_ptr = static_cast<value_type*>(static_cast<void*>(&temp_storage));
::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size()); ::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
::memcpy(this->data(), other.data(), sizeof(Value) * other.size()); ::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
@@ -1614,7 +1596,7 @@ private:
// @par Complexity // @par Complexity
// Linear O(N). // Linear O(N).
template <std::size_t C, typename S> 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; namespace sv = varray_detail;
@@ -1632,22 +1614,21 @@ private:
// Nothing. // Nothing.
// @par Complexity // @par Complexity
// Linear O(N). // 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)); //BOOST_ASSERT_MSG(boost::container::iterator_distance(first_sm, last_sm) <= boost::container::iterator_distance(first_la, last_la));
namespace sv = varray_detail; namespace sv = varray_detail;
for (; first_sm != last_sm ; ++first_sm, ++first_la) for (; first_sm != last_sm ; ++first_sm, ++first_la)
{ {
boost::aligned_storage< typename aligned_storage<
sizeof(value_type), sizeof(value_type),
boost::alignment_of<value_type>::value alignment_of<value_type>::value
> temp_storage; >::type temp_storage;
value_type * temp_ptr = reinterpret_cast<value_type*>(temp_storage.address()); value_type * temp_ptr = static_cast<value_type*>(static_cast<void*>(&temp_storage));
::memcpy(temp_ptr, (addressof)(*first_sm), sizeof(value_type));
::memcpy(temp_ptr, boost::addressof(*first_sm), sizeof(value_type)); ::memcpy((addressof)(*first_sm), (addressof)(*first_la), sizeof(value_type));
::memcpy(boost::addressof(*first_sm), boost::addressof(*first_la), sizeof(value_type)); ::memcpy((addressof)(*first_la), temp_ptr, sizeof(value_type));
::memcpy(boost::addressof(*first_la), temp_ptr, sizeof(value_type));
} }
::memcpy(first_sm, first_la, sizeof(value_type) * boost::container::iterator_distance(first_la, last_la)); ::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. // If Value's move constructor or move assignment throws.
// @par Complexity // @par Complexity
// Linear O(N). // 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)); //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() pointer ptr()
{ {
return pointer(static_cast<Value*>(m_storage.address())); return pointer(static_cast<Value*>(static_cast<void*>(&m_storage)));
} }
const_pointer ptr() const 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; size_type m_size;
@@ -2091,8 +2072,8 @@ public:
} }
// nothrow // nothrow
Value * data() { return boost::addressof(*(this->ptr())); } Value * data() { return (addressof)(*(this->ptr())); }
const Value * data() const { return boost::addressof(*(this->ptr())); } const Value * data() const { return (addressof)(*(this->ptr())); }
// nothrow // nothrow
iterator begin() { return this->ptr(); } iterator begin() { return this->ptr(); }

View File

@@ -17,26 +17,20 @@
#include <memory> #include <memory>
#include <limits> #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/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/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? // 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 boost { namespace container { namespace varray_detail {
namespace bcd = ::boost::container::container_detail;
template <typename I> 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) #if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
template <typename Pointer> template <typename Pointer>
struct are_elements_contiguous< struct are_elements_contiguous<
boost::container::container_detail::vector_const_iterator<Pointer> bcd::vector_const_iterator<Pointer>
> : boost::true_type > : bcd::true_type
{}; {};
template <typename Pointer> template <typename Pointer>
struct are_elements_contiguous< struct are_elements_contiguous<
boost::container::container_detail::vector_iterator<Pointer> bcd::vector_iterator<Pointer>
> : boost::true_type > : bcd::true_type
{}; {};
#if defined(BOOST_DINKUMWARE_STDLIB) #if defined(BOOST_DINKUMWARE_STDLIB)
@@ -70,21 +66,21 @@ struct are_elements_contiguous<
template <typename T> template <typename T>
struct are_elements_contiguous< struct are_elements_contiguous<
std::_Vector_const_iterator<T> std::_Vector_const_iterator<T>
> : boost::true_type > : bcd::true_type
{}; {};
template <typename T> template <typename T>
struct are_elements_contiguous< struct are_elements_contiguous<
std::_Vector_iterator<T> std::_Vector_iterator<T>
> : boost::true_type > : bcd::true_type
{}; {};
#elif defined(BOOST_GNU_STDLIB) #elif defined(BOOST_GNU_STDLIB)
template <typename P, typename T, typename A> template <typename P, typename T, typename Allocator>
struct are_elements_contiguous< struct are_elements_contiguous<
__gnu_cxx::__normal_iterator<P, std::vector<T, A> > __gnu_cxx::__normal_iterator<P, std::vector<T, Allocator> >
> : boost::true_type > : bcd::true_type
{}; {};
#elif defined(_LIBCPP_VERSION) #elif defined(_LIBCPP_VERSION)
@@ -93,7 +89,7 @@ struct are_elements_contiguous<
//template <typename P> //template <typename P>
//struct are_elements_contiguous< //struct are_elements_contiguous<
// __wrap_iter<P> // __wrap_iter<P>
//> : boost::true_type //> : bcd::true_type
//{}; //{};
#else // OTHER_STDLIB #else // OTHER_STDLIB
@@ -104,46 +100,40 @@ struct are_elements_contiguous<
#endif // BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS #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> template <typename I, typename O>
struct are_corresponding : struct are_corresponding :
::boost::mpl::and_< bcd::bool_<
::boost::is_same< bcd::is_same<
::boost::remove_const< bcd::remove_const<
typename ::boost::container::iterator_traits<I>::value_type typename ::boost::container::iterator_traits<I>::value_type
>, >,
::boost::remove_const< bcd::remove_const<
typename ::boost::container::iterator_traits<O>::value_type typename ::boost::container::iterator_traits<O>::value_type
> >
>, >::value &&
are_elements_contiguous<I>, are_elements_contiguous<I>::value &&
are_elements_contiguous<O> are_elements_contiguous<O>::value
> >
{}; {};
template <typename I, typename V> template <typename I, typename V>
struct is_corresponding_value : struct is_corresponding_value :
::boost::is_same< bcd::bool_<
::boost::remove_const< bcd::is_same<
typename ::boost::container::iterator_traits<I>::value_type bcd::remove_const<typename ::boost::container::iterator_traits<I>::value_type>,
>, bcd::remove_const<V>
::boost::remove_const<V> >::value
> >
{}; {};
// destroy(I, I) // destroy(I, I)
template <typename I> template <typename I>
void destroy_dispatch(I /*first*/, I /*last*/, void destroy_dispatch(I /*first*/, I /*last*/, bcd::true_type const& /*is_trivially_destructible*/)
boost::true_type const& /*has_trivial_destructor*/)
{} {}
template <typename I> template <typename I>
void destroy_dispatch(I first, I last, void destroy_dispatch(I first, I last, bcd::false_type const& /*is_trivially_destructible*/)
boost::false_type const& /*has_trivial_destructor*/)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
for ( ; first != last ; ++first ) for ( ; first != last ; ++first )
@@ -154,19 +144,19 @@ template <typename I>
void destroy(I first, I last) void destroy(I first, I last)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; 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) // destroy(I)
template <typename I> template <typename I>
void destroy_dispatch(I /*pos*/, void destroy_dispatch(I /*pos*/,
boost::true_type const& /*has_trivial_destructor*/) bcd::true_type const& /*is_trivially_destructible*/)
{} {}
template <typename I> template <typename I>
void destroy_dispatch(I pos, 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; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
pos->~value_type(); pos->~value_type();
@@ -176,24 +166,22 @@ template <typename I>
void destroy(I pos) void destroy(I pos)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; 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) // copy(I, I, O)
template <typename I, typename O> template <typename I, typename O>
inline O copy_dispatch(I first, I last, O dst, inline O copy_dispatch(I first, I last, O dst, bcd::true_type const& /*use_memmove*/)
boost::mpl::bool_<true> const& /*use_memmove*/)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last); 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; return dst + d;
} }
template <typename I, typename O> template <typename I, typename O>
inline O copy_dispatch(I first, I last, O dst, inline O copy_dispatch(I first, I last, O dst, bcd::false_type const& /*use_memmove*/)
boost::mpl::bool_<false> const& /*use_memmove*/)
{ {
return std::copy(first, last, dst); // may throw 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> template <typename I, typename O>
inline O copy(I first, I last, O dst) inline O copy(I first, I last, O dst)
{ {
typedef typename typedef bcd::bool_
::boost::mpl::and_< < are_corresponding<I, O>::value &&
are_corresponding<I, O>, bcd::is_trivially_copy_assignable<typename ::boost::container::iterator_traits<O>::value_type>::value
::boost::has_trivial_assign< > use_memmove;
typename ::boost::container::iterator_traits<O>::value_type
>
>::type
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) // uninitialized_copy(I, I, O)
@@ -218,18 +202,18 @@ inline O copy(I first, I last, O dst)
template <typename I, typename O> template <typename I, typename O>
inline inline
O uninitialized_copy_dispatch(I first, I last, O dst, 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; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last); 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; return dst + d;
} }
template <typename I, typename F> template <typename I, typename F>
inline inline
F uninitialized_copy_dispatch(I first, I last, F dst, 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 return std::uninitialized_copy(first, last, dst); // may throw
} }
@@ -238,16 +222,11 @@ template <typename I, typename F>
inline inline
F uninitialized_copy(I first, I last, F dst) F uninitialized_copy(I first, I last, F dst)
{ {
typedef typename typedef bcd::bool_
::boost::mpl::and_< < are_corresponding<I, F>::value &&
are_corresponding<I, F>, bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<F>::value_type>::value
::boost::has_trivial_copy< > use_memcpy;
typename ::boost::container::iterator_traits<F>::value_type return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
>
>::type
use_memcpy;
return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
} }
// uninitialized_move(I, I, O) // uninitialized_move(I, I, O)
@@ -255,18 +234,18 @@ F uninitialized_copy(I first, I last, F dst)
template <typename I, typename O> template <typename I, typename O>
inline inline
O uninitialized_move_dispatch(I first, I last, O dst, 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; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last); 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; return dst + d;
} }
template <typename I, typename O> template <typename I, typename O>
inline inline
O uninitialized_move_dispatch(I first, I last, O dst, 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 //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; typedef typename boost::container::iterator_traits<O>::value_type value_type;
for (; first != last; ++first, ++o ) 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(...) BOOST_CATCH(...)
{ {
@@ -292,15 +271,10 @@ template <typename I, typename O>
inline inline
O uninitialized_move(I first, I last, O dst) O uninitialized_move(I first, I last, O dst)
{ {
typedef typename typedef bcd::bool_
::boost::mpl::and_< < are_corresponding<I, O>::value &&
are_corresponding<I, O>, bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<O>::value_type>::value
::boost::has_trivial_copy< > use_memcpy;
typename ::boost::container::iterator_traits<O>::value_type
>
>::type
use_memcpy;
return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw 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> template <typename I, typename O>
inline inline
O move_dispatch(I first, I last, O dst, 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; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last); 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; return dst + d;
} }
template <typename I, typename O> template <typename I, typename O>
inline inline
O move_dispatch(I first, I last, O dst, 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 return boost::move(first, last, dst); // may throw
} }
@@ -331,15 +305,10 @@ template <typename I, typename O>
inline inline
O move(I first, I last, O dst) O move(I first, I last, O dst)
{ {
typedef typename typedef bcd::bool_
::boost::mpl::and_< < are_corresponding<I, O>::value &&
are_corresponding<I, O>, bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<O>::value_type>::value
::boost::has_trivial_assign< > use_memmove;
typename ::boost::container::iterator_traits<O>::value_type
>
>::type
use_memmove;
return move_dispatch(first, last, dst, use_memmove()); // may throw 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> template <typename BDI, typename BDO>
inline inline
BDO move_backward_dispatch(BDI first, BDI last, BDO dst, 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; typedef typename ::boost::container::iterator_traits<BDI>::value_type value_type;
const std::size_t d = boost::container::iterator_distance(first, last); const std::size_t d = boost::container::iterator_distance(first, last);
BDO foo(dst - d); 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; return foo;
} }
template <typename BDI, typename BDO> template <typename BDI, typename BDO>
inline inline
BDO move_backward_dispatch(BDI first, BDI last, BDO dst, 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 return boost::move_backward(first, last, dst); // may throw
} }
@@ -369,29 +338,21 @@ template <typename BDI, typename BDO>
inline inline
BDO move_backward(BDI first, BDI last, BDO dst) BDO move_backward(BDI first, BDI last, BDO dst)
{ {
typedef typename typedef bcd::bool_
::boost::mpl::and_< < are_corresponding<BDI, BDO>::value &&
are_corresponding<BDI, BDO>, bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<BDO>::value_type>::value
::boost::has_trivial_assign< > use_memmove;
typename ::boost::container::iterator_traits<BDO>::value_type return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
>
>::type
use_memmove;
return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
} }
template <typename T> template <typename T>
struct has_nothrow_move : public struct has_nothrow_move : public
::boost::mpl::or_< bcd::bool_<
boost::mpl::bool_< ::boost::has_nothrow_move<
::boost::has_nothrow_move< typename bcd::remove_const<T>::type
typename ::boost::remove_const<T>::type >::value
>::value ||
>, ::boost::has_nothrow_move<T>::value
boost::mpl::bool_<
::boost::has_nothrow_move<T>::value
>
> >
{}; {};
@@ -399,21 +360,21 @@ struct has_nothrow_move : public
template <typename I, typename O> template <typename I, typename O>
inline 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); } { return uninitialized_move(first, last, dst); }
template <typename I, typename O> template <typename I, typename O>
inline 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); } { return uninitialized_copy(first, last, dst); }
template <typename I, typename O> template <typename I, typename O>
inline inline
O uninitialized_move_if_noexcept(I first, I last, O dst) 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 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 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> template <typename I, typename O>
inline 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); } { return move(first, last, dst); }
template <typename I, typename O> template <typename I, typename O>
inline 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); } { return copy(first, last, dst); }
template <typename I, typename O> template <typename I, typename O>
inline inline
O move_if_noexcept(I first, I last, O dst) 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 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 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> template <typename I>
inline inline
void uninitialized_fill_dispatch(I first, I last, void uninitialized_fill_dispatch(I first, I last,
boost::true_type const& /*has_trivial_constructor*/, bcd::true_type const& /*is_trivially_default_constructible*/,
boost::true_type const& /*disable_trivial_init*/) bcd::true_type const& /*disable_trivial_init*/)
{} {}
template <typename I> template <typename I>
inline inline
void uninitialized_fill_dispatch(I first, I last, void uninitialized_fill_dispatch(I first, I last,
boost::true_type const& /*has_trivial_constructor*/, bcd::true_type const& /*is_trivially_default_constructible*/,
boost::false_type const& /*disable_trivial_init*/) bcd::false_type const& /*disable_trivial_init*/)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
for ( ; first != last ; ++first ) for ( ; first != last ; ++first )
new (boost::addressof(*first)) value_type(); new (boost::container::container_detail::addressof(*first)) value_type();
} }
template <typename I, typename DisableTrivialInit> template <typename I, typename DisableTrivialInit>
inline inline
void uninitialized_fill_dispatch(I first, I last, 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*/) DisableTrivialInit const& /*not_used*/)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; 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 BOOST_TRY
{ {
for ( ; it != last ; ++it ) 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(...) BOOST_CATCH(...)
{ {
@@ -488,22 +449,24 @@ inline
void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init) void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; 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) // construct(I)
template <typename I> template <typename I>
inline 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> template <typename I>
inline 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; 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> template <typename DisableTrivialInit, typename I>
@@ -511,11 +474,10 @@ inline
void construct(DisableTrivialInit const&, I pos) void construct(DisableTrivialInit const&, I pos)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type value_type; typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
typedef typename ::boost::mpl::and_< bcd::bool_<
boost::has_trivial_constructor<value_type>, bcd::is_trivially_default_constructible<value_type>::value &&
DisableTrivialInit DisableTrivialInit::value
>::type dont_init; > dont_init;
construct_dispatch(dont_init(), pos); // may throw construct_dispatch(dont_init(), pos); // may throw
} }
@@ -523,34 +485,29 @@ void construct(DisableTrivialInit const&, I pos)
template <typename I, typename V> template <typename I, typename V>
inline inline
void construct_dispatch(I pos, V const& v, void construct_dispatch(I pos, V const& v, bcd::true_type const& /*use_memcpy*/)
boost::mpl::bool_<true> 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> template <typename I, typename P>
inline inline
void construct_dispatch(I pos, P const& p, 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; 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> template <typename DisableTrivialInit, typename I, typename P>
inline inline
void construct(DisableTrivialInit const&, void construct(DisableTrivialInit const&, I pos, P const& p)
I pos, P const& p)
{ {
typedef typename typedef bcd::bool_
::boost::mpl::and_< < is_corresponding_value<I, P>::value &&
is_corresponding_value<I, P>, bcd::is_trivially_copy_constructible<P>::value
::boost::has_trivial_copy<P> > use_memcpy;
>::type construct_dispatch(pos, p, use_memcpy()); // may throw
use_memcpy;
construct_dispatch(pos, p, use_memcpy()); // may throw
} }
// Needed by push_back(V &&) // Needed by push_back(V &&)
@@ -560,13 +517,13 @@ inline
void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p) void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type V; 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() // Needed by emplace_back() and emplace()
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_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> template <typename DisableTrivialInit, typename I, class ...Args>
inline inline
@@ -575,33 +532,27 @@ void construct(DisableTrivialInit const&,
BOOST_FWD_REF(Args) ...args) BOOST_FWD_REF(Args) ...args)
{ {
typedef typename ::boost::container::iterator_traits<I>::value_type V; 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 const& p0
// !BOOST_NO_RVALUE_REFERENCES -> P0 && p0 // !BOOST_NO_RVALUE_REFERENCES -> P0 && p0
// which means that version with one parameter may take V const& v // which means that version with one parameter may take V const& v
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE(N) \
template <typename DisableTrivialInit, typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \ template <typename DisableTrivialInit, typename I BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
inline \ inline void construct(DisableTrivialInit const&, I pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
void construct(DisableTrivialInit const&, \ {\
I pos, \ typedef typename ::boost::container::iterator_traits<I>::value_type V;\
BOOST_CONTAINER_PP_PARAM(P, p) \ new (static_cast<void*>(boost::container::container_detail::addressof(*pos)))\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ V(boost::container::container_detail::addressof(*pos) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/\
{ \ }
typedef typename ::boost::container::iterator_traits<I>::value_type V; \ BOOST_MOVE_ITERATE_2TO9(BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE)
new \ #undef BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE
(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()
#endif // !BOOST_NO_VARIADIC_TEMPLATES #endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
// assign(I, V) // assign(I, V)
@@ -609,15 +560,15 @@ void construct(DisableTrivialInit const&,
template <typename I, typename V> template <typename I, typename V>
inline inline
void assign_dispatch(I pos, V const& v, 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> template <typename I, typename V>
inline inline
void assign_dispatch(I pos, V const& v, 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 *pos = v; // may throw
} }
@@ -626,14 +577,11 @@ template <typename I, typename V>
inline inline
void assign(I pos, V const& v) void assign(I pos, V const& v)
{ {
typedef typename typedef bcd::bool_
::boost::mpl::and_< < is_corresponding_value<I, V>::value &&
is_corresponding_value<I, V>, bcd::is_trivially_copy_assignable<V>::value
::boost::has_trivial_assign<V> > use_memcpy;
>::type assign_dispatch(pos, v, use_memcpy()); // may throw
use_memcpy;
assign_dispatch(pos, v, use_memcpy()); // may throw
} }
template <typename I, typename V> template <typename I, typename V>

View File

@@ -27,7 +27,7 @@ doxygen autodoc
<doxygen:param>MACRO_EXPANSION=YES <doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\ <doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\ \"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
\"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\ \"BOOST_MOVE_IMPDEF(T)=implementation_defined\" \\
\"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\ \"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\
\"BOOST_CONTAINER_NOEXCEPT=noexcept\" \\ \"BOOST_CONTAINER_NOEXCEPT=noexcept\" \\
\"BOOST_CONTAINER_NOEXCEPT_IF(T)=noexcept(T)\" \\ \"BOOST_CONTAINER_NOEXCEPT_IF(T)=noexcept(T)\" \\
@@ -41,6 +41,8 @@ doxygen autodoc
\"BOOST_CONTAINER_DOC1ST(T1, T2)=T1\" \\ \"BOOST_CONTAINER_DOC1ST(T1, T2)=T1\" \\
\"BOOST_CONTAINER_DOCIGN(T) \"\\ \"BOOST_CONTAINER_DOCIGN(T) \"\\
\"BOOST_CONTAINER_DOCONLY(T) T\"\\ \"BOOST_CONTAINER_DOCONLY(T) T\"\\
\"BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE=\"\\
\"BOOST_CONTAINER_SCOPEDALLOC_ALLINNER=InnerAllocs...\"\\
" "
<xsl:param>"boost.doxygen.reftitle=Boost.Container Header Reference" <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 For compilers with variadic templates, [*Boost.Container] supports placement insertion
(`emplace`, ...) functions from C++11. For those compilers without variadic templates (`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 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] [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 container's elements, and, if the elements themselves are containers, the third allocator is passed to the
elements' elements, and so on. 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 to C++03 compilers]. Due to C++03 limitations, in those compilers
the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions 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] will be based on traits ([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix]
@@ -791,12 +792,12 @@ will be used to detect if the allocator must be propagated with suffix or prefix
[endsect] [endsect]
[section:insertion_hints Insertion hints in associative containers and preserving [section:insertion_hints Insertion hints in associative containers and preserving
insertion ordering for elements with equivalent keys] insertion ordering for elements with equivalent keys]
[@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233 LWG Issue #233] corrected a defect [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233 LWG Issue #233] corrected a defect
in C++98 and specified how equivalent keys were to be inserted in associative containers. [*Boost.Container] in C++98 and specified how equivalent keys were to be inserted in associative containers. [*Boost.Container]
implements the C++11 changes that were specified in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html N1780 implements the C++11 changes that were specified in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html N1780
['Comments on LWG issue 233: Insertion hints in associative containers]]: ['Comments on LWG issue 233: Insertion hints in associative containers]]:
* `a_eq.insert(t)`: If a range containing elements equivalent to t exists in a_eq, t is inserted at the end of that range. * `a_eq.insert(t)`: If a range containing elements equivalent to t exists in a_eq, t is inserted at the end of that range.
@@ -883,7 +884,7 @@ to detect a reference to an inserted element and an additional copy in that case
references to already inserted objects are not used. Note that equivalent functions taking rvalue references or references to already inserted objects are not used. Note that equivalent functions taking rvalue references or
iterator ranges require elements not already inserted in the container. iterator ranges require elements not already inserted in the container.
[*Boost.Container] prioritizes performance and has not implemented the NAD resolution: [*Boost.Container] prioritizes performance and has not implemented the NAD resolution:
in functions that might modify the argument, the library requires references to elements not stored in functions that might modify the argument, the library requires references to elements not stored
in the container. Using references to inserted elements yields to undefined behaviour (although in debug mode, this in the container. Using references to inserted elements yields to undefined behaviour (although in debug mode, this
precondition violation could be notified via BOOST_ASSERT). precondition violation could be notified via BOOST_ASSERT).
@@ -946,7 +947,7 @@ member object and member function pointers) to be initializable using `std::mems
Most platforms are compatible with this initialization, but in case this initialization is not desired the Most platforms are compatible with this initialization, but in case this initialization is not desired the
user can `#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO` before including library headers. user can `#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO` before including library headers.
If neither `BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO` nor If neither `BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO` nor
`BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO` is defined [*Boost.Container] also considers POD `BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO` is defined [*Boost.Container] also considers POD
types to be value initializable via `std::memset` with value zero. types to be value initializable via `std::memset` with value zero.
@@ -1080,10 +1081,18 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes] [section:release_notes Release Notes]
[section:release_notes_boost_1_58_00 Boost 1.58 Release] [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`). * Added `nth` and `index_of` functions to containers with random-access iterators (except `basic_string`).
* Fixed bugs: * Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/10790 Trac #10790 (['long long errors from container"])]. * [@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"])]. * [@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] [endsect]

View File

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

View File

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

View File

@@ -13,7 +13,6 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP #ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
#define 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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp> #include <boost/container/container_fwd.hpp>
#include <boost/container/detail/memory_util.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/placement_new.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/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/mpl.hpp>
// move
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp> #include <boost/move/detail/fwd_macros.hpp>
#endif #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 boost {
namespace container { namespace container {
namespace allocator_traits_detail { 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 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -50,7 +76,7 @@ namespace container_detail {
//workaround needed for C++03 compilers with no construct() //workaround needed for C++03 compilers with no construct()
//supporting rvalue references //supporting rvalue references
template<class A> template<class Allocator>
struct is_std_allocator struct is_std_allocator
{ static const bool value = false; }; { static const bool value = false; };
@@ -59,11 +85,11 @@ struct is_std_allocator< std::allocator<T> >
{ static const bool value = true; }; { static const bool value = true; };
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer) 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(reference)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(void_pointer) BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_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(size_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_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. //! 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 //! This class is a C++03-compatible implementation of std::allocator_traits
template <typename Alloc> template <typename Allocator>
struct allocator_traits struct allocator_traits
{ {
//allocator_type //allocator_type
typedef Alloc allocator_type; typedef Allocator allocator_type;
//value_type //value_type
typedef typename Alloc::value_type value_type; typedef typename allocator_type::value_type value_type;
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #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; 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; typedef see_documentation const_pointer;
//! Non-standard extension //! 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; typedef see_documentation reference;
//! Non-standard extension //! 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; 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; 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; 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; 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; typedef see_documentation size_type;
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant //! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type
//! type with internal constant static member <code>value</code> == false. //! with an internal constant static boolean member <code>value</code> == false.
typedef see_documentation propagate_on_container_copy_assignment; typedef see_documentation propagate_on_container_copy_assignment;
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant //! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise otherwise a type
//! type with internal constant static member <code>value</code> == false. //! with an internal constant static boolean member <code>value</code> == false.
typedef see_documentation propagate_on_container_move_assignment; typedef see_documentation propagate_on_container_move_assignment;
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant //! Allocator::propagate_on_container_swap if such a type exists, otherwise an otherwise a type
//! type with internal constant static member <code>value</code> == false. //! with an internal constant static boolean member <code>value</code> == false.
typedef see_documentation propagate_on_container_swap; typedef see_documentation propagate_on_container_swap;
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args> //! Defines an allocator: Allocator::rebind<T>::other if such a type exists; otherwise, Allocator<T, Args>
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or //! 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. //! 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 //! 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> >; template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. //! 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> template <class T>
struct portable_rebind_alloc struct portable_rebind_alloc
{ typedef see_documentation type; }; { typedef see_documentation type; };
#else #else
//pointer //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, value_type*)
pointer; pointer;
//const_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 const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const value_type>) rebind_pointer<const value_type>)
const_pointer; const_pointer;
//reference //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, typename container_detail::unvoid<value_type>::type&)
reference; reference;
//const_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, const typename container_detail::unvoid<value_type>::type&)
const_reference; const_reference;
//void_pointer //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 void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<void>) rebind_pointer<void>)
void_pointer; void_pointer;
//const_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 const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const void>) rebind_pointer<const void>)
const_void_pointer; const_void_pointer;
//difference_type //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, std::ptrdiff_t)
difference_type; difference_type;
//size_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, std::size_t)
size_type; size_type;
//propagate_on_container_copy_assignment //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, container_detail::false_type)
propagate_on_container_copy_assignment; propagate_on_container_copy_assignment;
//propagate_on_container_move_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, container_detail::false_type)
propagate_on_container_move_assignment; propagate_on_container_move_assignment;
//propagate_on_container_swap //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, container_detail::false_type)
propagate_on_container_swap; propagate_on_container_swap;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//C++11 //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> >; template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
#else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) #else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//Some workaround for C++03 or C++11 compilers with no template aliases //Some workaround for C++03 or C++11 compilers with no template aliases
template <typename T> 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) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename... Args> template <typename... Args>
rebind_alloc(BOOST_FWD_REF(Args)... args) rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward<Args>(args)...) {}
: Base(boost::forward<Args>(args)...)
{}
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\
: Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \ //
{} \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC)
// #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
}; };
template <typename T> template <typename T>
struct rebind_traits 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) #endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T> template <class T>
struct portable_rebind_alloc 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 #endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: <code>a.allocate(n)</code> //! <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); } { return a.allocate(n); }
//! <b>Returns</b>: <code>a.deallocate(p, n)</code> //! <b>Returns</b>: <code>a.deallocate(p, n)</code>
//! //!
//! <b>Throws</b>: Nothing //! <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); } { a.deallocate(p, n); }
//! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed; //! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
//! otherwise, invokes <code>a.allocate(n)</code> //! 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:: const bool value = boost::container::container_detail::
has_member_function_callable_with_allocate 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; container_detail::bool_<value> flag;
return allocator_traits::priv_allocate(flag, a, n, p); 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; //! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
//! otherwise, invokes <code>p->~T()</code>. //! otherwise, invokes <code>p->~T()</code>.
template<class T> 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; typedef T* destroy_pointer;
const bool value = boost::container::container_detail:: const bool value = boost::container::container_detail::
has_member_function_callable_with_destroy has_member_function_callable_with_destroy
<Alloc, const destroy_pointer>::value; <Allocator, const destroy_pointer>::value;
container_detail::bool_<value> flag; container_detail::bool_<value> flag;
allocator_traits::priv_destroy(flag, a, p); allocator_traits::priv_destroy(flag, a, p);
} }
//! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise, //! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
//! <code>numeric_limits<size_type>::max()</code>. //! <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:: const bool value = allocator_traits_detail::has_max_size<Allocator, size_type (Allocator::*)() const>::value;
has_member_function_callable_with_max_size
<const Alloc>::value;
container_detail::bool_<value> flag; container_detail::bool_<value> flag;
return allocator_traits::priv_max_size(flag, a); return allocator_traits::priv_max_size(flag, a);
} }
@@ -273,20 +293,17 @@ struct allocator_traits
static static
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
typename container_detail::if_c typename container_detail::if_c
< boost::container::container_detail:: < allocator_traits_detail::has_select_on_container_copy_construction<Allocator, Allocator (Allocator::*)() const>::value
has_member_function_callable_with_select_on_container_copy_construction , Allocator
<const Alloc>::value , const Allocator &
, Alloc
, const Alloc &
>::type >::type
#else #else
Alloc Allocator
#endif #endif
select_on_container_copy_construction(const Alloc &a) select_on_container_copy_construction(const Allocator &a)
{ {
const bool value = boost::container::container_detail:: const bool value = allocator_traits_detail::has_select_on_container_copy_construction
has_member_function_callable_with_select_on_container_copy_construction <Allocator, Allocator (Allocator::*)() const>::value;
<const Alloc>::value;
container_detail::bool_<value> flag; container_detail::bool_<value> flag;
return allocator_traits::priv_select_on_container_copy_construction(flag, a); 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; //! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
//! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code> //! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
template <class T, class ...Args> 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)...); allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
} }
#endif #endif
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
private: 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); } { 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); } { return a.allocate(n); }
template<class T> 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); } { a.destroy(p); }
template<class T> 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; } { 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(); } { 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); } { 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(); } { 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; } { return a; }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class ...Args> 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:: const bool value = boost::container::container_detail::
has_member_function_callable_with_construct has_member_function_callable_with_construct
< Alloc, T*, Args... >::value; < Allocator, T*, Args... >::value;
container_detail::bool_<value> flag; 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> template<class T, class ...Args>
static void priv_construct(container_detail::true_type, Alloc &a, T *p, BOOST_FWD_REF(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)...); }
priv_construct_dispatch2(container_detail::false_type(), a, p, ::boost::forward<Args>(args)...);
}
template<class T, class ...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)...); } { a.construct( p, ::boost::forward<Args>(args)...); }
template<class T, class ...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)...); } { ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); }
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
public: public:
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ #define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \
static void construct(Alloc &a, T *p \ template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ \ {\
container_detail::bool_ \ container_detail::bool_<container_detail::is_std_allocator<Allocator>::value> flag;\
<container_detail::is_std_allocator<Alloc>::value> flag; \ (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
allocator_traits::priv_construct(flag, a, p \ }\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
// //
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
#include BOOST_PP_LOCAL_ITERATE() #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
private: private:
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \
static void priv_construct(container_detail::false_type, Alloc &a, T *p \ template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \ static void priv_construct(container_detail::false_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ \ {\
const bool value = \ const bool value = boost::container::container_detail::has_member_function_callable_with_construct\
boost::container::container_detail::has_member_function_callable_with_construct \ < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N>::value;\
< Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value; \ container_detail::bool_<value> flag;\
container_detail::bool_<value> flag; \ (priv_construct_dispatch_next)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
priv_construct_dispatch2(flag, a, p \ }\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ \
} \ 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)\
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ { (priv_construct_dispatch_next)(container_detail::false_type(), a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
static void priv_construct(container_detail::true_type, Alloc &a, T *p \ \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \ 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)\
priv_construct_dispatch2(container_detail::false_type(), a, p \ { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ \
} \ 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)\
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\
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_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL)
#include BOOST_PP_LOCAL_ITERATE() #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T> 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; } { ::new((void*)p) T; }
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)

View File

@@ -80,27 +80,30 @@ enum tree_type_enum
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template<class T>
class new_allocator;
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = new_allocator<T> >
class vector; class vector;
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = new_allocator<T> >
class stable_vector; class stable_vector;
template <class T, std::size_t Capacity> template <class T, std::size_t Capacity>
class static_vector; class static_vector;
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = new_allocator<T> >
class deque; class deque;
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = new_allocator<T> >
class list; class list;
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = new_allocator<T> >
class slist; class slist;
template<tree_type_enum TreeType, bool OptimizeSize> template<tree_type_enum TreeType, bool OptimizeSize>
@@ -110,67 +113,67 @@ typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<Key> ,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults > ,class Options = tree_assoc_defaults >
class set; class set;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<Key> ,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults > ,class Options = tree_assoc_defaults >
class multiset; class multiset;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,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 Options = tree_assoc_defaults >
class map; class map;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,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 Options = tree_assoc_defaults >
class multimap; class multimap;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<Key> > ,class Allocator = new_allocator<Key> >
class flat_set; class flat_set;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<Key> > ,class Allocator = new_allocator<Key> >
class flat_multiset; class flat_multiset;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<std::pair<Key, T> > > ,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_map; class flat_map;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<std::pair<Key, T> > > ,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_multimap; class flat_multimap;
template <class CharT template <class CharT
,class Traits = std::char_traits<CharT> ,class Traits = std::char_traits<CharT>
,class A = std::allocator<CharT> > ,class Allocator = new_allocator<CharT> >
class basic_string; class basic_string;
typedef basic_string typedef basic_string
<char <char
,std::char_traits<char> ,std::char_traits<char>
,std::allocator<char> > ,new_allocator<char> >
string; string;
typedef basic_string typedef basic_string
<wchar_t <wchar_t
,std::char_traits<wchar_t> ,std::char_traits<wchar_t>
,std::allocator<wchar_t> > ,new_allocator<wchar_t> >
wstring; wstring;
static const std::size_t ADP_nodes_per_block = 256u; 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. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DEQUE_HPP #ifndef BOOST_CONTAINER_DEQUE_HPP
#define BOOST_CONTAINER_DEQUE_HPP #define BOOST_CONTAINER_DEQUE_HPP
@@ -17,35 +16,39 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp> #include <boost/container/container_fwd.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp> #include <boost/container/throw_exception.hpp>
#include <boost/container/detail/iterator.hpp> // container/detail
#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>
#include <boost/container/detail/advanced_insert_int.hpp> #include <boost/container/detail/advanced_insert_int.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare #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> #include <boost/core/no_exceptions_support.hpp>
// std
#include <cstddef> #include <cstddef>
#include <memory> //std::allocator
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list> #include <initializer_list>
#endif #endif
@@ -54,20 +57,15 @@ namespace boost {
namespace container { namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A> template <class T, class Allocator>
class deque; class deque;
template <class T> template <class T>
struct deque_value_traits struct deque_value_traits
{ {
typedef T value_type; 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_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' // 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 // Deque base class. It has two purposes. First, its constructor
// and destructor allocate (but don't initialize) storage. This makes // and destructor allocate (but don't initialize) storage. This makes
// exception safety easier. // exception safety easier.
template <class A> template <class Allocator>
class deque_base class deque_base
{ {
BOOST_COPYABLE_AND_MOVABLE(deque_base) BOOST_COPYABLE_AND_MOVABLE(deque_base)
public: 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::value_type val_alloc_val;
typedef typename val_alloc_traits_type::pointer val_alloc_ptr; typedef typename val_alloc_traits_type::pointer val_alloc_ptr;
typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr; 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::const_pointer ptr_alloc_cptr;
typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref; typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref; 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 allocator_type stored_allocator_type;
typedef val_alloc_size size_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. //! 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 T The type of object that is stored in the deque
//! \tparam A The allocator used for all internal memory management //! \tparam Allocator The allocator used for all internal memory management
template <class T, class A = std::allocator<T> > template <class T, class Allocator = new_allocator<T> >
#else #else
template <class T, class A> template <class T, class Allocator>
#endif #endif
class deque : protected deque_base<A> class deque : protected deque_base<Allocator>
{ {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private: private:
typedef deque_base<A> Base; typedef deque_base<Allocator> Base;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public: public:
@@ -497,18 +495,18 @@ class deque : protected deque_base<A>
////////////////////////////////////////////// //////////////////////////////////////////////
typedef T value_type; typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; typedef BOOST_MOVE_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator; typedef BOOST_MOVE_IMPDEF(typename Base::iterator) iterator;
typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator; typedef BOOST_MOVE_IMPDEF(typename Base::const_iterator) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator; typedef BOOST_MOVE_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(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -517,7 +515,7 @@ class deque : protected deque_base<A>
typedef typename Base::ptr_alloc_ptr index_pointer; typedef typename Base::ptr_alloc_ptr index_pointer;
static size_type s_buffer_size() static size_type s_buffer_size()
{ return Base::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 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -556,7 +554,7 @@ class deque : protected deque_base<A>
explicit deque(size_type n) explicit deque(size_type n)
: Base(n, allocator_type()) : 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); proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
//deque_base will deallocate in case of exception... //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) deque(size_type n, default_init_t)
: Base(n, allocator_type()) : 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); proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
//deque_base will deallocate in case of exception... //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); this->priv_erase_last_n(len - new_size);
else{ else{
const size_type n = new_size - this->size(); 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); 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); this->priv_erase_last_n(len - new_size);
else{ else{
const size_type n = new_size - this->size(); 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); 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 //! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the beginning of the deque. //! 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 //! <b>Complexity</b>: Amortized constant time
template <class... Args> template <class... Args>
void emplace_front(Args&&... args) void emplace_front(BOOST_FWD_REF(Args)... args)
{ {
if(this->priv_push_front_simple_available()){ if(this->priv_push_front_simple_available()){
allocator_traits_type::construct allocator_traits_type::construct
@@ -1268,7 +1266,7 @@ class deque : protected deque_base<A>
this->priv_push_front_simple_commit(); this->priv_push_front_simple_commit();
} }
else{ 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)...)); 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 //! <b>Complexity</b>: Amortized constant time
template <class... Args> template <class... Args>
void emplace_back(Args&&... args) void emplace_back(BOOST_FWD_REF(Args)... args)
{ {
if(this->priv_push_back_simple_available()){ if(this->priv_push_back_simple_available()){
allocator_traits_type::construct allocator_traits_type::construct
@@ -1290,7 +1288,7 @@ class deque : protected deque_base<A>
this->priv_push_back_simple_commit(); this->priv_push_back_simple_commit();
} }
else{ 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)...)); 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 //! <b>Complexity</b>: If p is end(), amortized constant time
//! Linear time otherwise. //! Linear time otherwise.
template <class... Args> template <class... Args>
iterator emplace(const_iterator p, Args&&... args) iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{ {
if(p == this->cbegin()){ if(p == this->cbegin()){
this->emplace_front(boost::forward<Args>(args)...); this->emplace_front(boost::forward<Args>(args)...);
@@ -1316,75 +1314,66 @@ class deque : protected deque_base<A>
return (this->end()-1); return (this->end()-1);
} }
else{ 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)...)); 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_CONTAINER_DEQUE_EMPLACE_CODE(N) \
#define BOOST_PP_LOCAL_MACRO(n) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, > ) \ void emplace_front(BOOST_MOVE_UREF##N)\
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ {\
{ \ if(priv_push_front_simple_available()){\
if(priv_push_front_simple_available()){ \ allocator_traits_type::construct\
allocator_traits_type::construct \ ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
( this->alloc() \ priv_push_front_simple_commit();\
, this->priv_push_front_simple_pos() \ }\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ else{\
priv_push_front_simple_commit(); \ typedef container_detail::insert_nonmovable_emplace_proxy##N\
} \ <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
else{ \ priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
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_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()){\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ allocator_traits_type::construct\
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
{ \ priv_push_back_simple_commit();\
if(priv_push_back_simple_available()){ \ }\
allocator_traits_type::construct \ else{\
( this->alloc() \ typedef container_detail::insert_nonmovable_emplace_proxy##N\
, this->priv_push_back_simple_pos() \ <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
priv_push_back_simple_commit(); \ }\
} \ }\
else{ \ \
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \ iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
priv_insert_back_aux_impl \ {\
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ if(p == this->cbegin()){\
} \ this->emplace_front(BOOST_MOVE_FWD##N);\
} \ return this->begin();\
\ }\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ else if(p == cend()){\
iterator emplace(const_iterator p \ this->emplace_back(BOOST_MOVE_FWD##N);\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ return (--this->end());\
{ \ }\
if(p == this->cbegin()){ \ else{\
this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ typedef container_detail::insert_emplace_proxy_arg##N\
return this->begin(); \ <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
} \ return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
else if(p == cend()){ \ }\
this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ }
return (this->end()-1); \ //
} \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
else{ \ #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
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()
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the front of the deque. //! <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 #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); return priv_insert_aux_impl(p, boost::container::iterator_distance(first, last), proxy);
} }
#endif #endif
@@ -1581,11 +1570,11 @@ class deque : protected deque_base<A>
++next; ++next;
size_type index = pos - this->members_.m_start; size_type index = pos - this->members_.m_start;
if (index < (this->size()/2)) { if (index < (this->size()/2)) {
boost::move_backward(this->begin(), pos.unconst(), next); boost::container::move_backward(this->begin(), pos.unconst(), next);
pop_front(); pop_front();
} }
else { else {
boost::move(next, this->end(), pos.unconst()); boost::container::move(next, this->end(), pos.unconst());
pop_back(); pop_back();
} }
return this->members_.m_start + index; 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 n = static_cast<size_type>(last - first);
const size_type elems_before = static_cast<size_type>(first - this->members_.m_start); const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
if (elems_before < (this->size() - n) - elems_before) { 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; iterator new_start = this->members_.m_start + n;
if(!Base::traits_t::trivial_dctr_after_move) if(!Base::traits_t::trivial_dctr_after_move)
this->priv_destroy_range(this->members_.m_start, new_start); 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; this->members_.m_start = new_start;
} }
else { else {
boost::move(last.unconst(), end(), first.unconst()); boost::container::move(last.unconst(), end(), first.unconst());
iterator new_finish = this->members_.m_finish - n; iterator new_finish = this->members_.m_finish - n;
if(!Base::traits_t::trivial_dctr_after_move) if(!Base::traits_t::trivial_dctr_after_move)
this->priv_destroy_range(new_finish, this->members_.m_finish); this->priv_destroy_range(new_finish, this->members_.m_finish);
@@ -1749,7 +1738,7 @@ class deque : protected deque_base<A>
else { else {
return priv_insert_aux_impl return priv_insert_aux_impl
( p, (size_type)1 ( 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{ else{
priv_insert_aux_impl priv_insert_aux_impl
( this->cbegin(), (size_type)1 ( 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{ else{
priv_insert_aux_impl priv_insert_aux_impl
( this->cend(), (size_type)1 ( 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) void priv_destroy_range(iterator p, iterator p2)
{ {
for(;p != p2; ++p){ if(!Base::traits_t::trivial_dctr){
allocator_traits_type::destroy for(;p != p2; ++p){
( this->alloc() allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
, container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p)) }
);
} }
} }
void priv_destroy_range(pointer p, pointer p2) void priv_destroy_range(pointer p, pointer p2)
{ {
for(;p != p2; ++p){ if(!Base::traits_t::trivial_dctr){
allocator_traits_type::destroy for(;p != p2; ++p){
( this->alloc() allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
, container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p)) }
);
} }
} }
@@ -1857,7 +1844,7 @@ class deque : protected deque_base<A>
::boost::container::uninitialized_move_alloc ::boost::container::uninitialized_move_alloc
(this->alloc(), this->members_.m_start, start_n, new_start); (this->alloc(), this->members_.m_start, start_n, new_start);
this->members_.m_start = 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); proxy.copy_n_and_update(this->alloc(), pos - n, n);
} }
else { else {
@@ -1887,7 +1874,7 @@ class deque : protected deque_base<A>
::boost::container::uninitialized_move_alloc ::boost::container::uninitialized_move_alloc
(this->alloc(), finish_n, old_finish, old_finish); (this->alloc(), finish_n, old_finish, old_finish);
this->members_.m_finish = new_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); proxy.copy_n_and_update(this->alloc(), pos, n);
} }
else { 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 new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0); + (add_at_front ? nodes_to_add : 0);
if (new_nstart < this->members_.m_start.m_node) 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 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); (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
} }
else { else {
@@ -2104,7 +2091,7 @@ class deque : protected deque_base<A>
index_pointer new_map = this->priv_allocate_map(new_map_size); index_pointer new_map = this->priv_allocate_map(new_map_size);
new_nstart = new_map + (new_map_size - new_num_nodes) / 2 new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0); + (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->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
this->members_.m_map = new_map; this->members_.m_map = new_map;
@@ -2125,10 +2112,13 @@ namespace boost {
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class T, class A> template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::deque<T, A> > struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
: public ::boost::has_trivial_destructor_after_move<A> {
{}; 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/container/detail/workaround.hpp>
#include <boost/intrusive/set.hpp> #include <boost/intrusive/set.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/container/detail/alloc_lib_auto_link.hpp> #include <boost/container/detail/alloc_lib_auto_link.hpp>
#include <boost/container/detail/multiallocation_chain.hpp> #include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/detail/pool_common_alloc.hpp> #include <boost/container/detail/pool_common_alloc.hpp>
#include <boost/container/detail/mutex.hpp> #include <boost/container/detail/mutex.hpp>
#include <boost/container/detail/adaptive_node_pool_impl.hpp> #include <boost/container/detail/adaptive_node_pool_impl.hpp>
#include <boost/container/detail/multiallocation_chain.hpp> #include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <cstddef> #include <cstddef>
#include <cmath> #include <cmath>
#include <cassert> #include <cassert>

View File

@@ -18,17 +18,23 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp> #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/pointer_traits.hpp>
#include <boost/intrusive/set.hpp> #include <boost/intrusive/set.hpp>
#include <boost/intrusive/list.hpp> #include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp> #include <boost/intrusive/slist.hpp>
#include <boost/container/detail/type_traits.hpp> // other
#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>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp> #include <boost/core/no_exceptions_support.hpp>
#include <cstddef> #include <cstddef>
@@ -482,7 +488,7 @@ class private_adaptive_node_pool_impl
free_nodes_iterator itf(nodes.begin()), itbf(itbb); free_nodes_iterator itf(nodes.begin()), itbf(itbb);
size_type splice_node_count = size_type(-1); size_type splice_node_count = size_type(-1);
while(itf != ite){ 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); block_info_t &block_info = *this->priv_block_from_node(pElem);
BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node); BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node);
++splice_node_count; ++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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
// container/detail
#include <boost/container/detail/copy_move_algo.hpp>
#include <boost/container/detail/destroyers.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/mpl.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/iterator.hpp> #include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.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/assert.hpp>
#include <boost/core/no_exceptions_support.hpp> #include <boost/core/no_exceptions_support.hpp>
namespace boost { namespace container { namespace container_detail { 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 struct move_insert_range_proxy
{ {
typedef typename allocator_traits<A>::size_type size_type; typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type; typedef typename allocator_traits<Allocator>::value_type value_type;
explicit move_insert_range_proxy(FwdIt first) explicit move_insert_range_proxy(FwdIt first)
: first_(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 this->first_ = ::boost::container::uninitialized_move_alloc_n_source
(a, this->first_, n, p); (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); 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 struct insert_range_proxy
{ {
typedef typename allocator_traits<A>::size_type size_type; typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type; typedef typename allocator_traits<Allocator>::value_type value_type;
explicit insert_range_proxy(FwdIt first) explicit insert_range_proxy(FwdIt first)
: first_(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); 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); 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 struct insert_n_copies_proxy
{ {
typedef typename allocator_traits<A>::size_type size_type; typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type; typedef typename allocator_traits<Allocator>::value_type value_type;
explicit insert_n_copies_proxy(const value_type &v) explicit insert_n_copies_proxy(const value_type &v)
: v_(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); } { 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){ for (; 0 < n; --n, ++p){
*p = v_; *p = v_;
@@ -105,38 +111,38 @@ struct insert_n_copies_proxy
const value_type &v_; const value_type &v_;
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_value_initialized_n_proxy struct insert_value_initialized_n_proxy
{ {
typedef ::boost::container::allocator_traits<A> alloc_traits; typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type; typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_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); } { 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); } { BOOST_ASSERT(false); }
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_default_initialized_n_proxy struct insert_default_initialized_n_proxy
{ {
typedef ::boost::container::allocator_traits<A> alloc_traits; typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type; typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_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); } { 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); } { BOOST_ASSERT(false); }
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_copy_proxy 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::size_type size_type;
typedef typename alloc_traits::value_type value_type; typedef typename alloc_traits::value_type value_type;
@@ -144,13 +150,13 @@ struct insert_copy_proxy
: v_(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_ASSERT(n == 1); (void)n; BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, iterator_to_raw_pointer(p), v_); 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; BOOST_ASSERT(n == 1); (void)n;
*p =v_; *p =v_;
@@ -160,10 +166,10 @@ struct insert_copy_proxy
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_move_proxy 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::size_type size_type;
typedef typename alloc_traits::value_type value_type; typedef typename alloc_traits::value_type value_type;
@@ -171,13 +177,13 @@ struct insert_move_proxy
: v_(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_ASSERT(n == 1); (void)n; BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) ); 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; BOOST_ASSERT(n == 1); (void)n;
*p = ::boost::move(v_); *p = ::boost::move(v_);
@@ -186,50 +192,48 @@ struct insert_move_proxy
value_type &v_; value_type &v_;
}; };
template<class It, class A> template<class It, class Allocator>
insert_move_proxy<A, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v) 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> template<class It, class Allocator>
insert_copy_proxy<A, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v) 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 { }}} //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/container/detail/variadic_templates_tools.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <typeinfo>
//#include <iostream> //For debugging purposes
namespace boost { namespace boost {
namespace container { namespace container {
namespace container_detail { namespace container_detail {
template<class A, class Iterator, class ...Args> template<class Allocator, class Iterator, class ...Args>
struct insert_non_movable_emplace_proxy 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::size_type size_type;
typedef typename alloc_traits::value_type value_type; typedef typename alloc_traits::value_type value_type;
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t; 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...) : 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); } { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
private: private:
template<int ...IdxPack> 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; BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... ); alloc_traits::construct( a, 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_; tuple<Args&...> args_;
}; };
template<class A, class Iterator, class ...Args> template<class Allocator, class Iterator, class ...Args>
struct insert_emplace_proxy 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 insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t;
typedef boost::container::allocator_traits<A> alloc_traits; typedef boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename base_t::value_type value_type; typedef typename base_t::value_type value_type;
typedef typename base_t::size_type size_type; typedef typename base_t::size_type size_type;
typedef typename base_t::index_tuple_t index_tuple_t; 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)...) : 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); } { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
private: private:
template<int ...IdxPack> 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; 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)); value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
alloc_traits::construct(a, vp, alloc_traits::construct(a, vp,
::boost::forward<Args>(get<IdxPack>(this->args_))...); ::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 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type> struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
: public insert_move_proxy<A, Iterator> : public insert_move_proxy<Allocator, Iterator>
{ {
explicit insert_emplace_proxy(typename boost::container::allocator_traits<A>::value_type &&v) explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
: insert_move_proxy<A, Iterator>(v) : insert_move_proxy<Allocator, Iterator>(v)
{} {}
}; };
//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking //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>). //compiler error C2752 (<28>more than one partial specialization matches<65>).
//Any problem is solvable with an extra layer of indirection? ;-) //Any problem is solvable with an extra layer of indirection? ;-)
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy<A, Iterator struct insert_emplace_proxy<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type , 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) explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<A, Iterator>(v) : insert_copy_proxy<Allocator, Iterator>(v)
{} {}
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type &> struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_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) explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<A, Iterator>(v) : insert_copy_proxy<Allocator, Iterator>(v)
{} {}
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy<A, Iterator struct insert_emplace_proxy<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type & , 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) explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<A, Iterator>(v) : insert_copy_proxy<Allocator, Iterator>(v)
{} {}
}; };
}}} //namespace boost { namespace container { namespace container_detail { }}} //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> #include <boost/container/detail/value_init.hpp>
namespace boost { namespace boost {
namespace container { namespace container {
namespace container_detail { namespace container_detail {
#define BOOST_PP_LOCAL_MACRO(N) \ #define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \ template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ struct insert_nonmovable_emplace_proxy##N\
{ \ {\
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::size_type size_type;\
typedef typename alloc_traits::value_type value_type; \ typedef typename alloc_traits::value_type value_type;\
\ \
explicit BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
BOOST_PP_EXPR_IF(N, :) BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \ \
{} \ void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
\ {\
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_MOVE_I##N BOOST_MOVE_MFWD##N);\
BOOST_ASSERT(n == 1); (void)n; \ }\
alloc_traits::construct \ \
( a, iterator_to_raw_pointer(p) \ void copy_n_and_update(Allocator &, Iterator, size_type)\
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ { BOOST_ASSERT(false); }\
); \ \
} \ protected:\
\ BOOST_MOVE_MREF##N\
void copy_n_and_update(A &, Iterator, size_type) \ };\
{ BOOST_ASSERT(false); } \ \
\ template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
protected: \ struct insert_emplace_proxy_arg##N\
BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \ : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
}; \ {\
\ typedef insert_nonmovable_emplace_proxy##N\
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \ < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \ typedef typename base_t::value_type value_type;\
: BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ typedef typename base_t::size_type size_type;\
< A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \ typedef boost::container::allocator_traits<Allocator> alloc_traits;\
{ \ \
typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \ : base_t(BOOST_MOVE_FWD##N){}\
typedef typename base_t::value_type value_type; \ \
typedef typename base_t::size_type size_type; \ void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
typedef boost::container::allocator_traits<A> alloc_traits; \ {\
\ BOOST_ASSERT(n == 1); (void)n;\
explicit BOOST_PP_CAT(insert_emplace_proxy_arg, N) \ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\
: base_t(BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \ 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{\
void copy_n_and_update(A &a, Iterator p, size_type n) \ *p = ::boost::move(*vp);\
{ \ }\
BOOST_ASSERT(n == 1); (void)n; \ BOOST_CATCH(...){\
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \ alloc_traits::destroy(a, vp);\
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \ BOOST_RETHROW\
alloc_traits::construct(a, vp \ }\
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \ BOOST_CATCH_END\
BOOST_TRY{ \ alloc_traits::destroy(a, vp);\
*p = ::boost::move(*vp); \ }\
} \ };\
BOOST_CATCH(...){ \ //
alloc_traits::destroy(a, vp); \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
BOOST_RETHROW \ #undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
} \
BOOST_CATCH_END \
alloc_traits::destroy(a, vp); \
} \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, ::boost::rv<typename boost::container::allocator_traits<A>::value_type> > struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
: public insert_move_proxy<A, Iterator> : public insert_move_proxy<Allocator, Iterator>
{ {
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<A>::value_type &v) explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_move_proxy<A, Iterator>(v) : insert_move_proxy<Allocator, Iterator>(v)
{} {}
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type> struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_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) explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<A, Iterator>(v) : insert_copy_proxy<Allocator, Iterator>(v)
{} {}
}; };
#else //e.g. MSVC10 & MSVC11 #else //e.g. MSVC10 & MSVC11
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type> struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
: public insert_move_proxy<A, Iterator> : public insert_move_proxy<Allocator, Iterator>
{ {
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<A>::value_type &&v) explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
: insert_move_proxy<A, Iterator>(v) : insert_move_proxy<Allocator, Iterator>(v)
{} {}
}; };
//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking //We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
//compiler error C2752 (<28>more than one partial specialization matches<65>). //compiler error C2752 (<28>more than one partial specialization matches<65>).
//Any problem is solvable with an extra layer of indirection? ;-) //Any problem is solvable with an extra layer of indirection? ;-)
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator struct insert_emplace_proxy_arg1<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type , 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) explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<A, Iterator>(v) : insert_copy_proxy<Allocator, Iterator>(v)
{} {}
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type &> struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_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) explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<A, Iterator>(v) : insert_copy_proxy<Allocator, Iterator>(v)
{} {}
}; };
template<class A, class Iterator> template<class Allocator, class Iterator>
struct insert_emplace_proxy_arg1<A, Iterator struct insert_emplace_proxy_arg1<Allocator, Iterator
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type & , 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) explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<A, Iterator>(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 { }}} //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> #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 try_shrink_in_place_v = 0x40
}; };
typedef int allocation_type; typedef unsigned int allocation_type;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
static const allocation_type allocate_new = (allocation_type)allocate_new_v; static const allocation_type allocate_new = (allocation_type)allocate_new_v;
static const allocation_type expand_fwd = (allocation_type)expand_fwd_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/allocation_type.hpp> //allocation_type
#include <boost/container/detail/mpl.hpp> //integral_constant #include <boost/container/detail/mpl.hpp> //integral_constant
#include <boost/intrusive/pointer_traits.hpp> //pointer_traits #include <boost/intrusive/pointer_traits.hpp> //pointer_traits
#include <utility> //pair
#include <boost/core/no_exceptions_support.hpp> //BOOST_TRY #include <boost/core/no_exceptions_support.hpp> //BOOST_TRY
namespace boost { namespace boost {
namespace container { namespace container {
namespace container_detail { 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 struct allocator_version_traits
{ {
typedef ::boost::container::container_detail::integral_constant typedef ::boost::container::container_detail::integral_constant
<unsigned, Version> alloc_version; <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<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::size_type size_type; typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
//Node allocation interface //Node allocation interface
static pointer allocate_one(A &a) static pointer allocate_one(Allocator &a)
{ return a.allocate_one(); } { 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); } { 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); } { 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); } { a.deallocate_individual(holder); }
static std::pair<pointer, bool> static pointer allocation_command(Allocator &a, allocation_type command,
allocation_command(A &a, allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
size_type limit_size, size_type preferred_size, { return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
size_type &received_size, const pointer &reuse)
{
return a.allocation_command
(command, limit_size, preferred_size, received_size, reuse);
}
}; };
template<class A> template<class Allocator>
struct allocator_version_traits<A, 1> struct allocator_version_traits<Allocator, 1>
{ {
typedef ::boost::container::container_detail::integral_constant typedef ::boost::container::container_detail::integral_constant
<unsigned, 1> alloc_version; <unsigned, 1> alloc_version;
typedef typename boost::container::allocator_traits<A>::pointer pointer; typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::size_type size_type; typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::value_type value_type; typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
typedef typename boost::intrusive::pointer_traits<pointer>:: typedef typename boost::intrusive::pointer_traits<pointer>::
template rebind_pointer<void>::type void_ptr; template rebind_pointer<void>::type void_ptr;
@@ -85,13 +79,13 @@ struct allocator_version_traits<A, 1>
< multialloc_cached_counted, value_type> multiallocation_chain; < multialloc_cached_counted, value_type> multiallocation_chain;
//Node allocation interface //Node allocation interface
static pointer allocate_one(A &a) static pointer allocate_one(Allocator &a)
{ return a.allocate(1); } { 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); } { 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(); size_type n = holder.size();
typename multiallocation_chain::iterator it = holder.begin(); typename multiallocation_chain::iterator it = holder.begin();
@@ -104,7 +98,7 @@ struct allocator_version_traits<A, 1>
struct allocate_individual_rollback 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) : mr_a(a), mp_chain(&chain)
{} {}
@@ -119,11 +113,11 @@ struct allocator_version_traits<A, 1>
mp_chain = 0; mp_chain = 0;
} }
A &mr_a; Allocator &mr_a;
multiallocation_chain * mp_chain; 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); allocate_individual_rollback rollback(a, m);
while(n--){ while(n--){
@@ -132,21 +126,16 @@ struct allocator_version_traits<A, 1>
rollback.release(); rollback.release();
} }
static std::pair<pointer, bool> static pointer allocation_command(Allocator &a, allocation_type command,
allocation_command(A &a, allocation_type command, size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
size_type, size_type preferred_size,
size_type &received_size, const pointer &)
{ {
std::pair<pointer, bool> ret(pointer(), false); pointer ret = pointer();
if(!(command & allocate_new)){ if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
if(!(command & nothrow_allocation)){ throw_logic_error("version 1 allocator without allocate_new flag");
throw_logic_error("version 1 allocator without allocate_new flag");
}
} }
else{ else{
received_size = preferred_size;
BOOST_TRY{ BOOST_TRY{
ret.first = a.allocate(received_size); ret = a.allocate(prefer_in_recvd_out_size);
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
if(!(command & nothrow_allocation)){ if(!(command & nothrow_allocation)){
@@ -154,6 +143,7 @@ struct allocator_version_traits<A, 1>
} }
} }
BOOST_CATCH_END BOOST_CATCH_END
reuse = pointer();
} }
return ret; return ret;
} }

View File

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

View File

@@ -17,32 +17,33 @@
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
#pragma warning (push) #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 : 4127) // conditional expression is constant
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned #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 : 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 : 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 : 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 : 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 : 4355) // "this" : used in base member initializer list
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated #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 : 4511) // copy constructor could not be generated
#pragma warning (disable : 4512) // assignment operator could not be generated #pragma warning (disable : 4512) // assignment operator could not be generated
#pragma warning (disable : 4514) // unreferenced inline removed #pragma warning (disable : 4514) // unreferenced inline removed
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified" #pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
#pragma warning (disable : 4522) // "class" : multiple assignment operators 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 : 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 : 4710) // function not inlined
#pragma warning (disable : 4711) // function selected for automatic inline expansion #pragma warning (disable : 4711) // function selected for automatic inline expansion
#pragma warning (disable : 4786) // identifier truncated in debug info #pragma warning (disable : 4786) // identifier truncated in debug info
#pragma warning (disable : 4996) // "function": was declared deprecated #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 #endif //BOOST_MSVC

View File

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

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP #ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP #define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
@@ -15,167 +14,26 @@
# pragma once # pragma once
#endif #endif
#include <boost/container/detail/config_begin.hpp> // container
#include <boost/container/detail/workaround.hpp> #include <boost/container/allocator_traits.hpp>
// container/detail
#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>
#include <boost/container/detail/iterator.hpp> #include <boost/container/detail/iterator.hpp>
#include <boost/type_traits/is_pod.hpp> #include <boost/container/detail/iterator_to_raw_pointer.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/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator_traits.hpp> // move
#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>
#include <boost/move/adl_move_swap.hpp> #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 boost {
namespace container { namespace container {
//////////////////////////////////////////////////////////////////////////////
//
// swap
//
//////////////////////////////////////////////////////////////////////////////
namespace container_detail { 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> template<class I>
struct are_elements_contiguous struct are_elements_contiguous
{ {
@@ -266,34 +124,34 @@ template <typename I, typename O>
struct is_memtransfer_copy_assignable struct is_memtransfer_copy_assignable
{ {
static const bool value = are_contiguous_and_same<I, O>::value && 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> template <typename I, typename O>
struct is_memtransfer_copy_constructible struct is_memtransfer_copy_constructible
{ {
static const bool value = are_contiguous_and_same<I, O>::value && 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> template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_constructible 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> template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_constructible 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> template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_assignable 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> template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_assignable 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 template
@@ -347,32 +205,45 @@ struct is_memzero_initializable
{ {
typedef typename ::boost::container::iterator_traits<O>::value_type value_type; typedef typename ::boost::container::iterator_traits<O>::value_type value_type;
static const bool value = are_elements_contiguous<O>::value && 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) #if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
|| ::boost::is_pointer<value_type>::value || container_detail::is_pointer<value_type>::value
#endif #endif
#if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) #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 #endif
#if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL) #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 #endif
); );
}; };
template <typename O, typename R> template <typename O, typename R>
struct enable_if_memzero_initializable 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> template <typename O, typename R>
struct disable_if_memzero_initializable 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 { } //namespace container_detail {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// uninitialized_move_alloc // uninitialized_move_alloc
@@ -388,22 +259,22 @@ struct disable_if_memzero_initializable
//! //!
//! <b>Returns</b>: r //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (f != l) { 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; ++f; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -412,11 +283,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
} }
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type 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); } { 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 //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (n--) { 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; ++f; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -457,11 +328,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
} }
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type 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); } { 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) //! <b>Returns</b>: f (after incremented)
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (n--) { 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; ++f; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -502,11 +373,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
} }
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type 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); } { 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 //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (f != l) { 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; ++f; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -547,11 +418,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
} }
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type 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); } { 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 //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (n--) { 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; ++f; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -592,11 +463,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
} }
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type 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); } { 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) //! <b>Returns</b>: f (after incremented)
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (n--) { 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; ++f; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -637,11 +508,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
} }
template template
<typename A, <typename Allocator,
typename I, // I models InputIterator typename I, // I models InputIterator
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type 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); } { 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 //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memzero_initializable<F, F>::type 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (n--) { 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; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -681,10 +552,10 @@ inline typename container_detail::disable_if_memzero_initializable<F, F>::type
} }
template template
<typename A, <typename Allocator,
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memzero_initializable<F, F>::type 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; 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); ::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 //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename F> // F models ForwardIterator 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (n--) { 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; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; BOOST_RETHROW;
} }
@@ -741,21 +612,21 @@ inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::
//! //!
//! <b>Returns</b>: r //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename F, // F models ForwardIterator typename F, // F models ForwardIterator
typename T> 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; F back = f;
BOOST_TRY{ BOOST_TRY{
while (f != l) { 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; ++f;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != l; ++back){ 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; BOOST_RETHROW;
} }
@@ -777,21 +648,21 @@ inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
//! //!
//! <b>Returns</b>: r //! <b>Returns</b>: r
template template
<typename A, <typename Allocator,
typename T, typename T,
typename F> // F models ForwardIterator 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; F back = r;
BOOST_TRY{ BOOST_TRY{
while (n--) { 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; ++r;
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
for (; back != r; ++back){ 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; 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 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); } { return container_detail::memmove_n(f, n, r); }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// move_n_source // move_backward
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
template template
<typename I // I models InputIterator <typename I, // I models BidirectionalIterator
,typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) move_backward(I f, I l, F r)
{ {
while (n--) { while (f != l) {
*r = ::boost::move(*f); --l; --r;
++f; ++r; *r = ::boost::move(*l);
} }
return f; return r;
} }
template template
<typename I // I models InputIterator <typename I, // I models InputIterator
,typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT move_backward(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
{ return container_detail::memmove_n_source(f, n, r); } {
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 template
<typename A <typename I // I models InputIterator
,typename I> // I models InputIterator ,typename F> // F models ForwardIterator
inline void destroy_alloc_n(A &a, I f, typename boost::container::iterator_traits<I>::difference_type n inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
,typename boost::container::container_detail::enable_if_c move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
< !boost::has_trivial_destructor<typename boost::container::iterator_traits<I>::value_type>::value >::type* = 0) {
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--){ 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 template
<typename A <typename Allocator
,typename I> // I models InputIterator ,typename I // I models InputIterator
inline void destroy_alloc_n(A &, I, typename boost::container::iterator_traits<I>::difference_type ,typename U> // U models unsigned integral constant
,typename boost::container::container_detail::enable_if_c inline typename container_detail::enable_if_trivially_destructible<I, void>::type
< boost::has_trivial_destructor<typename boost::container::iterator_traits<I>::value_type>::value >::type* = 0) destroy_alloc_n(Allocator &, I, U)
{} {}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -1041,15 +946,15 @@ inline void destroy_alloc_n(A &, I, typename boost::container::iterator_traits<I
template template
<std::size_t MaxTmpBytes <std::size_t MaxTmpBytes
,typename A ,typename Allocator
,typename F // F models ForwardIterator ,typename F // F models ForwardIterator
,typename G // G models ForwardIterator ,typename G // G models ForwardIterator
> >
inline typename container_detail::disable_if_memtransfer_copy_assignable<F, G, void>::type 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 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<A>::size_type n_j) , 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){ for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){
boost::adl_move_swap(*short_range_f, *large_range_f); 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 template
<std::size_t MaxTmpBytes <std::size_t MaxTmpBytes
,typename A ,typename Allocator
,typename F // F models ForwardIterator ,typename F // F models ForwardIterator
,typename G // G models ForwardIterator ,typename G // G models ForwardIterator
> >
inline typename container_detail::enable_if_c inline typename container_detail::enable_if_c
< container_detail::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false < container_detail::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
, void>::type , void>::type
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i 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<A>::size_type n_j) , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{ {
typedef typename allocator_traits<A>::value_type value_type; typedef typename allocator_traits<Allocator>::value_type value_type;
typedef typename boost::aligned_storage typedef typename container_detail::aligned_storage
<MaxTmpBytes, container_detail::alignment_of<value_type>::value>::type storage_type; <MaxTmpBytes, container_detail::alignment_of<value_type>::value>::type storage_type;
storage_type storage; storage_type storage;
@@ -1091,18 +996,18 @@ inline typename container_detail::enable_if_c
template template
<std::size_t MaxTmpBytes <std::size_t MaxTmpBytes
,typename A ,typename Allocator
,typename F // F models ForwardIterator ,typename F // F models ForwardIterator
,typename G // G models ForwardIterator ,typename G // G models ForwardIterator
> >
inline typename container_detail::enable_if_c inline typename container_detail::enable_if_c
< container_detail::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage) < container_detail::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
, void>::type , void>::type
deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i 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<A>::size_type n_j) , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{ {
typedef typename allocator_traits<A>::value_type value_type; typedef typename allocator_traits<Allocator>::value_type value_type;
typedef typename boost::aligned_storage typedef typename container_detail::aligned_storage
<DeepSwapAllocNMaxStorage, container_detail::alignment_of<value_type>::value>::type storage_type; <DeepSwapAllocNMaxStorage, container_detail::alignment_of<value_type>::value>::type storage_type;
storage_type storage; storage_type storage;
const std::size_t sizeof_storage = sizeof(storage); const std::size_t sizeof_storage = sizeof(storage);
@@ -1168,12 +1073,12 @@ inline typename container_detail::enable_if_c
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
template template
<typename A <typename Allocator
,typename I // F models InputIterator ,typename I // F models InputIterator
,typename O // G models OutputIterator ,typename O // G models OutputIterator
> >
void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i 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<A>::size_type n_o ) , O out_start, typename allocator_traits<Allocator>::size_type n_o )
{ {
if (n_o < n_i){ if (n_o < n_i){
inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw 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 template
<typename A <typename Allocator
,typename I // F models InputIterator ,typename I // F models InputIterator
,typename O // G models OutputIterator ,typename O // G models OutputIterator
> >
void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i 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<A>::size_type n_o ) , O out_start, typename allocator_traits<Allocator>::size_type n_o )
{ {
if (n_o < n_i){ if (n_o < n_i){
inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw 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 container {
} //namespace boost { } //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_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/config_begin.hpp>
#include <boost/container/detail/workaround.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/allocator_traits.hpp>
#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/version_type.hpp>
namespace boost { namespace boost {
namespace container { namespace container {
@@ -30,22 +30,20 @@ namespace container_detail {
//!A deleter for scoped_ptr that deallocates the memory //!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator. //!allocated for an object using a STL allocator.
template <class A> template <class Allocator>
struct scoped_deallocator 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 typename allocator_traits_type::pointer pointer;
typedef container_detail::integral_constant<unsigned, typedef container_detail::integral_constant<unsigned,
boost::container::container_detail:: boost::container::container_detail::
version<A>::value> alloc_version; version<Allocator>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
private: private:
void priv_deallocate(allocator_v1) void priv_deallocate(version_1)
{ m_alloc.deallocate(m_ptr, 1); } { m_alloc.deallocate(m_ptr, 1); }
void priv_deallocate(allocator_v2) void priv_deallocate(version_2)
{ m_alloc.deallocate_one(m_ptr); } { m_alloc.deallocate_one(m_ptr); }
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator) BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
@@ -53,9 +51,9 @@ struct scoped_deallocator
public: public:
pointer m_ptr; 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) : m_ptr(p), m_alloc(a)
{} {}
@@ -76,14 +74,14 @@ struct scoped_deallocator
{ m_ptr = 0; } { m_ptr = 0; }
}; };
template <class A> template <class Allocator>
struct null_scoped_deallocator 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::pointer pointer;
typedef typename AllocTraits::size_type size_type; typedef typename AllocTraits::size_type size_type;
null_scoped_deallocator(pointer, A&, size_type) null_scoped_deallocator(pointer, Allocator&, size_type)
{} {}
void release() void release()
@@ -98,14 +96,14 @@ struct null_scoped_deallocator
//!A deleter for scoped_ptr that deallocates the memory //!A deleter for scoped_ptr that deallocates the memory
//!allocated for an array of objects using a STL allocator. //!allocated for an array of objects using a STL allocator.
template <class A> template <class Allocator>
struct scoped_array_deallocator 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::pointer pointer;
typedef typename AllocTraits::size_type size_type; 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) {} : m_ptr(p), m_alloc(a), m_length(length) {}
~scoped_array_deallocator() ~scoped_array_deallocator()
@@ -116,37 +114,35 @@ struct scoped_array_deallocator
private: private:
pointer m_ptr; pointer m_ptr;
A& m_alloc; Allocator& m_alloc;
size_type m_length; size_type m_length;
}; };
template <class A> template <class Allocator>
struct null_scoped_array_deallocator 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::pointer pointer;
typedef typename AllocTraits::size_type size_type; 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() void release()
{} {}
}; };
template <class A> template <class Allocator>
struct scoped_destroy_deallocator 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::pointer pointer;
typedef typename AllocTraits::size_type size_type; typedef typename AllocTraits::size_type size_type;
typedef container_detail::integral_constant<unsigned, typedef container_detail::integral_constant<unsigned,
boost::container::container_detail:: boost::container::container_detail::
version<A>::value> alloc_version; version<Allocator>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
scoped_destroy_deallocator(pointer p, A& a) scoped_destroy_deallocator(pointer p, Allocator& a)
: m_ptr(p), m_alloc(a) {} : m_ptr(p), m_alloc(a) {}
~scoped_destroy_deallocator() ~scoped_destroy_deallocator()
@@ -162,28 +158,28 @@ struct scoped_destroy_deallocator
private: private:
void priv_deallocate(const pointer &p, allocator_v1) void priv_deallocate(const pointer &p, version_1)
{ AllocTraits::deallocate(m_alloc, p, 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); } { m_alloc.deallocate_one(p); }
pointer m_ptr; pointer m_ptr;
A& m_alloc; Allocator& m_alloc;
}; };
//!A deleter for scoped_ptr that destroys //!A deleter for scoped_ptr that destroys
//!an object using a STL allocator. //!an object using a STL allocator.
template <class A> template <class Allocator>
struct scoped_destructor_n 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::pointer pointer;
typedef typename AllocTraits::value_type value_type; typedef typename AllocTraits::value_type value_type;
typedef typename AllocTraits::size_type size_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) : m_p(p), m_a(a), m_n(n)
{} {}
@@ -210,20 +206,20 @@ struct scoped_destructor_n
private: private:
pointer m_p; pointer m_p;
A & m_a; Allocator & m_a;
size_type m_n; size_type m_n;
}; };
//!A deleter for scoped_ptr that destroys //!A deleter for scoped_ptr that destroys
//!an object using a STL allocator. //!an object using a STL allocator.
template <class A> template <class Allocator>
struct null_scoped_destructor_n 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::pointer pointer;
typedef typename AllocTraits::size_type size_type; 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) void increment_size(size_type)
@@ -239,13 +235,13 @@ struct null_scoped_destructor_n
{} {}
}; };
template<class A> template<class Allocator>
class scoped_destructor class scoped_destructor
{ {
typedef boost::container::allocator_traits<A> AllocTraits; typedef boost::container::allocator_traits<Allocator> AllocTraits;
public: public:
typedef typename A::value_type value_type; typedef typename Allocator::value_type value_type;
scoped_destructor(A &a, value_type *pv) scoped_destructor(Allocator &a, value_type *pv)
: pv_(pv), a_(a) : pv_(pv), a_(a)
{} {}
@@ -266,17 +262,17 @@ class scoped_destructor
private: private:
value_type *pv_; value_type *pv_;
A &a_; Allocator &a_;
}; };
template<class A> template<class Allocator>
class value_destructor class value_destructor
{ {
typedef boost::container::allocator_traits<A> AllocTraits; typedef boost::container::allocator_traits<Allocator> AllocTraits;
public: public:
typedef typename A::value_type value_type; typedef typename Allocator::value_type value_type;
value_destructor(A &a, value_type &rv) value_destructor(Allocator &a, value_type &rv)
: rv_(rv), a_(a) : rv_(rv), a_(a)
{} {}
@@ -287,33 +283,31 @@ class value_destructor
private: private:
value_type &rv_; value_type &rv_;
A &a_; Allocator &a_;
}; };
template <class A> template <class Allocator>
class allocator_destroyer 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::value_type value_type;
typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::pointer pointer;
typedef container_detail::integral_constant<unsigned, typedef container_detail::integral_constant<unsigned,
boost::container::container_detail:: boost::container::container_detail::
version<A>::value> alloc_version; version<Allocator>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
private: private:
A & a_; Allocator & a_;
private: private:
void priv_deallocate(const pointer &p, allocator_v1) void priv_deallocate(const pointer &p, version_1)
{ AllocTraits::deallocate(a_,p, 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); } { a_.deallocate_one(p); }
public: public:
allocator_destroyer(A &a) allocator_destroyer(Allocator &a)
: a_(a) : a_(a)
{} {}
@@ -324,41 +318,41 @@ class allocator_destroyer
} }
}; };
template <class A> template <class Allocator>
class allocator_destroyer_and_chain_builder 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 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_; multiallocation_chain &c_;
public: 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) : 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); c_.push_back(p);
} }
}; };
template <class A> template <class Allocator>
class allocator_multialloc_chain_node_deallocator 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 allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain; typedef typename Allocator::multiallocation_chain multiallocation_chain;
typedef allocator_destroyer_and_chain_builder<A> chain_builder; typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;
A & a_; Allocator & a_;
multiallocation_chain c_; multiallocation_chain c_;
public: public:
allocator_multialloc_chain_node_deallocator(A &a) allocator_multialloc_chain_node_deallocator(Allocator &a)
: a_(a), c_() : a_(a), c_()
{} {}

View File

@@ -20,10 +20,8 @@
#include <boost/container/container_fwd.hpp> #include <boost/container/container_fwd.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp> #include <boost/container/detail/pair.hpp>
#include <boost/container/vector.hpp> #include <boost/container/vector.hpp>
#include <boost/container/detail/value_init.hpp> #include <boost/container/detail/value_init.hpp>
@@ -34,11 +32,14 @@
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER #ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#endif #endif
#include <boost/aligned_storage.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/move/make_unique.hpp> #include <boost/move/make_unique.hpp>
#include <boost/move/adl_move_swap.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 boost {
namespace container { namespace container {
@@ -94,11 +95,11 @@ struct get_flat_tree_iterators
}; };
template <class Key, class Value, class KeyOfValue, template <class Key, class Value, class KeyOfValue,
class Compare, class A> class Compare, class Allocator>
class flat_tree class flat_tree
{ {
typedef boost::container::vector<Value, A> vector_t; typedef boost::container::vector<Value, Allocator> vector_t;
typedef A allocator_t; typedef Allocator allocator_t;
public: public:
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare; 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)) : 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) : 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) : 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); } { this->priv_insert_ordered_range(true, first, last); }
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class... Args> 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)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -510,9 +511,9 @@ class flat_tree
} }
template <class... 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)
{ {
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)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -521,9 +522,9 @@ class flat_tree
} }
template <class... Args> 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)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -532,9 +533,9 @@ class flat_tree
} }
template <class... Args> 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)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); 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)); 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) \ #define BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator, bool> \ std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\
emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ {\
{ \ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \ stored_allocator_type &a = this->get_stored_allocator();\
stored_allocator_type &a = this->get_stored_allocator(); \ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
stored_allocator_traits::construct(a, &val \ value_destructor<stored_allocator_type> d(a, val);\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ return this->insert_unique(::boost::move(val));\
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)\
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 \ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
{ \ stored_allocator_type &a = this->get_stored_allocator();\
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \ value_destructor<stored_allocator_type> d(a, val);\
stored_allocator_type &a = this->get_stored_allocator(); \ return this->insert_unique(hint, ::boost::move(val));\
stored_allocator_traits::construct(a, &val \ }\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ \
value_destructor<stored_allocator_type> d(a, val); \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
return this->insert_unique(hint, ::boost::move(val)); \ iterator emplace_equal(BOOST_MOVE_UREF##N)\
} \ {\
\ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ stored_allocator_type &a = this->get_stored_allocator();\
{ \ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \ value_destructor<stored_allocator_type> d(a, val);\
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \ return this->insert_equal(::boost::move(val));\
stored_allocator_type &a = this->get_stored_allocator(); \ }\
stored_allocator_traits::construct(a, &val \ \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
value_destructor<stored_allocator_type> d(a, val); \ iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
return this->insert_equal(::boost::move(val)); \ {\
} \ typename aligned_storage <sizeof(value_type), alignment_of<value_type>::value>::type v;\
\ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ stored_allocator_type &a = this->get_stored_allocator();\
iterator emplace_hint_equal(const_iterator hint \ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ value_destructor<stored_allocator_type> d(a, val);\
{ \ return this->insert_equal(hint, ::boost::move(val));\
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(); \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE)
stored_allocator_traits::construct(a, &val \ #undef BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE
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()
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
iterator erase(const_iterator position) iterator erase(const_iterator position)
{ return this->m_data.m_vect.erase(position); } { return this->m_data.m_vect.erase(position); }
@@ -965,7 +959,7 @@ class flat_tree
for(; checked != burst; ++checked){ for(; checked != burst; ++checked){
//Get the insertion position for each key, use iterator_traits<BidirIt>::value_type //Get the insertion position for each key, use iterator_traits<BidirIt>::value_type
//because it can be different from container::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; 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)); pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
//Check if already present //Check if already present
@@ -1012,16 +1006,18 @@ class flat_tree
} //namespace container_detail { } //namespace container_detail {
} //namespace container { } //namespace container {
/*
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class K, class V, class KOV, template <class Key, class T, class KeyOfValue,
class C, class A> class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<K, V, KOV, C, A> > 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 { } //namespace boost {
#include <boost/container/detail/config_end.hpp> #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>, 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 class hash_set
{ {
public: public:
@@ -9,7 +9,7 @@ public:
typedef key_type value_type; typedef key_type value_type;
typedef Hash hasher; typedef Hash hasher;
typedef Pred key_equal; typedef Pred key_equal;
typedef Alloc allocator_type; typedef Allocator allocator_type;
typedef value_type& reference; typedef value_type& reference;
typedef const value_type& const_reference; typedef const value_type& const_reference;
typedef typename allocator_traits<allocator_type>::pointer pointer; typedef typename allocator_traits<allocator_type>::pointer pointer;
@@ -37,13 +37,13 @@ public:
const allocator_type& a = allocator_type()); const allocator_type& a = allocator_type());
explicit hash_set(const allocator_type&); explicit hash_set(const allocator_type&);
hash_set(const hash_set&); hash_set(const hash_set&);
hash_set(const hash_set&, const A&); hash_set(const hash_set&, const Allocator&);
hash_set(hash_set&&) hash_set(hash_set&&)
noexcept( noexcept(
is_nothrow_move_constructible<hasher>::value && is_nothrow_move_constructible<hasher>::value &&
is_nothrow_move_constructible<key_equal>::value && is_nothrow_move_constructible<key_equal>::value &&
is_nothrow_move_constructible<allocator_type>::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, hash_set(initializer_list<value_type>, size_type n = 0,
const hasher& hf = hasher(), const key_equal& eql = key_equal(), const hasher& hf = hasher(), const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type()); const allocator_type& a = allocator_type());
@@ -71,9 +71,9 @@ public:
const_iterator cend() const noexcept; const_iterator cend() const noexcept;
template <class... Args> template <class... Args>
pair<iterator, bool> emplace(Args&&... args); pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... 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(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj); pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const 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>, 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 class hash_map
{ {
public: public:
@@ -133,7 +133,7 @@ public:
typedef T mapped_type; typedef T mapped_type;
typedef Hash hasher; typedef Hash hasher;
typedef Pred key_equal; typedef Pred key_equal;
typedef Alloc allocator_type; typedef Allocator allocator_type;
typedef pair<const key_type, mapped_type> value_type; typedef pair<const key_type, mapped_type> value_type;
typedef value_type& reference; typedef value_type& reference;
typedef const value_type& const_reference; typedef const value_type& const_reference;
@@ -162,13 +162,13 @@ public:
const allocator_type& a = allocator_type()); const allocator_type& a = allocator_type());
explicit hash_map(const allocator_type&); explicit hash_map(const allocator_type&);
hash_map(const hash_map&); hash_map(const hash_map&);
hash_map(const hash_map&, const A&); hash_map(const hash_map&, const Allocator&);
hash_map(hash_map&&) hash_map(hash_map&&)
noexcept( noexcept(
is_nothrow_move_constructible<hasher>::value && is_nothrow_move_constructible<hasher>::value &&
is_nothrow_move_constructible<key_equal>::value && is_nothrow_move_constructible<key_equal>::value &&
is_nothrow_move_constructible<allocator_type>::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, hash_map(initializer_list<value_type>, size_type n = 0,
const hasher& hf = hasher(), const key_equal& eql = key_equal(), const hasher& hf = hasher(), const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type()); const allocator_type& a = allocator_type());
@@ -196,9 +196,9 @@ public:
const_iterator cend() const noexcept; const_iterator cend() const noexcept;
template <class... Args> template <class... Args>
pair<iterator, bool> emplace(Args&&... args); pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... 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(const value_type& obj);
template <class P> template <class P>
pair<iterator, bool> insert(P&& obj); 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>, 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 class hash_table
{ {
public: public:
@@ -268,7 +268,7 @@ public:
typedef key_type value_type; typedef key_type value_type;
typedef Hash hasher; typedef Hash hasher;
typedef Pred key_equal; typedef Pred key_equal;
typedef Alloc allocator_type; typedef Allocator allocator_type;
typedef value_type& reference; typedef value_type& reference;
typedef const value_type& const_reference; typedef const value_type& const_reference;
typedef typename allocator_traits<allocator_type>::pointer pointer; typedef typename allocator_traits<allocator_type>::pointer pointer;
@@ -296,13 +296,13 @@ public:
const allocator_type& a = allocator_type()); const allocator_type& a = allocator_type());
explicit hash_set(const allocator_type&); explicit hash_set(const allocator_type&);
hash_set(const hash_set&); hash_set(const hash_set&);
hash_set(const hash_set&, const A&); hash_set(const hash_set&, const Allocator&);
hash_set(hash_set&&) hash_set(hash_set&&)
noexcept( noexcept(
is_nothrow_move_constructible<hasher>::value && is_nothrow_move_constructible<hasher>::value &&
is_nothrow_move_constructible<key_equal>::value && is_nothrow_move_constructible<key_equal>::value &&
is_nothrow_move_constructible<allocator_type>::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, hash_set(initializer_list<value_type>, size_type n = 0,
const hasher& hf = hasher(), const key_equal& eql = key_equal(), const hasher& hf = hasher(), const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type()); const allocator_type& a = allocator_type());
@@ -330,9 +330,9 @@ public:
const_iterator cend() const noexcept; const_iterator cend() const noexcept;
template <class... Args> template <class... Args>
pair<iterator, bool> emplace(Args&&... args); pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... 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(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj); pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const 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/move/utility_core.hpp>
#include <boost/intrusive/detail/reverse_iterator.hpp> #include <boost/intrusive/detail/reverse_iterator.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/variadic_templates_tools.hpp> #include <boost/move/detail/fwd_macros.hpp>
#else #else
#include <boost/container/detail/preprocessor.hpp> #include <boost/container/detail/variadic_templates_tools.hpp>
#endif #endif
#include <boost/container/detail/iterator.hpp> #include <boost/container/detail/iterator.hpp>
namespace boost { namespace boost {
@@ -564,8 +563,8 @@ class emplace_iterator
//const T& operator[](difference_type) const; //const T& operator[](difference_type) const;
//const T* operator->() const; //const T* operator->() const;
template<class A> template<class Allocator>
void construct_in_place(A &a, T* ptr) void construct_in_place(Allocator &a, T* ptr)
{ (*m_pe)(a, ptr); } { (*m_pe)(a, ptr); }
private: private:
@@ -597,54 +596,49 @@ class emplace_iterator
{ return difference_type(m_num - other.m_num); } { return difference_type(m_num - other.m_num); }
}; };
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class ...Args> template<class ...Args>
struct emplace_functor struct emplace_functor
{ {
typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t; 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...) : args_(args...)
{} {}
template<class A, class T> template<class Allocator, class T>
void operator()(A &a, T *ptr) void operator()(Allocator &a, T *ptr)
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); } { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
template<class A, class T, int ...IdxPack> template<class Allocator, class T, int ...IdxPack>
void inplace_impl(A &a, T* ptr, const container_detail::index_tuple<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_))...); (a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
} }
container_detail::tuple<Args&...> 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) \ #define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
BOOST_PP_EXPR_IF(n, template <) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
BOOST_PP_ENUM_PARAMS(n, class P) \ struct emplace_functor##N\
BOOST_PP_EXPR_IF(n, >) \ {\
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
{ \ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ \
( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ template<class Allocator, class T>\
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \ void operator()(Allocator &a, T *ptr)\
\ { allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
template<class A, class T> \ \
void operator()(A &a, T *ptr) \ BOOST_MOVE_MREF##N\
{ \ };\
allocator_traits<A>::construct \ //
(a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \ BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
} \ #undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
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()
#endif #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; 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 <typename T> struct unvoid { typedef T type; };
template <> struct unvoid<void> { struct type { }; }; template <> struct unvoid<void> { struct type { }; };
template <> struct unvoid<const 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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp> #include <boost/container/container_fwd.hpp>
#include <boost/container/detail/utilities.hpp> // container/detail
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/transform_iterator.hpp> #include <boost/container/detail/transform_iterator.hpp>
#include <boost/container/detail/type_traits.hpp>
// intrusive
#include <boost/intrusive/slist.hpp> #include <boost/intrusive/slist.hpp>
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <boost/type_traits/make_unsigned.hpp> // move
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
namespace boost { namespace boost {
@@ -47,7 +49,7 @@ class basic_multiallocation_chain
typedef bi::slist< node typedef bi::slist< node
, bi::linear<true> , bi::linear<true>
, bi::cache_last<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_t slist_impl_; 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_TRY_LOCK(sl) !BOOST_CONTAINER_CAS_LOCK(sl)
#define BOOST_CONTAINER_RELEASE_LOCK(sl) BOOST_CONTAINER_CLEAR_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_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) #define BOOST_CONTAINER_DESTROY_LOCK(sl) (0)
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32 #elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
// //
@@ -199,7 +199,7 @@ namespace container_detail {
void operator=(const spin_mutex &); void operator=(const spin_mutex &);
public: public:
spin_mutex() { BOOST_CONTAINER_INITIAL_LOCK(&sl); } spin_mutex() { BOOST_MOVE_INITIAL_LOCK(&sl); }
void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); } void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); }
void unlock() { BOOST_CONTAINER_RELEASE_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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <utility> // container
#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>
#include <boost/container/allocator_traits.hpp> #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/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/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 { namespace boost {
@@ -50,7 +51,7 @@ namespace container_detail {
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
template<class A, class ICont> template<class Allocator, class ICont>
struct node_alloc_holder struct node_alloc_holder
{ {
//If the intrusive container is an associative container, obtain the predicate, which will //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, typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
predicate_type, container_detail::nat) 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 typename allocator_traits_type::value_type value_type;
typedef ICont intrusive_container; typedef ICont intrusive_container;
typedef typename ICont::value_type Node; typedef typename ICont::value_type Node;
@@ -70,13 +71,11 @@ struct node_alloc_holder
portable_rebind_alloc<Node>::type NodeAlloc; portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type; typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_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 typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator; typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
typedef typename node_allocator_traits_type::size_type size_type; typedef typename node_allocator_traits_type::size_type size_type;
typedef typename node_allocator_traits_type::difference_type difference_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, typedef container_detail::integral_constant<unsigned,
boost::container::container_detail:: boost::container::container_detail::
version<NodeAlloc>::value> alloc_version; version<NodeAlloc>::value> alloc_version;
@@ -152,7 +151,7 @@ struct node_alloc_holder
void deallocate_one(const NodePtr &p) void deallocate_one(const NodePtr &p)
{ AllocVersionTraits::deallocate_one(this->node_alloc(), p); } { AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class ...Args> template<class ...Args>
NodePtr create_node(Args &&...args) NodePtr create_node(Args &&...args)
@@ -169,28 +168,90 @@ struct node_alloc_holder
return (p); 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) \ template<BOOST_MOVE_CLASS1>
\ NodePtr create_node(BOOST_MOVE_UREF1)
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());
NodePtr p = this->allocate_one(); \ allocator_traits<NodeAlloc>::construct
Deallocator node_deallocator(p, this->node_alloc()); \ (this->node_alloc(), container_detail::addressof(p->m_data)
allocator_traits<NodeAlloc>::construct \ , BOOST_MOVE_FWD1);
(this->node_alloc(), container_detail::addressof(p->m_data) \ node_deallocator.release();
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ typedef typename Node::hook_type hook_type;
node_deallocator.release(); \ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
typedef typename Node::hook_type hook_type; \ return (p);
::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()
#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> template<class It>
NodePtr create_node_from_it(const It &it) NodePtr create_node_from_it(const It &it)
@@ -237,7 +298,7 @@ struct node_alloc_holder
Deallocator node_deallocator(NodePtr(), nalloc); Deallocator node_deallocator(NodePtr(), nalloc);
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0); container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
while(n--){ while(n--){
p = container_detail::to_raw_pointer(iterator_to_pointer(itbeg)); p = container_detail::iterator_to_raw_pointer(itbeg);
node_deallocator.set(p); node_deallocator.set(p);
++itbeg; ++itbeg;
//This can throw //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())); } { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
void clear(allocator_v2) void clear(version_2)
{ {
typename NodeAlloc::multiallocation_chain chain; typename NodeAlloc::multiallocation_chain chain;
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), 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); 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())); } { 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; typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
NodeAlloc & nalloc = this->node_alloc(); NodeAlloc & nalloc = this->node_alloc();
@@ -292,11 +353,11 @@ struct node_alloc_holder
} }
template<class Key, class Comparator> 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())); } { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
template<class Key, class Comparator> 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()); allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder()); 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. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP #ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
#define 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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.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/math_functions.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.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/core/no_exceptions_support.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <cstddef> #include <cstddef>
@@ -57,6 +58,10 @@ class private_node_pool_impl
< node_t, bi::base_hook<slist_hook_t> < node_t, bi::base_hook<slist_hook_t>
, bi::linear<true> , bi::linear<true>
, bi::constant_time_size<false> >::type blockslist_t; , 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: public:
//!Segment manager typedef //!Segment manager typedef
@@ -145,7 +150,7 @@ class private_node_pool_impl
nodelist_iterator backup_list_last = backup_list.before_begin(); nodelist_iterator backup_list_last = backup_list.before_begin();
//Execute the algorithm and get an iterator to the last value //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); (m_real_node_size*m_nodes_per_block, (size_type) alignment_of<node_t>::value);
while(it != itend){ while(it != itend){
@@ -205,7 +210,7 @@ class private_node_pool_impl
{ {
//check for memory leaks //check for memory leaks
BOOST_ASSERT(m_allocated==0); 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); (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 //We iterate though the NodeBlock list to free the memory
@@ -298,7 +303,7 @@ class private_node_pool_impl
{ {
BOOST_ASSERT(num_blocks > 0); BOOST_ASSERT(num_blocks > 0);
size_type blocksize = 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{ BOOST_TRY{
for(size_type i = 0; i != num_blocks; ++i){ for(size_type i = 0; i != num_blocks; ++i){

View File

@@ -26,16 +26,9 @@
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/move/adl_move_swap.hpp> //swap #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> #include <boost/move/utility_core.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
namespace boost { namespace boost {
namespace container { namespace container {
namespace container_detail { namespace container_detail {
@@ -167,37 +160,7 @@ struct pair
//template <class... Args1, class... Args2> //template <class... Args1, class... Args2>
// pair(piecewise_construct_t, tuple<Args1...> first_args, // pair(piecewise_construct_t, tuple<Args1...> first_args,
// tuple<Args2...> second_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 copy assignment
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p) 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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/iterator.hpp>
namespace boost { namespace boost {
namespace container { namespace container {

View File

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

View File

@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000. // (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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
@@ -8,10 +8,11 @@
// //
// See http://www.boost.org/libs/container for documentation. // 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 #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
@@ -19,219 +20,41 @@
# pragma once # pragma once
#endif #endif
#include <boost/container/detail/config_begin.hpp> #include <boost/move/detail/type_traits.hpp>
#include <boost/container/detail/workaround.hpp>
namespace boost { namespace boost {
namespace container { namespace container {
namespace container_detail { 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> } //namespace container_detail {
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 { } //namespace container {
} //namespace boost { } //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP #endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP

View File

@@ -30,8 +30,6 @@ namespace boost{
namespace container { namespace container {
namespace container_detail { namespace container_detail {
//using namespace boost;
template <class T, unsigned V> template <class T, unsigned V>
struct version_type struct version_type
: public container_detail::integral_constant<unsigned, V> : public container_detail::integral_constant<unsigned, V>
@@ -95,6 +93,11 @@ struct is_version
}; };
} //namespace container_detail { } //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 container {
} //namespace boost{ } //namespace boost{

View File

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

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_FLAT_MAP_HPP #ifndef BOOST_CONTAINER_FLAT_MAP_HPP
#define 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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.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/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/mpl.hpp>
#include <boost/container/detail/algorithm.hpp> //equal() #include <boost/container/detail/algorithm.hpp> //equal()
#include <boost/container/allocator_traits.hpp> // move
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.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 <boost/core/no_exceptions_support.hpp>
#include <utility> //pair
#include <functional> //less
#include <memory> //allocator
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list> #include <initializer_list>
#endif #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>). //! 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>). //! (e.g. <i>allocator< std::pair<Key, T> ></i>).
//! //!
//! flat_map is similar to std::map but it's implemented like an ordered vector. //! 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 Key is the key_type of the map
//! \tparam Value is the <code>mapped_type</code> //! \tparam Value is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). //! \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>). //! (e.g. <i>allocator< std::pair<Key, T> > </i>).
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #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 #else
template <class Key, class T, class Compare, class A> template <class Key, class T, class Compare, class Allocator>
#endif #endif
class flat_map class flat_map
{ {
@@ -104,14 +110,14 @@ class flat_map
std::pair<Key, T>, std::pair<Key, T>,
container_detail::select1st< std::pair<Key, T> >, container_detail::select1st< std::pair<Key, T> >,
Compare, Compare,
A> tree_t; Allocator> tree_t;
//This is the real tree stored here. It's based on a movable pair //This is the real tree stored here. It's based on a movable pair
typedef container_detail::flat_tree<Key, typedef container_detail::flat_tree<Key,
container_detail::pair<Key, T>, container_detail::pair<Key, T>,
container_detail::select1st<container_detail::pair<Key, T> >, container_detail::select1st<container_detail::pair<Key, T> >,
Compare, 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; <container_detail::pair<Key, T> >::type> impl_tree_t;
impl_tree_t m_flat_tree; // flat tree representing flat_map 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> > , container_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare_impl; , std::pair<Key, T> > value_compare_impl;
typedef typename container_detail::get_flat_tree_iterators 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 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 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 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 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public: public:
@@ -143,22 +149,22 @@ class flat_map
typedef Key key_type; typedef Key key_type;
typedef T mapped_type; typedef T mapped_type;
typedef std::pair<Key, T> value_type; typedef std::pair<Key, T> value_type;
typedef ::boost::container::allocator_traits<A> allocator_traits_type; typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer; typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference; typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference; typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type; typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type; typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef BOOST_CONTAINER_IMPDEF(A) stored_allocator_type; typedef BOOST_MOVE_IMPDEF(Allocator) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare; typedef Compare key_compare;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; typedef BOOST_MOVE_IMPDEF(reverse_iterator_impl) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; typedef BOOST_MOVE_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; typedef BOOST_MOVE_IMPDEF(impl_value_type) movable_value_type;
public: public:
////////////////////////////////////////////// //////////////////////////////////////////////
@@ -174,7 +180,7 @@ class flat_map
: m_flat_tree() : m_flat_tree()
{ {
//A type must be std::pair<Key, T> //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 //! <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)) : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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. //! <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)) : m_flat_tree(container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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 //! <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)) : m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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 //! <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) : m_flat_tree(ordered_range, first, last, comp, a)
{ {
//A type must be std::pair<Key, T> //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) #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)) : m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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 //! <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) : m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
{ {
//A type must be std::pair<Key, T> //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 #endif
@@ -271,7 +277,7 @@ class flat_map
: m_flat_tree(x.m_flat_tree) : m_flat_tree(x.m_flat_tree)
{ {
//A type must be std::pair<Key, T> //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. //! <b>Effects</b>: Move constructs a flat_map.
@@ -284,7 +290,7 @@ class flat_map
: m_flat_tree(boost::move(x.m_flat_tree)) : m_flat_tree(boost::move(x.m_flat_tree))
{ {
//A type must be std::pair<Key, T> //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. //! <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) : m_flat_tree(x.m_flat_tree, a)
{ {
//A type must be std::pair<Key, T> //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. //! <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) : m_flat_tree(boost::move(x.m_flat_tree), a)
{ {
//A type must be std::pair<Key, T> //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. //! <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 //! <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 //! 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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> 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)...)); } { 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 //! <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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> 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> return container_detail::force_copy<iterator>
(m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint) (m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
, boost::forward<Args>(args)...)); , boost::forward<Args>(args)...));
} }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return container_detail::force_copy< std::pair<iterator, bool> > \ {\
(m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ return container_detail::force_copy< std::pair<iterator, bool> >\
\ (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
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, _)) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique \ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
(container_detail::force_copy<impl_const_iterator>(hint) \ {\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ 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));\
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) }\
#include BOOST_PP_LOCAL_ITERATE() //
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 //! <b>Effects</b>: Inserts x if and only if there is no element in the container
//! with key equivalent to the key of x. //! 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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
std::pair<iterator,bool> insert(const value_type& x) 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))); } 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 //! <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 //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class K, class T, class C, class A> template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, A> > 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 { namespace container {
@@ -1061,7 +1072,7 @@ namespace container {
//! //!
//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). //! 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>). //! (e.g. <i>allocator< std::pair<Key, T> ></i>).
//! //!
//! flat_multimap is similar to std::multimap but it's implemented like an ordered vector. //! 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 Key is the key_type of the map
//! \tparam Value is the <code>mapped_type</code> //! \tparam Value is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). //! \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>). //! (e.g. <i>allocator< std::pair<Key, T> > </i>).
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #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 #else
template <class Key, class T, class Compare, class A> template <class Key, class T, class Compare, class Allocator>
#endif #endif
class flat_multimap class flat_multimap
{ {
@@ -1092,13 +1103,13 @@ class flat_multimap
std::pair<Key, T>, std::pair<Key, T>,
container_detail::select1st< std::pair<Key, T> >, container_detail::select1st< std::pair<Key, T> >,
Compare, Compare,
A> tree_t; Allocator> tree_t;
//This is the real tree stored here. It's based on a movable pair //This is the real tree stored here. It's based on a movable pair
typedef container_detail::flat_tree<Key, typedef container_detail::flat_tree<Key,
container_detail::pair<Key, T>, container_detail::pair<Key, T>,
container_detail::select1st<container_detail::pair<Key, T> >, container_detail::select1st<container_detail::pair<Key, T> >,
Compare, 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; <container_detail::pair<Key, T> >::type> impl_tree_t;
impl_tree_t m_flat_tree; // flat tree representing flat_map 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> > , container_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare_impl; , std::pair<Key, T> > value_compare_impl;
typedef typename container_detail::get_flat_tree_iterators 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 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 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 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 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public: public:
@@ -1130,22 +1141,22 @@ class flat_multimap
typedef Key key_type; typedef Key key_type;
typedef T mapped_type; typedef T mapped_type;
typedef std::pair<Key, T> value_type; typedef std::pair<Key, T> value_type;
typedef ::boost::container::allocator_traits<A> allocator_traits_type; typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer; typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference; typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference; typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type; typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type; typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef BOOST_CONTAINER_IMPDEF(A) stored_allocator_type; typedef BOOST_MOVE_IMPDEF(Allocator) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare; typedef Compare key_compare;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; typedef BOOST_MOVE_IMPDEF(reverse_iterator_impl) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; typedef BOOST_MOVE_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; typedef BOOST_MOVE_IMPDEF(impl_value_type) movable_value_type;
////////////////////////////////////////////// //////////////////////////////////////////////
// //
@@ -1160,7 +1171,7 @@ class flat_multimap
: m_flat_tree() : m_flat_tree()
{ {
//A type must be std::pair<Key, T> //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 //! <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)) : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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. //! <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)) : m_flat_tree(container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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 //! <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)) : m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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 //! <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) : m_flat_tree(ordered_range, first, last, comp, a)
{ {
//A type must be std::pair<Key, T> //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) #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)) : m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
{ {
//A type must be std::pair<Key, T> //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 //! <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) : m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
{ {
//A type must be std::pair<Key, T> //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 #endif
@@ -1257,7 +1268,7 @@ class flat_multimap
: m_flat_tree(x.m_flat_tree) : m_flat_tree(x.m_flat_tree)
{ {
//A type must be std::pair<Key, T> //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. //! <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)) : m_flat_tree(boost::move(x.m_flat_tree))
{ {
//A type must be std::pair<Key, T> //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. //! <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) : m_flat_tree(x.m_flat_tree, a)
{ {
//A type must be std::pair<Key, T> //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. //! <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) : m_flat_tree(boost::move(x.m_flat_tree), a)
{ {
//A type must be std::pair<Key, T> //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. //! <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 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)); } { 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 //! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the //! 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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> 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)...)); } { 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 //! <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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> 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 return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
(container_detail::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...)); (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) \ #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ iterator emplace(BOOST_MOVE_UREF##N)\
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal \ { return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ \
\ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
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_MOVE_I##N BOOST_MOVE_UREF##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\
{ 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));\
(container_detail::force_copy<impl_const_iterator>(hint) \ }\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ //
//! BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE
#include BOOST_PP_LOCAL_ITERATE()
#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 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
//! newly inserted element. //! newly inserted element.
@@ -1917,10 +1927,13 @@ namespace boost {
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class K, class T, class C, class A> template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T, C, A> > 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 { } //namespace boost {

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_FLAT_SET_HPP #ifndef BOOST_CONTAINER_FLAT_SET_HPP
#define 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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.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/flat_tree.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp> // move
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp> #include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
#include <utility> //pair // move/detail
#include <functional> //less #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <memory> //allocator #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) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list> #include <initializer_list>
#endif #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 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 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 #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 #else
template <class Key, class Compare, class A> template <class Key, class Compare, class Allocator>
#endif #endif
class flat_set class flat_set
///@cond ///@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 ///@endcond
{ {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private: private:
BOOST_COPYABLE_AND_MOVABLE(flat_set) 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 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public: public:
@@ -77,19 +84,19 @@ class flat_set
typedef Key value_type; typedef Key value_type;
typedef Compare key_compare; typedef Compare key_compare;
typedef Compare value_compare; typedef Compare value_compare;
typedef ::boost::container::allocator_traits<A> allocator_traits_type; typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; typedef typename BOOST_MOVE_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::const_reverse_iterator) const_reverse_iterator;
public: 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 //! <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 //! 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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> 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)...); } { return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with //! <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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> 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)...); } { 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) \ #define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\ { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
\ \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator p \ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
{ return this->base_t::emplace_hint_unique \ //
(p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE)
//! #undef BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x if and only if there is no element in the container //! <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 //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class Key, class C, class A> template <class Key, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_set<Key, C, A> > 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 { 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 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 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 #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 #else
template <class Key, class Compare, class A> template <class Key, class Compare, class Allocator>
#endif #endif
class flat_multiset class flat_multiset
///@cond ///@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 ///@endcond
{ {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private: private:
BOOST_COPYABLE_AND_MOVABLE(flat_multiset) 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 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public: public:
@@ -854,19 +862,19 @@ class flat_multiset
typedef Key value_type; typedef Key value_type;
typedef Compare key_compare; typedef Compare key_compare;
typedef Compare value_compare; typedef Compare value_compare;
typedef ::boost::container::allocator_traits<A> allocator_traits_type; typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; typedef typename BOOST_MOVE_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::const_reverse_iterator) const_reverse_iterator;
//! @copydoc ::boost::container::flat_set::flat_set() //! @copydoc ::boost::container::flat_set::flat_set()
explicit flat_multiset() 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 //! <b>Effects</b>: Inserts an object of type Key constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the //! 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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> template <class... Args>
iterator emplace(Args&&... args) iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); } { return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with //! <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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> 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)...); } { 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) \ #define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ iterator emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
\ \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator p \ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
{ return this->base_t::emplace_hint_equal \ //
(p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE)
//! #undef BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the //! <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 //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class Key, class C, class A> template <class Key, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C, A> > 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 { namespace container {

View File

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

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_MAP_HPP #ifndef BOOST_CONTAINER_MAP_HPP
#define BOOST_CONTAINER_MAP_HPP #define BOOST_CONTAINER_MAP_HPP
@@ -18,25 +17,31 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/container_fwd.hpp> #include <boost/container/container_fwd.hpp>
#include <boost/container/detail/tree.hpp> #include <boost/container/new_allocator.hpp> //new_allocator
#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/throw_exception.hpp> #include <boost/container/throw_exception.hpp>
#include <boost/move/utility_core.hpp> // container/detail
#include <boost/move/detail/move_helpers.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/move/traits.hpp> #include <boost/container/detail/tree.hpp>
#include <boost/static_assert.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/value_init.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 <boost/core/no_exceptions_support.hpp>
// std
#include <utility> //pair
#include <functional> //less
#include <memory> //allocator
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list> #include <initializer_list>
#endif #endif
@@ -55,22 +60,22 @@ namespace container {
//! by this container is the value_type is std::pair<const Key, T>. //! by this container is the value_type is std::pair<const Key, T>.
//! //!
//! \tparam Key is the key_type of the map //! \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 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>). //! (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. //! \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> 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 #else
template <class Key, class T, class Compare, class A, class MapOptions> template <class Key, class T, class Compare, class Allocator, class MapOptions>
#endif #endif
class map class map
///@cond ///@cond
: public container_detail::tree : public container_detail::tree
< Key, std::pair<const Key, T> < Key, std::pair<const Key, T>
, container_detail::select1st< std::pair<const Key, T> > , container_detail::select1st< std::pair<const Key, T> >
, Compare, A, MapOptions> , Compare, Allocator, MapOptions>
///@endcond ///@endcond
{ {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -79,7 +84,7 @@ class map
typedef std::pair<const Key, T> value_type_impl; typedef std::pair<const Key, T> value_type_impl;
typedef container_detail::tree 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::pair <Key, T> movable_value_type_impl;
typedef container_detail::tree_value_compare typedef container_detail::tree_value_compare
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
@@ -94,25 +99,25 @@ class map
////////////////////////////////////////////// //////////////////////////////////////////////
typedef Key key_type; 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 T mapped_type;
typedef std::pair<const Key, T> value_type; typedef std::pair<const Key, T> value_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer; typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference; typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference; typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type; typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type; typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare; typedef Compare key_compare;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; typedef typename BOOST_MOVE_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::const_reverse_iterator) const_reverse_iterator;
typedef std::pair<key_type, mapped_type> nonconst_value_type; 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() : base_t()
{ {
//A type must be std::pair<CONST Key, 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 //! <b>Effects</b>: Constructs an empty map using the specified comparison object
@@ -139,7 +144,7 @@ class map
: base_t(comp, a) : base_t(comp, a)
{ {
//A type must be std::pair<CONST Key, 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 allocator. //! <b>Effects</b>: Constructs an empty map using the specified allocator.
@@ -149,7 +154,7 @@ class map
: base_t(a) : base_t(a)
{ {
//A type must be std::pair<CONST Key, 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 and //! <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) : base_t(true, first, last, comp, a)
{ {
//A type must be std::pair<CONST Key, 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 and //! <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) : base_t(ordered_range, first, last, comp, a)
{ {
//A type must be std::pair<CONST Key, 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));
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -195,7 +200,7 @@ class map
: base_t(true, il.begin(), il.end(), comp, a) : base_t(true, il.begin(), il.end(), comp, a)
{ {
//A type must be std::pair<CONST Key, 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));
} }
map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(), 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) : base_t(ordered_range, il.begin(), il.end(), comp, a)
{ {
//A type must be std::pair<CONST Key, 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));
} }
#endif #endif
@@ -214,7 +219,7 @@ class map
: base_t(static_cast<const base_t&>(x)) : base_t(static_cast<const base_t&>(x))
{ {
//A type must be std::pair<CONST Key, 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>: Move constructs a map. Constructs *this using x's resources. //! <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)) : base_t(BOOST_MOVE_BASE(base_t, x))
{ {
//A type must be std::pair<CONST Key, 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>: Copy constructs a map using the specified allocator. //! <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) : base_t(static_cast<const base_t&>(x), a)
{ {
//A type must be std::pair<CONST Key, 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>: Move constructs a map using the specified allocator. //! <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) : base_t(BOOST_MOVE_BASE(base_t, x), a)
{ {
//A type must be std::pair<CONST Key, 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>: Makes *this a copy of x. //! <b>Effects</b>: Makes *this a copy of x.
@@ -598,7 +603,7 @@ class map
{ this->base_t::insert_unique(il.begin(), il.end()); } { this->base_t::insert_unique(il.begin(), il.end()); }
#endif #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 //! <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 //! 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 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p. //! is inserted right before p.
template <class... Args> 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)...); } { return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with //! <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 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p. //! is inserted right before p.
template <class... Args> 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)...); } { 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) \ #define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\ { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
\ \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator p \ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
{ return this->base_t::emplace_hint_unique(p \ //
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE)
//! #undef BOOST_CONTAINER_MAP_EMPLACE_CODE
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -835,10 +838,13 @@ class map
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class K, class T, class C, class A> template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::map<K, T, C, A> > 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 { namespace container {
@@ -859,20 +865,20 @@ namespace container {
//! \tparam Key is the key_type of the map //! \tparam Key is the key_type of the map
//! \tparam Value is the <code>mapped_type</code> //! \tparam Value is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). //! \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>). //! (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. //! \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> 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 #else
template <class Key, class T, class Compare, class A, class MultiMapOptions> template <class Key, class T, class Compare, class Allocator, class MultiMapOptions>
#endif #endif
class multimap class multimap
///@cond ///@cond
: public container_detail::tree : public container_detail::tree
< Key, std::pair<const Key, T> < Key, std::pair<const Key, T>
, container_detail::select1st< std::pair<const Key, T> > , container_detail::select1st< std::pair<const Key, T> >
, Compare, A, MultiMapOptions> , Compare, Allocator, MultiMapOptions>
///@endcond ///@endcond
{ {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -881,7 +887,7 @@ class multimap
typedef std::pair<const Key, T> value_type_impl; typedef std::pair<const Key, T> value_type_impl;
typedef container_detail::tree 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::pair <Key, T> movable_value_type_impl;
typedef container_detail::tree_value_compare typedef container_detail::tree_value_compare
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
@@ -898,22 +904,22 @@ class multimap
typedef Key key_type; typedef Key key_type;
typedef T mapped_type; typedef T mapped_type;
typedef std::pair<const Key, T> value_type; typedef std::pair<const Key, T> value_type;
typedef typename boost::container::allocator_traits<A>::pointer pointer; typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<A>::reference reference; typedef typename boost::container::allocator_traits<Allocator>::reference reference;
typedef typename boost::container::allocator_traits<A>::const_reference const_reference; typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::allocator_traits<A>::size_type size_type; typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<A>::difference_type difference_type; typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare;
typedef Compare key_compare; typedef Compare key_compare;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator;
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; typedef typename BOOST_MOVE_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::const_reverse_iterator) const_reverse_iterator;
typedef std::pair<key_type, mapped_type> nonconst_value_type; 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() : base_t()
{ {
//A type must be std::pair<CONST Key, 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. //! <b>Effects</b>: Constructs an empty multimap using the specified allocator.
@@ -938,7 +944,7 @@ class multimap
: base_t(comp, a) : base_t(comp, a)
{ {
//A type must be std::pair<CONST Key, 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 comparison //! <b>Effects</b>: Constructs an empty multimap using the specified comparison
@@ -949,7 +955,7 @@ class multimap
: base_t(a) : base_t(a)
{ {
//A type must be std::pair<CONST Key, 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 comparison object //! <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) : base_t(false, first, last, comp, a)
{ {
//A type must be std::pair<CONST Key, 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 comparison object and //! <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) : base_t(false, il.begin(), il.end(), comp, a)
{ {
//A type must be std::pair<CONST Key, 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));
} }
multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(), 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) : base_t(ordered_range, il.begin(), il.end(), comp, a)
{ {
//A type must be std::pair<CONST Key, 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));
} }
#endif #endif
@@ -1012,7 +1018,7 @@ class multimap
: base_t(static_cast<const base_t&>(x)) : base_t(static_cast<const base_t&>(x))
{ {
//A type must be std::pair<CONST Key, 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>: Move constructs a multimap. Constructs *this using x's resources. //! <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)) : base_t(BOOST_MOVE_BASE(base_t, x))
{ {
//A type must be std::pair<CONST Key, 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>: Copy constructs a multimap. //! <b>Effects</b>: Copy constructs a multimap.
@@ -1034,7 +1040,7 @@ class multimap
: base_t(static_cast<const base_t&>(x), a) : base_t(static_cast<const base_t&>(x), a)
{ {
//A type must be std::pair<CONST Key, 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>: Move constructs a multimap using the specified allocator. //! <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) : base_t(BOOST_MOVE_BASE(base_t, x), a)
{ {
//A type must be std::pair<CONST Key, 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>: Makes *this a copy of x. //! <b>Effects</b>: Makes *this a copy of x.
@@ -1130,7 +1136,7 @@ class multimap
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #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 //! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container. //! std::forward<Args>(args)... in the container.
@@ -1142,7 +1148,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p. //! is inserted right before p.
template <class... Args> template <class... Args>
iterator emplace(Args&&... args) iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); } { return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with //! <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 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p. //! is inserted right before p.
template <class... Args> 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)...); } { 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) \ #define BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE(N) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ iterator emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
\ \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint(const_iterator p \ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
{ return this->base_t::emplace_hint_equal(p \ //
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE)
//! #undef BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#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 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
//! newly inserted element. //! newly inserted element.
@@ -1388,10 +1392,13 @@ class multimap
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class K, class T, class C, class A> template <class Key, class T, class Compare, class Allocator>
struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, A> > 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 { 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/container/detail/singleton.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <utility>
#include <cstddef> #include <cstddef>
namespace boost { namespace boost {
@@ -145,7 +143,7 @@ class node_allocator
//!Throws std::bad_alloc if there is no enough memory //!Throws std::bad_alloc if there is no enough memory
pointer allocate(size_type count, const void * = 0) 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(); boost::container::throw_bad_alloc();
if(Version == 1 && count == 1){ if(Version == 1 && count == 1){
@@ -156,7 +154,7 @@ class node_allocator
} }
else{ else{
void *ret = boost_cont_malloc(count*sizeof(T)); void *ret = boost_cont_malloc(count*sizeof(T));
if(!ret) if(BOOST_UNLIKELY(!ret))
boost::container::throw_bad_alloc(); boost::container::throw_bad_alloc();
return static_cast<pointer>(ret); return static_cast<pointer>(ret);
} }
@@ -187,16 +185,12 @@ class node_allocator
singleton_t::instance().deallocate_free_blocks(); singleton_t::instance().deallocate_free_blocks();
} }
std::pair<pointer, bool> pointer allocation_command
allocation_command(allocation_type command, (allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
size_type limit_size,
size_type preferred_size,
size_type &received_size, pointer reuse = pointer())
{ {
BOOST_STATIC_ASSERT(( Version > 1 )); BOOST_STATIC_ASSERT(( Version > 1 ));
std::pair<pointer, bool> ret = pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
priv_allocation_command(command, limit_size, preferred_size, received_size, reuse); if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
boost::container::throw_bad_alloc(); boost::container::throw_bad_alloc();
return ret; return ret;
} }
@@ -263,7 +257,7 @@ class node_allocator
BOOST_STATIC_ASSERT(( Version > 1 )); BOOST_STATIC_ASSERT(( Version > 1 ));
boost_cont_memchain ch; boost_cont_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&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(); boost::container::throw_bad_alloc();
} }
chain.incorporate_after( chain.before_begin() chain.incorporate_after( chain.before_begin()
@@ -279,7 +273,7 @@ class node_allocator
BOOST_STATIC_ASSERT(( Version > 1 )); BOOST_STATIC_ASSERT(( Version > 1 ));
boost_cont_memchain ch; boost_cont_memchain ch;
boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &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(); boost::container::throw_bad_alloc();
} }
chain.incorporate_after( chain.before_begin() chain.incorporate_after( chain.before_begin()
@@ -315,23 +309,26 @@ class node_allocator
{ return false; } { return false; }
private: private:
std::pair<pointer, bool> priv_allocation_command pointer priv_allocation_command
(allocation_type command, std::size_t limit_size (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}; boost_cont_command_ret_t ret = {0 , 0};
if(limit_size > this->max_size() || preferred_size > this->max_size()){ if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
//ret.first = 0; return pointer();
return std::pair<pointer, bool>(pointer(), false);
} }
std::size_t l_size = limit_size*sizeof(T); std::size_t l_size = limit_size*sizeof(T);
std::size_t p_size = preferred_size*sizeof(T); std::size_t p_size = preferred_size*sizeof(T);
std::size_t r_size; 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); prefer_in_recvd_out_size = r_size/sizeof(T);
return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second); 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> #include <boost/container/detail/workaround.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp> #include <boost/move/detail/fwd_macros.hpp>
#include <boost/container/detail/type_traits.hpp>
#endif #endif
namespace boost { namespace container { namespace boost { namespace container {
@@ -51,10 +50,7 @@ namespace boost { namespace container {
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename OuterAlloc template <typename OuterAlloc, BOOST_MOVE_CLASSDFLT9>
BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
, BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
>
class scoped_allocator_adaptor; class scoped_allocator_adaptor;
#endif #endif
@@ -77,7 +73,7 @@ struct constructible_with_allocator_suffix;
template <class T> template <class T>
struct constructible_with_allocator_prefix; struct constructible_with_allocator_prefix;
template <typename T, typename Alloc> template <typename T, typename Allocator>
struct uses_allocator; struct uses_allocator;
}} // namespace boost { namespace container { }} // namespace boost { namespace container {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,135 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="7.10" Version="7.10"
Name="allocator_traits_test" Name="allocator_traits_test"
ProjectGUID="{5CE11C83-096A-84FE-4FA2-D3A6BA792002}" ProjectGUID="{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
Keyword="Win32Proj"> Keyword="Win32Proj">
<Platforms> <Platforms>
<Platform <Platform
Name="Win32"/> Name="Win32"/>
</Platforms> </Platforms>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug" OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/allocator_traits_test" IntermediateDirectory="Debug/allocator_traits_test"
ConfigurationType="1" ConfigurationType="1"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="../../../.." AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0" KeepComments="FALSE"
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="3" RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE" ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="4" WarningLevel="4"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/> DebugInformationFormat="3"/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="winmm.lib" AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/allocator_traits_test_d.exe" OutputFile="$(OutDir)/allocator_traits_test_d.exe"
LinkIncremental="1" LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib" AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/allocator_traits_test.pdb" ProgramDatabaseFile="$(OutDir)/allocator_traits_test.pdb"
SubSystem="1" SubSystem="1"
TargetMachine="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"
FixedBaseAddress="1"/> FixedBaseAddress="1"/>
<Tool <Tool
Name="VCMIDLTool"/> Name="VCMIDLTool"/>
<Tool <Tool
Name="VCPostBuildEventTool"/> Name="VCPostBuildEventTool"/>
<Tool <Tool
Name="VCPreBuildEventTool"/> Name="VCPreBuildEventTool"/>
<Tool <Tool
Name="VCPreLinkEventTool"/> Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool"/> Name="VCResourceCompilerTool"/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCWebServiceProxyGeneratorTool"/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCXMLDataGeneratorTool"/>
<Tool <Tool
Name="VCWebDeploymentTool"/> Name="VCWebDeploymentTool"/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCManagedWrapperGeneratorTool"/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
</Configurations> <Configuration
<References> Name="Release|Win32"
</References> OutputDirectory="../../Bin/Win32/Release"
<Files> IntermediateDirectory="Release/allocator_traits_test"
<Filter ConfigurationType="1"
Name="Source Files" CharacterSet="2">
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" <Tool
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}"> Name="VCCLCompilerTool"
<File AdditionalIncludeDirectories="../../../.."
RelativePath="..\..\test\allocator_traits_test.cpp"> PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
</File> RuntimeLibrary="2"
</Filter> TreatWChar_tAsBuiltInType="TRUE"
</Files> ForceConformanceInForLoopScope="FALSE"
<Globals> UsePrecompiledHeader="0"
</Globals> 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> </VisualStudioProject>

View File

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

View File

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

View File

@@ -1,136 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="7.10" Version="7.10"
Name="scoped_allocator_adaptor_test" Name="scoped_allocator_adaptor_test"
ProjectGUID="{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}" ProjectGUID="{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
Keyword="Win32Proj"> Keyword="Win32Proj">
<Platforms> <Platforms>
<Platform <Platform
Name="Win32"/> Name="Win32"/>
</Platforms> </Platforms>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug" OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/scoped_allocator_adaptor_test" IntermediateDirectory="Debug/scoped_allocator_adaptor_test"
ConfigurationType="1" ConfigurationType="1"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="../../../.." AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0" MinimalRebuild="TRUE"
MinimalRebuild="TRUE" BasicRuntimeChecks="3"
BasicRuntimeChecks="3" RuntimeLibrary="3"
RuntimeLibrary="3" TreatWChar_tAsBuiltInType="TRUE"
TreatWChar_tAsBuiltInType="TRUE" ForceConformanceInForLoopScope="FALSE"
ForceConformanceInForLoopScope="FALSE" UsePrecompiledHeader="0"
UsePrecompiledHeader="0" WarningLevel="4"
WarningLevel="4" Detect64BitPortabilityProblems="TRUE"
Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="3"/>
DebugInformationFormat="3"/> <Tool
<Tool Name="VCCustomBuildTool"/>
Name="VCCustomBuildTool"/> <Tool
<Tool Name="VCLinkerTool"
Name="VCLinkerTool" AdditionalDependencies="winmm.lib"
AdditionalDependencies="winmm.lib" OutputFile="$(OutDir)/scoped_allocator_adaptor_test_d.exe"
OutputFile="$(OutDir)/scoped_allocator_adaptor_test_d.exe" LinkIncremental="1"
LinkIncremental="1" AdditionalLibraryDirectories="../../../../stage/lib"
AdditionalLibraryDirectories="../../../../stage/lib" GenerateDebugInformation="TRUE"
GenerateDebugInformation="TRUE" ProgramDatabaseFile="$(OutDir)/scoped_allocator_adaptor_test.pdb"
ProgramDatabaseFile="$(OutDir)/scoped_allocator_adaptor_test.pdb" SubSystem="1"
SubSystem="1" TargetMachine="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"
FixedBaseAddress="1"/> FixedBaseAddress="1"/>
<Tool <Tool
Name="VCMIDLTool"/> Name="VCMIDLTool"/>
<Tool <Tool
Name="VCPostBuildEventTool"/> Name="VCPostBuildEventTool"/>
<Tool <Tool
Name="VCPreBuildEventTool"/> Name="VCPreBuildEventTool"/>
<Tool <Tool
Name="VCPreLinkEventTool"/> Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool"/> Name="VCResourceCompilerTool"/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCWebServiceProxyGeneratorTool"/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCXMLDataGeneratorTool"/>
<Tool <Tool
Name="VCWebDeploymentTool"/> Name="VCWebDeploymentTool"/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCManagedWrapperGeneratorTool"/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
</Configurations> <Configuration
<References> Name="Release|Win32"
</References> OutputDirectory="../../Bin/Win32/Release"
<Files> IntermediateDirectory="Release/scoped_allocator_adaptor_test"
<Filter ConfigurationType="1"
Name="Source Files" CharacterSet="2">
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" <Tool
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}"> Name="VCCLCompilerTool"
<File AdditionalIncludeDirectories="../../../.."
RelativePath="..\..\test\scoped_allocator_adaptor_test.cpp"> PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
</File> RuntimeLibrary="2"
</Filter> TreatWChar_tAsBuiltInType="TRUE"
</Files> ForceConformanceInForLoopScope="FALSE"
<Globals> UsePrecompiledHeader="0"
</Globals> 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> </VisualStudioProject>

View File

@@ -1,136 +1,136 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="7.10" Version="7.10"
Name="throw_exception_test" Name="throw_exception_test"
ProjectGUID="{5A8D91E0-FA57-284F-84FE-D3A6BA792002}" ProjectGUID="{5A8D91E0-FA57-284F-84FE-D3A6BA792002}"
Keyword="Win32Proj"> Keyword="Win32Proj">
<Platforms> <Platforms>
<Platform <Platform
Name="Win32"/> Name="Win32"/>
</Platforms> </Platforms>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug" OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/throw_exception_test" IntermediateDirectory="Debug/throw_exception_test"
ConfigurationType="1" ConfigurationType="1"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="../../../.." AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE" KeepComments="FALSE"
ExceptionHandling="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" ExceptionHandling="TRUE"
RuntimeLibrary="3" BasicRuntimeChecks="3"
TreatWChar_tAsBuiltInType="TRUE" RuntimeLibrary="3"
ForceConformanceInForLoopScope="FALSE" TreatWChar_tAsBuiltInType="TRUE"
UsePrecompiledHeader="0" ForceConformanceInForLoopScope="FALSE"
WarningLevel="4" UsePrecompiledHeader="0"
Detect64BitPortabilityProblems="TRUE" WarningLevel="4"
DebugInformationFormat="3"/> Detect64BitPortabilityProblems="TRUE"
<Tool DebugInformationFormat="3"/>
Name="VCCustomBuildTool"/> <Tool
<Tool Name="VCCustomBuildTool"/>
Name="VCLinkerTool" <Tool
AdditionalDependencies="winmm.lib" Name="VCLinkerTool"
OutputFile="$(OutDir)/throw_exception_test_d.exe" AdditionalDependencies="winmm.lib"
LinkIncremental="1" OutputFile="$(OutDir)/throw_exception_test_d.exe"
AdditionalLibraryDirectories="../../../../stage/lib" LinkIncremental="1"
GenerateDebugInformation="TRUE" AdditionalLibraryDirectories="../../../../stage/lib"
ProgramDatabaseFile="$(OutDir)/throw_exception_test.pdb" GenerateDebugInformation="TRUE"
SubSystem="1" ProgramDatabaseFile="$(OutDir)/throw_exception_test.pdb"
TargetMachine="1" SubSystem="1"
FixedBaseAddress="1" TargetMachine="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"
FixedBaseAddress="1"/> FixedBaseAddress="1"/>
<Tool <Tool
Name="VCMIDLTool"/> Name="VCMIDLTool"/>
<Tool <Tool
Name="VCPostBuildEventTool"/> Name="VCPostBuildEventTool"/>
<Tool <Tool
Name="VCPreBuildEventTool"/> Name="VCPreBuildEventTool"/>
<Tool <Tool
Name="VCPreLinkEventTool"/> Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool"/> Name="VCResourceCompilerTool"/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCWebServiceProxyGeneratorTool"/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCXMLDataGeneratorTool"/>
<Tool <Tool
Name="VCWebDeploymentTool"/> Name="VCWebDeploymentTool"/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCManagedWrapperGeneratorTool"/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
</Configurations> <Configuration
<References> Name="Release|Win32"
</References> OutputDirectory="../../Bin/Win32/Release"
<Files> IntermediateDirectory="Release/throw_exception_test"
<Filter ConfigurationType="1"
Name="Source Files" CharacterSet="2">
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" <Tool
UniqueIdentifier="{A1735C4B-7AC5-3542-C626-3A2AF6C0D762}"> Name="VCCLCompilerTool"
<File AdditionalIncludeDirectories="../../../.."
RelativePath="..\..\test\throw_exception_test.cpp"> PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
</File> RuntimeLibrary="2"
</Filter> TreatWChar_tAsBuiltInType="TRUE"
</Files> ForceConformanceInForLoopScope="FALSE"
<Globals> UsePrecompiledHeader="0"
</Globals> 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> </VisualStudioProject>

View File

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

View File

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

View File

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

View File

@@ -26,7 +26,7 @@ const Container &as_const(Container &c)
template<class Container> template<class Container>
bool test_nth_index_of(Container &c) bool test_nth_index_of(Container &c)
{ {
typename Container::iterator it; typename Container::iterator it;
typename Container::const_iterator cit; typename Container::const_iterator cit;
typename Container::size_type sz, csz; typename Container::size_type sz, csz;
//index 0 //index 0
@@ -43,7 +43,7 @@ bool test_nth_index_of(Container &c)
return false; return false;
if(csz != 0) if(csz != 0)
return false; return false;
//index size()/2 //index size()/2
const typename Container::size_type sz_div_2 = c.size()/2; const typename Container::size_type sz_div_2 = c.size()/2;
it = c.nth(sz_div_2); it = c.nth(sz_div_2);

View File

@@ -12,27 +12,7 @@
#define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER #define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <algorithm> #include <cstddef>
#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"
namespace boost{ namespace boost{
namespace container { namespace container {

View File

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

View File

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

View File

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

View File

@@ -17,14 +17,18 @@
#include <boost/container/detail/config_begin.hpp> #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/container_fwd.hpp>
#include <boost/container/throw_exception.hpp> #include <boost/container/throw_exception.hpp>
#include <boost/container/detail/addressof.hpp>
#include <boost/container/detail/allocation_type.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/container/detail/version_type.hpp>
#include <boost/move/adl_move_swap.hpp> #include <boost/move/adl_move_swap.hpp>
#include <boost/assert.hpp>
#include <memory> #include <memory>
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
@@ -117,35 +121,33 @@ class expand_bwd_test_allocator
//Experimental version 2 expand_bwd_test_allocator functions //Experimental version 2 expand_bwd_test_allocator functions
std::pair<pointer, bool> pointer allocation_command(boost::container::allocation_type command,
allocation_command(boost::container::allocation_type command, size_type limit_size,size_type &prefer_in_recvd_out_size,pointer &reuse)
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{ {
(void)preferred_size; (void)reuse; (void)command; (void)reuse; (void)command;
//This allocator only expands backwards! //This allocator only expands backwards!
assert(m_allocations == 0 || (command & boost::container::expand_bwd)); 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_allocations == 0){
if((m_offset + limit_size) > m_size){ if((m_offset + limit_size) > m_size){
assert(0); assert(0);
} }
++m_allocations; ++m_allocations;
return std::pair<pointer, bool>(mp_buffer + m_offset, false); reuse = 0;
return (mp_buffer + m_offset);
} }
else if(m_allocations == 1){ else if(m_allocations == 1){
if(limit_size > m_size){ if(limit_size > m_size){
assert(0); assert(0);
} }
++m_allocations; ++m_allocations;
return std::pair<pointer, bool>(mp_buffer, true); return mp_buffer;
} }
else{ else{
throw_bad_alloc(); 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 "expand_bwd_test_allocator.hpp"
#include <boost/container/detail/algorithm.hpp> //equal() #include <boost/container/detail/algorithm.hpp> //equal()
#include "movable_int.hpp" #include "movable_int.hpp"
#include <boost/type_traits/remove_volatile.hpp>
#include <boost/move/make_unique.hpp> #include <boost/move/make_unique.hpp>
namespace boost { namespace container { namespace test { namespace boost { namespace container { namespace test {
@@ -79,6 +78,9 @@ bool test_insert_with_expand_bwd()
{ 0, 100, 200 }; { 0, 100, 200 };
for(unsigned int pos = 0; pos < sizeof(Position)/sizeof(Position[0]); ++pos){ 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) for(unsigned int iteration = 0; iteration < Iterations; ++iteration)
{ {
boost::movelib::unique_ptr<char[]> memptr = boost::movelib::unique_ptr<char[]> memptr =
@@ -122,6 +124,8 @@ bool test_insert_with_expand_bwd()
return false; return false;
} }
} }
if(!life_count<value_type>::check(0))
return false;
} }
return true; return true;

View File

@@ -183,7 +183,7 @@ public:
flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::const_iterator cit_; flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::const_iterator cit_;
flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::reverse_iterator rit_; flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::reverse_iterator rit_;
flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::const_reverse_iterator crit_; flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::const_reverse_iterator crit_;
friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b) friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b)
{ return a.id_ < b.id_; } { return a.id_ < b.id_; }
}; };
@@ -199,17 +199,17 @@ void test_move()
move_assign.swap(original); move_assign.swap(original);
} }
template<class T, class A> template<class T, class Allocator>
class flat_map_propagate_test_wrapper class flat_map_propagate_test_wrapper
: public boost::container::flat_map : public boost::container::flat_map
< T, T, std::less<T> < 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> portable_rebind_alloc< std::pair<T, T> >::type>
{ {
BOOST_COPYABLE_AND_MOVABLE(flat_map_propagate_test_wrapper) BOOST_COPYABLE_AND_MOVABLE(flat_map_propagate_test_wrapper)
typedef boost::container::flat_map typedef boost::container::flat_map
< T, T, std::less<T> < 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; portable_rebind_alloc< std::pair<T, T> >::type> Base;
public: public:
flat_map_propagate_test_wrapper() flat_map_propagate_test_wrapper()
@@ -441,8 +441,8 @@ int main()
//Allocator argument container //Allocator argument container
{ {
flat_map<int, int> map_((std::allocator<std::pair<int, int> >())); flat_map<int, int> map_((flat_map<int, int>::allocator_type()));
flat_multimap<int, int> multimap_((std::allocator<std::pair<int, int> >())); flat_multimap<int, int> multimap_((flat_multimap<int, int>::allocator_type()));
} }
//Now test move semantics //Now test move semantics
{ {

View File

@@ -184,7 +184,7 @@ class recursive_flat_set
flat_set<recursive_flat_set>::const_iterator cit_; flat_set<recursive_flat_set>::const_iterator cit_;
flat_set<recursive_flat_set>::reverse_iterator rit_; flat_set<recursive_flat_set>::reverse_iterator rit_;
flat_set<recursive_flat_set>::const_reverse_iterator crit_; flat_set<recursive_flat_set>::const_reverse_iterator crit_;
friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b) friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b)
{ return a.id_ < b.id_; } { return a.id_ < b.id_; }
}; };
@@ -210,7 +210,7 @@ class recursive_flat_multiset
flat_multiset<recursive_flat_multiset>::const_iterator cit_; flat_multiset<recursive_flat_multiset>::const_iterator cit_;
flat_multiset<recursive_flat_multiset>::reverse_iterator rit_; flat_multiset<recursive_flat_multiset>::reverse_iterator rit_;
flat_multiset<recursive_flat_multiset>::const_reverse_iterator crit_; flat_multiset<recursive_flat_multiset>::const_reverse_iterator crit_;
friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b) friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
{ return a.id_ < b.id_; } { return a.id_ < b.id_; }
}; };
@@ -227,12 +227,12 @@ void test_move()
move_assign.swap(original); move_assign.swap(original);
} }
template<class T, class A> template<class T, class Allocator>
class flat_set_propagate_test_wrapper 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) 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: public:
flat_set_propagate_test_wrapper() flat_set_propagate_test_wrapper()
: Base() : Base()
@@ -524,8 +524,8 @@ int main()
//Allocator argument container //Allocator argument container
{ {
flat_set<int> set_((std::allocator<int>())); flat_set<int> set_((flat_set<int>::allocator_type()));
flat_multiset<int> multiset_((std::allocator<int>())); flat_multiset<int> multiset_((flat_multiset<int>::allocator_type()));
} }
//Now test move semantics //Now test move semantics
{ {

View File

@@ -64,7 +64,7 @@ public:
X& operator=(BOOST_COPY_ASSIGN_REF(X) x) X& operator=(BOOST_COPY_ASSIGN_REF(X) x)
{ {
i_ = x.i_; i_ = x.i_;
p_ = x.p_; p_ = x.p_;
// std::cout << "X& operator=(const X& x)\n"; // std::cout << "X& operator=(const X& x)\n";
@@ -82,7 +82,7 @@ public:
X& operator=(BOOST_RV_REF(X) x) BOOST_CONTAINER_NOEXCEPT X& operator=(BOOST_RV_REF(X) x) BOOST_CONTAINER_NOEXCEPT
{ {
i_ = x.i_; i_ = x.i_;
p_ = x.p_; p_ = x.p_;
// std::cout << "X& operator=(X&& x)\n"; // std::cout << "X& operator=(X&& x)\n";

View File

@@ -71,7 +71,7 @@ public:
list<recursive_list>::const_iterator cit_; list<recursive_list>::const_iterator cit_;
list<recursive_list>::reverse_iterator rit_; list<recursive_list>::reverse_iterator rit_;
list<recursive_list>::const_reverse_iterator crit_; list<recursive_list>::const_reverse_iterator crit_;
recursive_list &operator=(const recursive_list &o) recursive_list &operator=(const recursive_list &o)
{ list_ = o.list_; return *this; } { list_ = o.list_; return *this; }
}; };
@@ -207,3 +207,13 @@ int main ()
} }
#include <boost/container/detail/config_end.hpp> #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/iterator.hpp>
#include <boost/move/make_unique.hpp> #include <boost/move/make_unique.hpp>
#include <memory>
#include <list> #include <list>
#include <vector>
#include <functional> //std::greater #include <functional> //std::greater
#include <string>
namespace boost{ namespace boost{
namespace container { namespace container {

View File

@@ -13,7 +13,6 @@
#include <boost/container/node_allocator.hpp> #include <boost/container/node_allocator.hpp>
#include <boost/container/adaptive_pool.hpp> #include <boost/container/adaptive_pool.hpp>
#include <utility>
#include <map> #include <map>
#include "print_container.hpp" #include "print_container.hpp"
@@ -201,7 +200,7 @@ class recursive_map
map<recursive_map, recursive_map>::const_iterator cit_; map<recursive_map, recursive_map>::const_iterator cit_;
map<recursive_map, recursive_map>::reverse_iterator rit_; map<recursive_map, recursive_map>::reverse_iterator rit_;
map<recursive_map, recursive_map>::const_reverse_iterator crit_; map<recursive_map, recursive_map>::const_reverse_iterator crit_;
friend bool operator< (const recursive_map &a, const recursive_map &b) friend bool operator< (const recursive_map &a, const recursive_map &b)
{ return a.id_ < b.id_; } { return a.id_ < b.id_; }
}; };
@@ -218,7 +217,7 @@ class recursive_multimap
multimap<recursive_multimap, recursive_multimap>::const_iterator cit_; multimap<recursive_multimap, recursive_multimap>::const_iterator cit_;
multimap<recursive_multimap, recursive_multimap>::reverse_iterator rit_; multimap<recursive_multimap, recursive_multimap>::reverse_iterator rit_;
multimap<recursive_multimap, recursive_multimap>::const_reverse_iterator crit_; multimap<recursive_multimap, recursive_multimap>::const_reverse_iterator crit_;
friend bool operator< (const recursive_multimap &a, const recursive_multimap &b) friend bool operator< (const recursive_multimap &a, const recursive_multimap &b)
{ return a.id_ < b.id_; } { return a.id_ < b.id_; }
}; };
@@ -236,11 +235,11 @@ void test_move()
move_assign.swap(original); move_assign.swap(original);
} }
template<class T, class A> template<class T, class Allocator>
class map_propagate_test_wrapper class map_propagate_test_wrapper
: public boost::container::map : public boost::container::map
< T, T, std::less<T> < 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 portable_rebind_alloc< std::pair<const T, T> >::type
//tree_assoc_defaults //tree_assoc_defaults
> >
@@ -248,7 +247,7 @@ class map_propagate_test_wrapper
BOOST_COPYABLE_AND_MOVABLE(map_propagate_test_wrapper) BOOST_COPYABLE_AND_MOVABLE(map_propagate_test_wrapper)
typedef boost::container::map typedef boost::container::map
< T, T, std::less<T> < 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 portable_rebind_alloc< std::pair<const T, T> >::type
> Base; > Base;
public: public:
@@ -399,8 +398,8 @@ int main ()
} }
//Allocator argument container //Allocator argument container
{ {
map<int, int> map_((std::allocator<std::pair<const int, int> >())); map<int, int> map_((map<int, int>::allocator_type()));
multimap<int, int> multimap_((std::allocator<std::pair<const int, int> >())); multimap<int, int> multimap_((multimap<int, int>::allocator_type()));
} }
//Now test move semantics //Now test move semantics
{ {

View File

@@ -14,22 +14,22 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp" #include "check_equal_containers.hpp"
#include "print_container.hpp" #include "print_container.hpp"
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp> #include <boost/container/detail/pair.hpp>
#include <boost/move/iterator.hpp> #include <boost/move/iterator.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/move/make_unique.hpp> #include <boost/move/make_unique.hpp>
#include <utility> //std::pair #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <boost/intrusive/detail/has_member_function_callable_with.hpp> #include <boost/intrusive/detail/mpl.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 { 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>)) BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(has_member_rebalance, rebalance)
#include BOOST_PP_ITERATE()
}}}
template<class T1, class T2, class T3, class T4> template<class T1, class T2, class T3, class T4>
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2) bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
@@ -534,13 +534,13 @@ int map_test()
return 1; return 1;
map_test_rebalanceable(boostmap 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)){ if(!CheckEqualContainers(boostmap, stdmap)){
std::cout << "Error in boostmap.rebalance()" << std::endl; std::cout << "Error in boostmap.rebalance()" << std::endl;
return 1; return 1;
} }
map_test_rebalanceable(boostmultimap 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)){ if(!CheckEqualContainers(boostmultimap, stdmultimap)){
std::cout << "Error in boostmultimap.rebalance()" << std::endl; std::cout << "Error in boostmultimap.rebalance()" << std::endl;
return 1; return 1;

View File

@@ -22,14 +22,13 @@
#include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/mpl.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <cstring> #include <cstring>
#include <new> #include <new>
using namespace boost::container; 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_0x00;
static buffer_t buffer_0xFF; static buffer_t buffer_0xFF;

View File

@@ -12,33 +12,12 @@
#define BOOST_PRINTCONTAINER_HPP #define BOOST_PRINTCONTAINER_HPP
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <functional>
#include <iostream> #include <iostream>
#include <algorithm>
namespace boost{ namespace boost{
namespace container { namespace container {
namespace test{ 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 //Function to dump data
template<class MyBoostCont template<class MyBoostCont
,class MyStdCont> ,class MyStdCont>

View File

@@ -9,7 +9,6 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/scoped_allocator_fwd.hpp> #include <boost/container/scoped_allocator_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <cstddef> #include <cstddef>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
@@ -237,21 +236,22 @@ namespace container {
template<unsigned int AllocatorTag> template<unsigned int AllocatorTag>
struct constructible_with_allocator_prefix struct constructible_with_allocator_prefix
< ::mark_on_scoped_allocation<ConstructiblePrefix, AllocatorTag> > < ::mark_on_scoped_allocation<ConstructiblePrefix, AllocatorTag> >
: ::boost::true_type {
{}; static const bool value = true;
};
template<unsigned int AllocatorTag> template<unsigned int AllocatorTag>
struct constructible_with_allocator_suffix struct constructible_with_allocator_suffix
< ::mark_on_scoped_allocation<ConstructibleSuffix, AllocatorTag> > < ::mark_on_scoped_allocation<ConstructibleSuffix, AllocatorTag> >
: ::boost::true_type {
{}; static const bool value = true;
};
} //namespace container { } //namespace container {
} //namespace boost { } //namespace boost {
#include <boost/container/scoped_allocator.hpp> #include <boost/container/scoped_allocator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/container/vector.hpp> #include <boost/container/vector.hpp>
#include <boost/container/detail/pair.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 <boost/container/detail/config_begin.hpp>
#include <memory> #include <memory>
@@ -136,26 +145,26 @@ struct is_unique_assoc
static const bool value = false; static const bool value = false;
}; };
template<class K, class V, class C, class A> template<class Key, class T, class Compare, class Allocator>
struct is_unique_assoc< map<K, V, C, A> > struct is_unique_assoc< map<Key, T, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class K, class V, class C, class A> template<class Key, class T, class Compare, class Allocator>
struct is_unique_assoc< flat_map<K, V, C, A> > struct is_unique_assoc< flat_map<Key, T, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class V, class C, class A> template<class Key, class Compare, class Allocator>
struct is_unique_assoc< set<V, C, A> > struct is_unique_assoc< set<Key, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class V, class C, class A> template<class Key, class Compare, class Allocator>
struct is_unique_assoc< flat_set<V, C, A> > struct is_unique_assoc< flat_set<Key, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
@@ -171,26 +180,26 @@ struct is_map
static const bool value = false; static const bool value = false;
}; };
template<class K, class V, class C, class A> template<class Key, class T, class Compare, class Allocator>
struct is_map< map<K, V, C, A> > struct is_map< map<Key, T, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class K, class V, class C, class A> template<class Key, class T, class Compare, class Allocator>
struct is_map< flat_map<K, V, C, A> > struct is_map< flat_map<Key, T, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class K, class V, class C, class A> template<class Key, class T, class Compare, class Allocator>
struct is_map< multimap<K, V, C, A> > struct is_map< multimap<Key, T, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class K, class V, class C, class A> template<class Key, class T, class Compare, class Allocator>
struct is_map< flat_multimap<K, V, C, A> > struct is_map< flat_multimap<Key, T, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
@@ -201,26 +210,26 @@ struct is_set
static const bool value = false; static const bool value = false;
}; };
template<class V, class C, class A> template<class Key, class Compare, class Allocator>
struct is_set< set<V, C, A> > struct is_set< set<Key, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class V, class C, class A> template<class Key, class Compare, class Allocator>
struct is_set< flat_set<V, C, A> > struct is_set< flat_set<Key, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class V, class C, class A> template<class Key, class Compare, class Allocator>
struct is_set< multiset<V, C, A> > struct is_set< multiset<Key, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };
template<class V, class C, class A> template<class Key, class Compare, class Allocator>
struct is_set< flat_multiset<V, C, A> > struct is_set< flat_multiset<Key, Compare, Allocator> >
{ {
static const bool value = true; static const bool value = true;
}; };

View File

@@ -176,7 +176,7 @@ public:
set<recursive_set>::const_iterator cit_; set<recursive_set>::const_iterator cit_;
set<recursive_set>::reverse_iterator rit_; set<recursive_set>::reverse_iterator rit_;
set<recursive_set>::const_reverse_iterator crit_; set<recursive_set>::const_reverse_iterator crit_;
friend bool operator< (const recursive_set &a, const recursive_set &b) friend bool operator< (const recursive_set &a, const recursive_set &b)
{ return a.id_ < b.id_; } { return a.id_ < b.id_; }
}; };
@@ -194,7 +194,7 @@ class recursive_multiset
multiset<recursive_multiset>::const_iterator cit_; multiset<recursive_multiset>::const_iterator cit_;
multiset<recursive_multiset>::reverse_iterator rit_; multiset<recursive_multiset>::reverse_iterator rit_;
multiset<recursive_multiset>::const_reverse_iterator crit_; multiset<recursive_multiset>::const_reverse_iterator crit_;
friend bool operator< (const recursive_multiset &a, const recursive_multiset &b) friend bool operator< (const recursive_multiset &a, const recursive_multiset &b)
{ return a.id_ < b.id_; } { return a.id_ < b.id_; }
}; };
@@ -212,14 +212,14 @@ void test_move()
move_assign.swap(original); move_assign.swap(original);
} }
template<class T, class A> template<class T, class Allocator>
class set_propagate_test_wrapper 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 //tree_assoc_defaults
> >
{ {
BOOST_COPYABLE_AND_MOVABLE(set_propagate_test_wrapper) 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: public:
set_propagate_test_wrapper() set_propagate_test_wrapper()
: Base() : Base()
@@ -363,8 +363,8 @@ int main ()
} }
//Allocator argument container //Allocator argument container
{ {
set<int> set_((std::allocator<int>())); set<int> set_((set<int>::allocator_type()));
multiset<int> multiset_((std::allocator<int>())); multiset<int> multiset_((multiset<int>::allocator_type()));
} }
//Now test move semantics //Now test move semantics
{ {

View File

@@ -13,22 +13,17 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp" #include "check_equal_containers.hpp"
#include <memory>
#include <set>
#include <functional>
#include "print_container.hpp" #include "print_container.hpp"
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp> #include <boost/move/iterator.hpp>
#include <boost/move/make_unique.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_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_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>)) #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
#include BOOST_PP_ITERATE() #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
namespace boost{ namespace boost{
namespace container { namespace container {

View File

@@ -59,7 +59,7 @@ public:
slist<recursive_slist> slist_; slist<recursive_slist> slist_;
slist<recursive_slist>::iterator it_; slist<recursive_slist>::iterator it_;
slist<recursive_slist>::const_iterator cit_; slist<recursive_slist>::const_iterator cit_;
recursive_slist &operator=(const recursive_slist &o) recursive_slist &operator=(const recursive_slist &o)
{ slist_ = o.slist_; return *this; } { slist_ = o.slist_; return *this; }
}; };

View File

@@ -9,11 +9,7 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory> #include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/container/stable_vector.hpp> #include <boost/container/stable_vector.hpp>
#include <boost/container/allocator.hpp> #include <boost/container/allocator.hpp>
@@ -70,7 +66,7 @@ class recursive_vector
stable_vector<recursive_vector>::const_iterator cit_; stable_vector<recursive_vector>::const_iterator cit_;
stable_vector<recursive_vector>::reverse_iterator rit_; stable_vector<recursive_vector>::reverse_iterator rit_;
stable_vector<recursive_vector>::const_reverse_iterator crit_; stable_vector<recursive_vector>::const_reverse_iterator crit_;
recursive_vector &operator=(const recursive_vector &o) recursive_vector &operator=(const recursive_vector &o)
{ vector_ = o.vector_; return *this; } { vector_ = o.vector_; return *this; }
}; };

View File

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

View File

@@ -432,12 +432,12 @@ bool test_expand_bwd()
return test::test_all_expand_bwd<string_type>(); return test::test_all_expand_bwd<string_type>();
} }
template<class T, class A> template<class T, class Allocator>
class string_propagate_test_wrapper 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) 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: public:
string_propagate_test_wrapper() string_propagate_test_wrapper()
: Base() : Base()

View File

@@ -7,10 +7,8 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#include <memory> #include <memory>
#include <iostream> #include <iostream>
#include <functional>
#include <boost/container/vector.hpp> #include <boost/container/vector.hpp>
#include <boost/container/allocator.hpp> #include <boost/container/allocator.hpp>
@@ -252,3 +250,14 @@ int main()
return 0; 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 <boost/container/detail/config_begin.hpp>
#include <memory>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <functional>
#include <list> #include <list>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>