From 360957a797a2bde7e1623a6949d881c7eb9e923a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 2 Jan 2015 19:34:21 +0100 Subject: [PATCH] Massive dependency reduction. Removed dependency on several boost libraries and standard C++ headers. --- bench/bench_adaptive_node_pool.cpp | 10 +- bench/bench_alloc_expand_bwd.cpp | 12 +- bench/bench_alloc_expand_fwd.cpp | 36 +- bench/bench_alloc_shrink_to_fit.cpp | 12 +- ...h_alloc_stable_vector_burst_allocation.cpp | 22 +- bench/bench_set.hpp | 49 +- bench/bench_set_alloc_v2.cpp | 6 +- bench/detail/varray.hpp | 209 ++-- bench/detail/varray_util.hpp | 346 +++--- doc/Jamfile.v2 | 4 +- doc/container.qbk | 21 +- include/boost/container/adaptive_pool.hpp | 53 +- include/boost/container/allocator.hpp | 31 +- include/boost/container/allocator_traits.hpp | 287 ++--- include/boost/container/container_fwd.hpp | 35 +- include/boost/container/deque.hpp | 290 +++-- .../container/detail/adaptive_node_pool.hpp | 3 +- .../detail/adaptive_node_pool_impl.hpp | 20 +- include/boost/container/detail/addressof.hpp | 37 + .../container/detail/advanced_insert_int.hpp | 365 +++--- .../boost/container/detail/alloc_helpers.hpp | 56 + .../container/detail/allocation_type.hpp | 2 +- .../detail/allocator_version_traits.hpp | 68 +- .../container/detail/compare_functors.hpp | 4 +- .../boost/container/detail/config_begin.hpp | 21 +- .../container/detail/construct_in_place.hpp | 22 +- .../{utilities.hpp => copy_move_algo.hpp} | 439 +++---- include/boost/container/detail/destroyers.hpp | 132 +-- include/boost/container/detail/flat_tree.hpp | 158 ++- include/boost/container/detail/hash_table.hpp | 36 +- .../detail/iterator_to_raw_pointer.hpp | 54 + include/boost/container/detail/iterators.hpp | 64 +- .../boost/container/detail/memory_util.hpp | 62 - include/boost/container/detail/min_max.hpp | 33 + include/boost/container/detail/mpl.hpp | 6 + .../detail/multiallocation_chain.hpp | 12 +- include/boost/container/detail/mutex.hpp | 4 +- .../boost/container/detail/next_capacity.hpp | 71 ++ .../container/detail/node_alloc_holder.hpp | 167 ++- .../boost/container/detail/node_pool_impl.hpp | 25 +- include/boost/container/detail/pair.hpp | 39 +- .../boost/container/detail/preprocessor.hpp | 228 ---- .../boost/container/detail/to_raw_pointer.hpp | 29 + .../container/detail/transform_iterator.hpp | 1 + include/boost/container/detail/tree.hpp | 245 ++-- .../boost/container/detail/type_traits.hpp | 241 +--- .../boost/container/detail/version_type.hpp | 7 +- include/boost/container/detail/workaround.hpp | 4 +- include/boost/container/flat_map.hpp | 271 ++--- include/boost/container/flat_set.hpp | 181 +-- include/boost/container/list.hpp | 166 ++- include/boost/container/map.hpp | 245 ++-- include/boost/container/new_allocator.hpp | 164 +++ include/boost/container/node_allocator.hpp | 41 +- include/boost/container/scoped_allocator.hpp | 1019 ++++++----------- .../boost/container/scoped_allocator_fwd.hpp | 10 +- include/boost/container/set.hpp | 181 +-- include/boost/container/slist.hpp | 184 ++- include/boost/container/stable_vector.hpp | 164 +-- include/boost/container/static_vector.hpp | 33 +- include/boost/container/string.hpp | 363 +++--- include/boost/container/vector.hpp | 834 +++++--------- proj/vc7ide/alloc_lib.vcproj | 91 +- proj/vc7ide/allocator_traits_test.vcproj | 262 ++--- proj/vc7ide/container.vcproj | 32 +- proj/vc7ide/list_test.vcproj | 1 - proj/vc7ide/scoped_allocator_adaptor.vcproj | 262 +++-- proj/vc7ide/throw_exception_test.vcproj | 264 ++--- proj/vc7ide/vector_test.vcproj | 1 + test/alloc_full_test.cpp | 1 - test/allocator_traits_test.cpp | 170 ++- test/container_common_tests.hpp | 4 +- test/default_init_test.hpp | 22 +- test/deque_test.cpp | 2 - test/dummy_test_allocator.hpp | 28 +- test/emplace_test.hpp | 5 +- test/expand_bwd_test_allocator.hpp | 28 +- test/expand_bwd_test_template.hpp | 6 +- test/flat_map_test.cpp | 12 +- test/flat_set_test.cpp | 14 +- test/insert_vs_emplace_test.cpp | 4 +- test/list_test.cpp | 12 +- test/list_test.hpp | 3 - test/map_test.cpp | 15 +- test/map_test.hpp | 20 +- test/null_iterators_test.cpp | 3 +- test/print_container.hpp | 21 - test/scoped_allocator_adaptor_test.cpp | 12 +- test/scoped_allocator_usage_test.cpp | 57 +- test/set_test.cpp | 14 +- test/set_test.hpp | 13 +- test/slist_test.cpp | 2 +- test/stable_vector_test.cpp | 6 +- test/static_vector_test.hpp | 3 + test/string_test.cpp | 6 +- test/vector_test.cpp | 13 +- test/vector_test.hpp | 2 - 97 files changed, 4315 insertions(+), 5030 deletions(-) create mode 100644 include/boost/container/detail/addressof.hpp create mode 100644 include/boost/container/detail/alloc_helpers.hpp rename include/boost/container/detail/{utilities.hpp => copy_move_algo.hpp} (72%) create mode 100644 include/boost/container/detail/iterator_to_raw_pointer.hpp delete mode 100644 include/boost/container/detail/memory_util.hpp create mode 100644 include/boost/container/detail/min_max.hpp create mode 100644 include/boost/container/detail/next_capacity.hpp delete mode 100644 include/boost/container/detail/preprocessor.hpp create mode 100644 include/boost/container/detail/to_raw_pointer.hpp create mode 100644 include/boost/container/new_allocator.hpp diff --git a/bench/bench_adaptive_node_pool.cpp b/bench/bench_adaptive_node_pool.cpp index 4e4bb3f..2085c07 100644 --- a/bench/bench_adaptive_node_pool.cpp +++ b/bench/bench_adaptive_node_pool.cpp @@ -79,7 +79,7 @@ template class bc::node_allocator , bc::NodeAlloc_nodes_per_block , 2>; -template struct get_allocator_name; +template struct get_allocator_name; template<> struct get_allocator_name { static const char *get() { return "StdAllocator"; } }; @@ -124,10 +124,10 @@ class MyInt } }; -template +template void list_test_template(std::size_t num_iterations, std::size_t num_elements, bool csv_output) { - typedef typename A::template rebind::other IntAllocator; + typedef typename Allocator::template rebind::other IntAllocator; nanosecond_type tinsert, terase; boost_cont_malloc_stats_t insert_stats, erase_stats; std::size_t insert_inuse, erase_inuse; @@ -181,7 +181,7 @@ void list_test_template(std::size_t num_iterations, std::size_t num_elements, bo if(csv_output){ - std::cout << get_allocator_name::get() + std::cout << get_allocator_name::get() << ";" << num_iterations << ";" @@ -206,7 +206,7 @@ void list_test_template(std::size_t num_iterations, std::size_t num_elements, bo } else{ std::cout << std::endl - << "A: " << get_allocator_name::get() + << "Allocator: " << get_allocator_name::get() << std::endl << " allocation/deallocation(ns): " << float(tinsert)/(num_iterations*num_elements) << '\t' << float(terase)/(num_iterations*num_elements) << std::endl diff --git a/bench/bench_alloc_expand_bwd.cpp b/bench/bench_alloc_expand_bwd.cpp index 8b0c468..b598ede 100644 --- a/bench/bench_alloc_expand_bwd.cpp +++ b/bench/bench_alloc_expand_bwd.cpp @@ -32,7 +32,7 @@ typedef bc::allocator AllocatorPlusV2Ma typedef bc::allocator AllocatorPlusV2; typedef bc::allocator AllocatorPlusV1; -template struct get_allocator_name; +template struct get_allocator_name; template<> struct get_allocator_name { static const char *get() { return "StdAllocator"; } }; @@ -90,14 +90,14 @@ struct has_trivial_destructor_after_move void print_header() { std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";" - << "Capacity" << ";" << "push_back(ns)" << ";" << "A calls" << ";" + << "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";" << "New allocations" << ";" << "Bwd expansions" << std::endl; } -template +template void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output) { - typedef typename A::template rebind::other IntAllocator; + typedef typename Allocator::template rebind::other IntAllocator; unsigned int numalloc = 0, numexpand = 0; cpu_timer timer; @@ -132,7 +132,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements nanosecond_type nseconds = timer.elapsed().wall; if(csv_output){ - std::cout << get_allocator_name::get() + std::cout << get_allocator_name::get() << ";" << num_iterations << ";" @@ -151,7 +151,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements } else{ std::cout << std::endl - << "A: " << get_allocator_name::get() + << "Allocator: " << get_allocator_name::get() << std::endl << " push_back ns: " << float(nseconds)/(num_iterations*num_elements) diff --git a/bench/bench_alloc_expand_fwd.cpp b/bench/bench_alloc_expand_fwd.cpp index d25a771..b3108bc 100644 --- a/bench/bench_alloc_expand_fwd.cpp +++ b/bench/bench_alloc_expand_fwd.cpp @@ -35,7 +35,7 @@ typedef bc::allocator AllocatorPlusV2Ma typedef bc::allocator AllocatorPlusV2; typedef bc::allocator AllocatorPlusV1; -template struct get_allocator_name; +template struct get_allocator_name; template<> struct get_allocator_name { static const char *get() { return "StdAllocator"; } }; @@ -60,32 +60,32 @@ struct stats_traits; template<> struct stats_traits { - template - static void reset_alloc_stats(std::vector &) + template + static void reset_alloc_stats(std::vector &) {} - template - static std::size_t get_num_alloc(std::vector &) + template + static std::size_t get_num_alloc(std::vector &) { return 0; } - template - static std::size_t get_num_expand(std::vector &) + template + static std::size_t get_num_expand(std::vector &) { return 0; } }; template<> struct stats_traits { - template - static void reset_alloc_stats(bc::vector &v) + template + static void reset_alloc_stats(bc::vector &v) { v.reset_alloc_stats(); } - template - static std::size_t get_num_alloc(bc::vector &v) + template + static std::size_t get_num_alloc(bc::vector &v) { return v.num_alloc; } - template - static std::size_t get_num_expand(bc::vector &v) + template + static std::size_t get_num_expand(bc::vector &v) { return v.num_expand_fwd; } }; @@ -124,10 +124,10 @@ class MyInt } }; -template class Vector> +template class Vector> void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output) { - typedef typename A::template rebind::other IntAllocator; + typedef typename Allocator::template rebind::other IntAllocator; unsigned int numalloc = 0, numexpand = 0; #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS @@ -193,7 +193,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements nanosecond_type nseconds = timer.elapsed().wall; if(csv_output){ - std::cout << get_allocator_name::get() + std::cout << get_allocator_name::get() << ";" << num_iterations << ";" @@ -212,7 +212,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements } else{ std::cout << std::endl - << "A: " << get_allocator_name::get() + << "Allocator: " << get_allocator_name::get() << std::endl << " push_back ns: " << float(nseconds)/(num_iterations*num_elements) @@ -229,7 +229,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements void print_header() { std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";" - << "Capacity" << ";" << "push_back(ns)" << ";" << "A calls" << ";" + << "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";" << "New allocations" << ";" << "Fwd expansions" << std::endl; } diff --git a/bench/bench_alloc_shrink_to_fit.cpp b/bench/bench_alloc_shrink_to_fit.cpp index 61975d5..d8a9404 100644 --- a/bench/bench_alloc_shrink_to_fit.cpp +++ b/bench/bench_alloc_shrink_to_fit.cpp @@ -34,7 +34,7 @@ typedef std::allocator StdAllocator; typedef bc::allocator AllocatorPlusV2; typedef bc::allocator AllocatorPlusV1; -template struct get_allocator_name; +template struct get_allocator_name; template<> struct get_allocator_name { static const char *get() { return "StdAllocator"; } }; @@ -69,10 +69,10 @@ void print_header() << "num_shrink" << ";" << "shrink_to_fit(ns)" << std::endl; } -template +template void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output) { - typedef typename A::template rebind::other IntAllocator; + typedef typename Allocator::template rebind::other IntAllocator; unsigned int capacity = 0; const std::size_t Step = 5; @@ -84,7 +84,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements #ifndef NDEBUG typedef bc::container_detail::integral_constant - ::value> alloc_version; + ::value> alloc_version; #endif for(unsigned int r = 0; r != num_iterations; ++r){ @@ -105,7 +105,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements nanosecond_type nseconds = timer.elapsed().wall; if(csv_output){ - std::cout << get_allocator_name::get() + std::cout << get_allocator_name::get() << ";" << num_iterations << ";" @@ -118,7 +118,7 @@ void vector_test_template(unsigned int num_iterations, unsigned int num_elements } else{ std::cout << std::endl - << "A: " << get_allocator_name::get() + << "Allocator: " << get_allocator_name::get() << std::endl << " num_shrink: " << num_shrink << std::endl diff --git a/bench/bench_alloc_stable_vector_burst_allocation.cpp b/bench/bench_alloc_stable_vector_burst_allocation.cpp index 2b18f6a..cbbde70 100644 --- a/bench/bench_alloc_stable_vector_burst_allocation.cpp +++ b/bench/bench_alloc_stable_vector_burst_allocation.cpp @@ -41,7 +41,7 @@ typedef bc::adaptive_pool , 2 , 2> AdPool2PercentV2; -template struct get_allocator_name; +template struct get_allocator_name; template<> struct get_allocator_name { static const char *get() { return "StdAllocator"; } }; @@ -71,32 +71,32 @@ class MyInt } }; -template +template struct get_vector { typedef bc::vector - ::other> type; + ::other> type; static const char *vector_name() { return "vector"; } }; -template +template struct get_stable_vector { typedef bc::stable_vector - ::other> type; + ::other> type; static const char *vector_name() { return "stable_vector"; } }; -template class GetContainer, class A> +template class GetContainer, class Allocator> void stable_vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output) { - typedef typename GetContainer::type vector_type; + typedef typename GetContainer::type vector_type; //std::size_t top_capacity = 0; nanosecond_type nseconds; { @@ -113,9 +113,9 @@ void stable_vector_test_template(unsigned int num_iterations, unsigned int num_e nseconds = timer.elapsed().wall; if(csv_output){ - std::cout << get_allocator_name::get() + std::cout << get_allocator_name::get() << ";" - << GetContainer::vector_name() + << GetContainer::vector_name() << ";" << num_iterations << ";" @@ -125,9 +125,9 @@ void stable_vector_test_template(unsigned int num_iterations, unsigned int num_e << ";"; } else{ - std::cout << "Allocator: " << get_allocator_name::get() + std::cout << "Allocator: " << get_allocator_name::get() << '\t' - << GetContainer::vector_name() + << GetContainer::vector_name() << std::endl << " allocation ns: " << float(nseconds)/(num_iterations*num_elements); diff --git a/bench/bench_set.hpp b/bench/bench_set.hpp index 1e70250..b94c5a4 100644 --- a/bench/bench_set.hpp +++ b/bench/bench_set.hpp @@ -23,7 +23,6 @@ using boost::timer::cpu_timer; using boost::timer::cpu_times; using boost::timer::nanosecond_type; -using namespace boost::container; #ifdef NDEBUG static const std::size_t NElements = 1000; @@ -42,10 +41,10 @@ void compare_times(cpu_times time_numerator, cpu_times time_denominator){ std::cout << "----------------------------------------------" << '\n' << std::endl; } -vector sorted_unique_range_int; -vector sorted_range_int; -vector random_unique_range_int; -vector random_range_int; +boost::container::vector sorted_unique_range_int; +boost::container::vector sorted_range_int; +boost::container::vector random_unique_range_int; +boost::container::vector random_range_int; void fill_range_ints() { @@ -69,15 +68,15 @@ void fill_range_ints() std::random_shuffle(random_unique_range_int.begin(), random_unique_range_int.end()); } -vector sorted_unique_range_string; -vector sorted_range_string; -vector random_unique_range_string; -vector random_range_string; +boost::container::vector sorted_unique_range_string; +boost::container::vector sorted_range_string; +boost::container::vector random_unique_range_string; +boost::container::vector random_range_string; void fill_range_strings() { - string model_s; - model_s.append(sizeof(string), '*'); + boost::container::string model_s; + model_s.append(sizeof(boost::container::string), '*'); //sorted_unique_range_int sorted_unique_range_string.resize(NElements); @@ -111,7 +110,7 @@ struct range_provider; template<> struct range_provider { - typedef vector type; + typedef boost::container::vector type; static type &sorted_unique() { return sorted_unique_range_int; } @@ -127,9 +126,9 @@ struct range_provider }; template<> -struct range_provider +struct range_provider { - typedef vector type; + typedef boost::container::vector type; static type &sorted_unique() { return sorted_unique_range_string; } @@ -145,7 +144,7 @@ struct range_provider }; template -cpu_times copy_destroy_time(vector &unique_range) +cpu_times copy_destroy_time(boost::container::vector &unique_range) { cpu_timer copy_timer, assign_timer, destroy_timer; @@ -176,7 +175,9 @@ cpu_times copy_destroy_time(vector &unique_range) } template -cpu_times construct_time(vector &unique_range, vector &range, const char *RangeType) +cpu_times construct_time( boost::container::vector &unique_range + , boost::container::vector &range + , const char *RangeType) { cpu_timer sur_timer, sr_timer; @@ -206,7 +207,9 @@ cpu_times construct_time(vector &unique_range, vector -cpu_times insert_time(vector &unique_range, vector &range, const char *RangeType) +cpu_times insert_time( boost::container::vector &unique_range + , boost::container::vector &range + , const char *RangeType) { cpu_timer ur_timer,r_timer; ur_timer.stop();r_timer.stop(); @@ -240,7 +243,7 @@ cpu_times insert_time(vector &unique_range, vector -bool check_not_end(vector &iterators, Iterator itend, std::size_t number_of_ends = 0) +bool check_not_end(boost::container::vector &iterators, Iterator itend, std::size_t number_of_ends = 0) { std::size_t end_count = 0; for(std::size_t i = 0, max = iterators.size(); i != max; ++i){ @@ -251,7 +254,7 @@ bool check_not_end(vector &iterators, Iterator itend, std::size_t numb } template -bool check_all_not_empty(vector< std::pair > &iterator_pairs) +bool check_all_not_empty(boost::container::vector< std::pair > &iterator_pairs) { for(std::size_t i = 0, max = iterator_pairs.size(); i != max; ++i){ if(iterator_pairs[i].first == iterator_pairs[i].second) @@ -261,7 +264,7 @@ bool check_all_not_empty(vector< std::pair > &iterator_pair } template -cpu_times search_time(vector &unique_range, const char *RangeType) +cpu_times search_time(boost::container::vector &unique_range, const char *RangeType) { cpu_timer find_timer, lower_timer, upper_timer, equal_range_timer, count_timer; @@ -270,8 +273,8 @@ cpu_times search_time(vector &unique_range, const char * cpu_timer total_time; total_time.resume(); - vector v_it(NElements); - vector< std::pair > v_itp(NElements); + boost::container::vector v_it(NElements); + boost::container::vector< std::pair > v_itp(NElements); for(std::size_t i = 0; i != NIter; ++i){ //Find @@ -348,7 +351,7 @@ cpu_times search_time(vector &unique_range, const char * } template -void extensions_time(vector &sorted_unique_range) +void extensions_time(boost::container::vector &sorted_unique_range) { cpu_timer sur_timer,sur_opt_timer; sur_timer.stop();sur_opt_timer.stop(); diff --git a/bench/bench_set_alloc_v2.cpp b/bench/bench_set_alloc_v2.cpp index b927590..9c2fb9b 100644 --- a/bench/bench_set_alloc_v2.cpp +++ b/bench/bench_set_alloc_v2.cpp @@ -8,9 +8,9 @@ // ////////////////////////////////////////////////////////////////////////////// -#include "boost/container/set.hpp" -#include "boost/container/allocator.hpp" #include "bench_set.hpp" +#include +#include int main() { @@ -19,7 +19,7 @@ int main() fill_range_ints(); fill_range_strings(); - //set<..., allocator_v2> vs. set + //set<..., version_2> vs. set launch_tests< set, allocator >, set > ("set", "set"); launch_tests< set, allocator >, set > diff --git a/bench/detail/varray.hpp b/bench/detail/varray.hpp index f45765c..a1d1e8c 100644 --- a/bench/detail/varray.hpp +++ b/bench/detail/varray.hpp @@ -17,24 +17,25 @@ #include #include -#include + +#include #include //algo_equal(), algo_lexicographical_compare +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif #include #include +#include +#include #include //adl_move_swap + #include "varray_util.hpp" #include #include -#include - -#include - -#include -#include -#include +#include #ifndef BOOST_NO_EXCEPTIONS #include @@ -84,17 +85,17 @@ struct def //! //! This strategy defines the same types that are defined in the Allocator. //! -//! @tparam A The Allocator which will be adapted. -template +//! @tparam Allocator The Allocator which will be adapted. +template struct allocator_adaptor { - typedef typename A::value_type value_type; - typedef typename A::size_type size_type; - typedef typename A::difference_type difference_type; - typedef typename A::pointer pointer; - typedef typename A::const_pointer const_pointer; - typedef typename A::reference reference; - typedef typename A::const_reference const_reference; + typedef typename Allocator::value_type value_type; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef typename Allocator::pointer pointer; + typedef typename Allocator::const_pointer const_pointer; + typedef typename Allocator::reference reference; + typedef typename Allocator::const_reference const_reference; static void allocate_failed() { @@ -176,9 +177,9 @@ struct varray_traits typedef varray_error_handler error_handler; - typedef boost::false_type use_memop_in_swap_and_move; - typedef boost::false_type use_optimized_swap; - typedef boost::false_type disable_trivial_init; + typedef false_type use_memop_in_swap_and_move; + typedef false_type use_optimized_swap; + typedef false_type disable_trivial_init; }; /** @@ -220,18 +221,10 @@ class varray > vt; typedef typename vt::error_handler errh; - - BOOST_MPL_ASSERT_MSG( - ( boost::is_unsigned::value && - sizeof(typename boost::uint_value_t::least) <= sizeof(typename vt::size_type) ), - SIZE_TYPE_IS_TOO_SMALL_FOR_SPECIFIED_CAPACITY, - (varray) - ); - - typedef boost::aligned_storage< + typedef typename aligned_storage< sizeof(Value[Capacity]), - boost::alignment_of::value - > aligned_storage_type; + boost::container::container_detail::alignment_of::value + >::type aligned_storage_type; template friend class varray; @@ -1004,7 +997,7 @@ public: } #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE) -#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! @pre size() < capacity() //! //! @brief Inserts a Value constructed with @@ -1075,8 +1068,9 @@ public: ++m_size; // update end sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw - aligned_storage::value> temp_storage; - value_type * val_p = static_cast(temp_storage.address()); + typename aligned_storage + ::value>::type temp_storage; + value_type * val_p = static_cast(static_cast(&temp_storage)); sv::construct(dti(), val_p, ::boost::forward(args)...); // may throw sv::scoped_destructor d(val_p); sv::assign(position, ::boost::move(*val_p)); // may throw @@ -1085,63 +1079,51 @@ public: return position; } -#else // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_CONTAINER_DOXYGEN_INVOKED - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - typedef typename vt::disable_trivial_init dti; \ - \ - errh::check_capacity(*this, m_size + 1); /*may throw*/\ - \ - namespace sv = varray_detail; \ - sv::construct(dti(), this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\ - ++m_size; /*update end*/ \ - } \ - // - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_VARRAY_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + void emplace_back(BOOST_MOVE_UREF##N)\ + {\ + typedef typename vt::disable_trivial_init dti;\ + errh::check_capacity(*this, m_size + 1);/*may throw*/\ + \ + namespace sv = varray_detail;\ + sv::construct(dti(), this->end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\ + ++m_size; /*update end*/\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + typedef typename vt::disable_trivial_init dti;\ + namespace sv = varray_detail;\ + errh::check_iterator_end_eq(*this, position);\ + errh::check_capacity(*this, m_size + 1); /*may throw*/\ + if ( position == this->end() ){\ + sv::construct(dti(), position BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\ + ++m_size; /*update end*/\ + }\ + else{\ + /* TODO - should following lines check for exception and revert to the old size? */\ + /* TODO - should move be used only if it's nonthrowing? */\ + value_type & r = *(this->end() - 1);\ + sv::construct(dti(), this->end(), boost::move(r));/*may throw*/\ + ++m_size; /*update end*/\ + sv::move_backward(position, this->end() - 2, this->end() - 1);/*may throw*/\ + typename aligned_storage\ + ::value>::type temp_storage;\ + value_type * val_p = static_cast(static_cast(&temp_storage));\ + sv::construct(dti(), val_p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\ + sv::scoped_destructor d(val_p);\ + sv::assign(position, ::boost::move(*val_p));/*may throw*/\ + }\ + return position;\ + }\ + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VARRAY_EMPLACE_CODE) + #undef BOOST_CONTAINER_VARRAY_EMPLACE_CODE - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(iterator position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - typedef typename vt::disable_trivial_init dti; \ - namespace sv = varray_detail; \ - \ - errh::check_iterator_end_eq(*this, position); \ - errh::check_capacity(*this, m_size + 1); /*may throw*/\ - \ - if ( position == this->end() ) \ - { \ - sv::construct(dti(), position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\ - ++m_size; /*update end*/ \ - } \ - else \ - { \ - /* TODO - should following lines check for exception and revert to the old size? */ \ - /* TODO - should move be used only if it's nonthrowing? */ \ - \ - value_type & r = *(this->end() - 1); \ - sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\ - ++m_size; /*update end*/ \ - sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\ - \ - aligned_storage::value> temp_storage; \ - value_type * val_p = static_cast(temp_storage.address()); \ - sv::construct(dti(), val_p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\ - sv::scoped_destructor d(val_p); \ - sv::assign(position, ::boost::move(*val_p)); /*may throw*/\ - } \ - \ - return position; \ - } \ - // - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() - -#endif // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED +#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_CONTAINER_DOXYGEN_INVOKED #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE //! @brief Removes all elements from the container. @@ -1321,7 +1303,7 @@ public: //! Constant O(1). Value * data() { - return boost::addressof(*(this->ptr())); + return (addressof)(*(this->ptr())); } //! @brief Const pointer such that [data(), data() + size()) is a valid range. @@ -1334,7 +1316,7 @@ public: //! Constant O(1). const Value * data() const { - return boost::addressof(*(this->ptr())); + return (addressof)(*(this->ptr())); } @@ -1528,7 +1510,7 @@ private: // @par Complexity // Linear O(N). template - void move_ctor_dispatch(varray & other, boost::true_type /*use_memop*/) + void move_ctor_dispatch(varray & other, true_type /*use_memop*/) { ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size); m_size = other.m_size; @@ -1540,7 +1522,7 @@ private: // @par Complexity // Linear O(N). template - void move_ctor_dispatch(varray & other, boost::false_type /*use_memop*/) + void move_ctor_dispatch(varray & other, false_type /*use_memop*/) { namespace sv = varray_detail; sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw @@ -1552,7 +1534,7 @@ private: // @par Complexity // Linear O(N). template - void move_assign_dispatch(varray & other, boost::true_type /*use_memop*/) + void move_assign_dispatch(varray & other, true_type /*use_memop*/) { this->clear(); @@ -1566,7 +1548,7 @@ private: // @par Complexity // Linear O(N). template - void move_assign_dispatch(varray & other, boost::false_type /*use_memop*/) + void move_assign_dispatch(varray & other, false_type /*use_memop*/) { namespace sv = varray_detail; if ( m_size <= static_cast(other.size()) ) @@ -1588,18 +1570,18 @@ private: // @par Complexity // Linear O(N). template - void swap_dispatch(varray & other, boost::true_type const& /*use_optimized_swap*/) + void swap_dispatch(varray & other, true_type const& /*use_optimized_swap*/) { typedef typename - boost::mpl::if_c< + if_c< Capacity < C, aligned_storage_type, typename varray::aligned_storage_type >::type storage_type; - storage_type temp; - Value * temp_ptr = reinterpret_cast(temp.address()); + storage_type temp_storage; + value_type * temp_ptr = static_cast(static_cast(&temp_storage)); ::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size()); ::memcpy(this->data(), other.data(), sizeof(Value) * other.size()); @@ -1614,7 +1596,7 @@ private: // @par Complexity // Linear O(N). template - void swap_dispatch(varray & other, boost::false_type const& /*use_optimized_swap*/) + void swap_dispatch(varray & other, false_type const& /*use_optimized_swap*/) { namespace sv = varray_detail; @@ -1632,22 +1614,21 @@ private: // Nothing. // @par Complexity // Linear O(N). - void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::true_type const& /*use_memop*/) + void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, true_type const& /*use_memop*/) { //BOOST_ASSERT_MSG(boost::container::iterator_distance(first_sm, last_sm) <= boost::container::iterator_distance(first_la, last_la)); namespace sv = varray_detail; for (; first_sm != last_sm ; ++first_sm, ++first_la) { - boost::aligned_storage< + typename aligned_storage< sizeof(value_type), - boost::alignment_of::value - > temp_storage; - value_type * temp_ptr = reinterpret_cast(temp_storage.address()); - - ::memcpy(temp_ptr, boost::addressof(*first_sm), sizeof(value_type)); - ::memcpy(boost::addressof(*first_sm), boost::addressof(*first_la), sizeof(value_type)); - ::memcpy(boost::addressof(*first_la), temp_ptr, sizeof(value_type)); + alignment_of::value + >::type temp_storage; + value_type * temp_ptr = static_cast(static_cast(&temp_storage)); + ::memcpy(temp_ptr, (addressof)(*first_sm), sizeof(value_type)); + ::memcpy((addressof)(*first_sm), (addressof)(*first_la), sizeof(value_type)); + ::memcpy((addressof)(*first_la), temp_ptr, sizeof(value_type)); } ::memcpy(first_sm, first_la, sizeof(value_type) * boost::container::iterator_distance(first_la, last_la)); @@ -1657,7 +1638,7 @@ private: // If Value's move constructor or move assignment throws. // @par Complexity // Linear O(N). - void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::false_type const& /*use_memop*/) + void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, false_type const& /*use_memop*/) { //BOOST_ASSERT_MSG(boost::container::iterator_distance(first_sm, last_sm) <= boost::container::iterator_distance(first_la, last_la)); @@ -1860,12 +1841,12 @@ private: pointer ptr() { - return pointer(static_cast(m_storage.address())); + return pointer(static_cast(static_cast(&m_storage))); } const_pointer ptr() const { - return const_pointer(static_cast(m_storage.address())); + return pointer(static_cast(static_cast(&m_storage))); } size_type m_size; @@ -2091,8 +2072,8 @@ public: } // nothrow - Value * data() { return boost::addressof(*(this->ptr())); } - const Value * data() const { return boost::addressof(*(this->ptr())); } + Value * data() { return (addressof)(*(this->ptr())); } + const Value * data() const { return (addressof)(*(this->ptr())); } // nothrow iterator begin() { return this->ptr(); } diff --git a/bench/detail/varray_util.hpp b/bench/detail/varray_util.hpp index 04b9383..82917cc 100644 --- a/bench/detail/varray_util.hpp +++ b/bench/detail/varray_util.hpp @@ -17,26 +17,20 @@ #include #include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include #include -#include +#include + +#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +#include +#include + #include -#include +#include +#include // TODO - move vectors iterators optimization to the other, optional file instead of checking defines? @@ -47,22 +41,24 @@ namespace boost { namespace container { namespace varray_detail { +namespace bcd = ::boost::container::container_detail; + template -struct are_elements_contiguous : boost::is_pointer +struct are_elements_contiguous : boost::container::container_detail::is_pointer {}; #if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS) template struct are_elements_contiguous< - boost::container::container_detail::vector_const_iterator -> : boost::true_type + bcd::vector_const_iterator +> : bcd::true_type {}; template struct are_elements_contiguous< - boost::container::container_detail::vector_iterator -> : boost::true_type + bcd::vector_iterator +> : bcd::true_type {}; #if defined(BOOST_DINKUMWARE_STDLIB) @@ -70,21 +66,21 @@ struct are_elements_contiguous< template struct are_elements_contiguous< std::_Vector_const_iterator -> : boost::true_type +> : bcd::true_type {}; template struct are_elements_contiguous< std::_Vector_iterator -> : boost::true_type +> : bcd::true_type {}; #elif defined(BOOST_GNU_STDLIB) -template +template struct are_elements_contiguous< - __gnu_cxx::__normal_iterator > -> : boost::true_type + __gnu_cxx::__normal_iterator > +> : bcd::true_type {}; #elif defined(_LIBCPP_VERSION) @@ -93,7 +89,7 @@ struct are_elements_contiguous< //template //struct are_elements_contiguous< // __wrap_iter

-//> : boost::true_type +//> : bcd::true_type //{}; #else // OTHER_STDLIB @@ -104,46 +100,40 @@ struct are_elements_contiguous< #endif // BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS -}}} // namespace boost::container::varray_detail - -namespace boost { namespace container { namespace varray_detail { - template struct are_corresponding : - ::boost::mpl::and_< - ::boost::is_same< - ::boost::remove_const< + bcd::bool_< + bcd::is_same< + bcd::remove_const< typename ::boost::container::iterator_traits::value_type >, - ::boost::remove_const< + bcd::remove_const< typename ::boost::container::iterator_traits::value_type > - >, - are_elements_contiguous, - are_elements_contiguous + >::value && + are_elements_contiguous::value && + are_elements_contiguous::value > {}; template struct is_corresponding_value : - ::boost::is_same< - ::boost::remove_const< - typename ::boost::container::iterator_traits::value_type - >, - ::boost::remove_const - > + bcd::bool_< + bcd::is_same< + bcd::remove_const::value_type>, + bcd::remove_const + >::value + > {}; // destroy(I, I) template -void destroy_dispatch(I /*first*/, I /*last*/, - boost::true_type const& /*has_trivial_destructor*/) +void destroy_dispatch(I /*first*/, I /*last*/, bcd::true_type const& /*is_trivially_destructible*/) {} template -void destroy_dispatch(I first, I last, - boost::false_type const& /*has_trivial_destructor*/) +void destroy_dispatch(I first, I last, bcd::false_type const& /*is_trivially_destructible*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; for ( ; first != last ; ++first ) @@ -154,19 +144,19 @@ template void destroy(I first, I last) { typedef typename ::boost::container::iterator_traits::value_type value_type; - destroy_dispatch(first, last, has_trivial_destructor()); + destroy_dispatch(first, last, bcd::bool_::value>()); } // destroy(I) template void destroy_dispatch(I /*pos*/, - boost::true_type const& /*has_trivial_destructor*/) + bcd::true_type const& /*is_trivially_destructible*/) {} template 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::value_type value_type; pos->~value_type(); @@ -176,24 +166,22 @@ template void destroy(I pos) { typedef typename ::boost::container::iterator_traits::value_type value_type; - destroy_dispatch(pos, has_trivial_destructor()); + destroy_dispatch(pos, bcd::bool_::value>()); } // copy(I, I, O) template -inline O copy_dispatch(I first, I last, O dst, - boost::mpl::bool_ const& /*use_memmove*/) +inline O copy_dispatch(I first, I last, O dst, bcd::true_type const& /*use_memmove*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; const std::size_t d = boost::container::iterator_distance(first, last); - ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); + ::memmove(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type) * d); return dst + d; } template -inline O copy_dispatch(I first, I last, O dst, - boost::mpl::bool_ const& /*use_memmove*/) +inline O copy_dispatch(I first, I last, O dst, bcd::false_type const& /*use_memmove*/) { return std::copy(first, last, dst); // may throw } @@ -201,16 +189,12 @@ inline O copy_dispatch(I first, I last, O dst, template inline O copy(I first, I last, O dst) { - typedef typename - ::boost::mpl::and_< - are_corresponding, - ::boost::has_trivial_assign< - typename ::boost::container::iterator_traits::value_type - > - >::type - use_memmove; + typedef bcd::bool_ + < are_corresponding::value && + bcd::is_trivially_copy_assignable::value_type>::value + > use_memmove; - return copy_dispatch(first, last, dst, use_memmove()); // may throw + return copy_dispatch(first, last, dst, use_memmove()); // may throw } // uninitialized_copy(I, I, O) @@ -218,18 +202,18 @@ inline O copy(I first, I last, O dst) template inline O uninitialized_copy_dispatch(I first, I last, O dst, - boost::mpl::bool_ const& /*use_memcpy*/) + bcd::true_type const& /*use_memcpy*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; const std::size_t d = boost::container::iterator_distance(first, last); - ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); + ::memcpy(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type) * d); return dst + d; } template inline F uninitialized_copy_dispatch(I first, I last, F dst, - boost::mpl::bool_ const& /*use_memcpy*/) + bcd::false_type const& /*use_memcpy*/) { return std::uninitialized_copy(first, last, dst); // may throw } @@ -238,16 +222,11 @@ template inline F uninitialized_copy(I first, I last, F dst) { - typedef typename - ::boost::mpl::and_< - are_corresponding, - ::boost::has_trivial_copy< - typename ::boost::container::iterator_traits::value_type - > - >::type - use_memcpy; - - return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw + typedef bcd::bool_ + < are_corresponding::value && + bcd::is_trivially_copy_constructible::value_type>::value + > use_memcpy; + return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw } // uninitialized_move(I, I, O) @@ -255,18 +234,18 @@ F uninitialized_copy(I first, I last, F dst) template inline O uninitialized_move_dispatch(I first, I last, O dst, - boost::mpl::bool_ const& /*use_memcpy*/) + bcd::true_type const& /*use_memcpy*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; const std::size_t d = boost::container::iterator_distance(first, last); - ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); + ::memcpy(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type) * d); return dst + d; } template inline O uninitialized_move_dispatch(I first, I last, O dst, - boost::mpl::bool_ const& /*use_memcpy*/) + bcd::false_type const& /*use_memcpy*/) { //return boost::uninitialized_move(first, last, dst); // may throw @@ -276,7 +255,7 @@ O uninitialized_move_dispatch(I first, I last, O dst, { typedef typename boost::container::iterator_traits::value_type value_type; for (; first != last; ++first, ++o ) - new (boost::addressof(*o)) value_type(boost::move(*first)); + new (boost::container::container_detail::addressof(*o)) value_type(boost::move(*first)); } BOOST_CATCH(...) { @@ -292,15 +271,10 @@ template inline O uninitialized_move(I first, I last, O dst) { - typedef typename - ::boost::mpl::and_< - are_corresponding, - ::boost::has_trivial_copy< - typename ::boost::container::iterator_traits::value_type - > - >::type - use_memcpy; - + typedef bcd::bool_ + < are_corresponding::value && + bcd::is_trivially_copy_constructible::value_type>::value + > use_memcpy; return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw } @@ -311,18 +285,18 @@ O uninitialized_move(I first, I last, O dst) template inline O move_dispatch(I first, I last, O dst, - boost::mpl::bool_ const& /*use_memmove*/) + bcd::true_type const& /*use_memmove*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; const std::size_t d = boost::container::iterator_distance(first, last); - ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type)*d ); + ::memmove(boost::container::container_detail::addressof(*dst), boost::container::container_detail::addressof(*first), sizeof(value_type)*d ); return dst + d; } template inline O move_dispatch(I first, I last, O dst, - boost::mpl::bool_ const& /*use_memmove*/) + bcd::false_type const& /*use_memmove*/) { return boost::move(first, last, dst); // may throw } @@ -331,15 +305,10 @@ template inline O move(I first, I last, O dst) { - typedef typename - ::boost::mpl::and_< - are_corresponding, - ::boost::has_trivial_assign< - typename ::boost::container::iterator_traits::value_type - > - >::type - use_memmove; - + typedef bcd::bool_ + < are_corresponding::value && + bcd::is_trivially_copy_constructible::value_type>::value + > use_memmove; return move_dispatch(first, last, dst, use_memmove()); // may throw } @@ -348,19 +317,19 @@ O move(I first, I last, O dst) template inline BDO move_backward_dispatch(BDI first, BDI last, BDO dst, - boost::mpl::bool_ const& /*use_memmove*/) + bcd::true_type const& /*use_memmove*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; const std::size_t d = boost::container::iterator_distance(first, last); BDO foo(dst - d); - ::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d); + ::memmove(boost::container::container_detail::addressof(*foo), boost::container::container_detail::addressof(*first), sizeof(value_type) * d); return foo; } template inline BDO move_backward_dispatch(BDI first, BDI last, BDO dst, - boost::mpl::bool_ const& /*use_memmove*/) + bcd::false_type const& /*use_memmove*/) { return boost::move_backward(first, last, dst); // may throw } @@ -369,29 +338,21 @@ template inline BDO move_backward(BDI first, BDI last, BDO dst) { - typedef typename - ::boost::mpl::and_< - are_corresponding, - ::boost::has_trivial_assign< - typename ::boost::container::iterator_traits::value_type - > - >::type - use_memmove; - - return move_backward_dispatch(first, last, dst, use_memmove()); // may throw + typedef bcd::bool_ + < are_corresponding::value && + bcd::is_trivially_copy_constructible::value_type>::value + > use_memmove; + return move_backward_dispatch(first, last, dst, use_memmove()); // may throw } template struct has_nothrow_move : public - ::boost::mpl::or_< - boost::mpl::bool_< - ::boost::has_nothrow_move< - typename ::boost::remove_const::type - >::value - >, - boost::mpl::bool_< - ::boost::has_nothrow_move::value - > + bcd::bool_< + ::boost::has_nothrow_move< + typename bcd::remove_const::type + >::value + || + ::boost::has_nothrow_move::value > {}; @@ -399,21 +360,21 @@ struct has_nothrow_move : public template inline -O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) +O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, bcd::true_type const& /*use_move*/) { return uninitialized_move(first, last, dst); } template inline -O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) +O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, bcd::false_type const& /*use_move*/) { return uninitialized_copy(first, last, dst); } template inline O uninitialized_move_if_noexcept(I first, I last, O dst) { - typedef typename has_nothrow_move< + typedef has_nothrow_move< typename ::boost::container::iterator_traits::value_type - >::type use_move; + > use_move; return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw } @@ -422,21 +383,21 @@ O uninitialized_move_if_noexcept(I first, I last, O dst) template inline -O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) +O move_if_noexcept_dispatch(I first, I last, O dst, bcd::true_type const& /*use_move*/) { return move(first, last, dst); } template inline -O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) +O move_if_noexcept_dispatch(I first, I last, O dst, bcd::false_type const& /*use_move*/) { return copy(first, last, dst); } template inline O move_if_noexcept(I first, I last, O dst) { - typedef typename has_nothrow_move< + typedef has_nothrow_move< typename ::boost::container::iterator_traits::value_type - >::type use_move; + > use_move; return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw } @@ -446,25 +407,25 @@ O move_if_noexcept(I first, I last, O dst) template inline void uninitialized_fill_dispatch(I first, I last, - boost::true_type const& /*has_trivial_constructor*/, - boost::true_type const& /*disable_trivial_init*/) + bcd::true_type const& /*is_trivially_default_constructible*/, + bcd::true_type const& /*disable_trivial_init*/) {} template inline void uninitialized_fill_dispatch(I first, I last, - boost::true_type const& /*has_trivial_constructor*/, - boost::false_type const& /*disable_trivial_init*/) + bcd::true_type const& /*is_trivially_default_constructible*/, + bcd::false_type const& /*disable_trivial_init*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; for ( ; first != last ; ++first ) - new (boost::addressof(*first)) value_type(); + new (boost::container::container_detail::addressof(*first)) value_type(); } template inline void uninitialized_fill_dispatch(I first, I last, - boost::false_type const& /*has_trivial_constructor*/, + bcd::false_type const& /*is_trivially_default_constructible*/, DisableTrivialInit const& /*not_used*/) { typedef typename ::boost::container::iterator_traits::value_type value_type; @@ -473,7 +434,7 @@ void uninitialized_fill_dispatch(I first, I last, BOOST_TRY { for ( ; it != last ; ++it ) - new (boost::addressof(*it)) value_type(); // may throw + new (boost::container::container_detail::addressof(*it)) value_type(); // may throw } BOOST_CATCH(...) { @@ -488,22 +449,24 @@ inline void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init) { typedef typename ::boost::container::iterator_traits::value_type value_type; - uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor(), disable_trivial_init); // may throw + uninitialized_fill_dispatch(first, last + , bcd::bool_::value>() + , disable_trivial_init); // may throw } // construct(I) template inline -void construct_dispatch(boost::mpl::bool_ const& /*dont_init*/, I pos) +void construct_dispatch(bcd::true_type const& /*dont_init*/, I pos) {} template inline -void construct_dispatch(boost::mpl::bool_ const& /*dont_init*/, I pos) +void construct_dispatch(bcd::false_type const& /*dont_init*/, I pos) { typedef typename ::boost::container::iterator_traits::value_type value_type; - new (static_cast(::boost::addressof(*pos))) value_type(); // may throw + new (static_cast(::boost::container::container_detail::addressof(*pos))) value_type(); // may throw } template @@ -511,11 +474,10 @@ inline void construct(DisableTrivialInit const&, I pos) { typedef typename ::boost::container::iterator_traits::value_type value_type; - typedef typename ::boost::mpl::and_< - boost::has_trivial_constructor, - DisableTrivialInit - >::type dont_init; - + bcd::bool_< + bcd::is_trivially_default_constructible::value && + DisableTrivialInit::value + > dont_init; construct_dispatch(dont_init(), pos); // may throw } @@ -523,34 +485,29 @@ void construct(DisableTrivialInit const&, I pos) template inline -void construct_dispatch(I pos, V const& v, - boost::mpl::bool_ const& /*use_memcpy*/) +void construct_dispatch(I pos, V const& v, bcd::true_type const& /*use_memcpy*/) { - ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); + ::memcpy(boost::container::container_detail::addressof(*pos), boost::container::container_detail::addressof(v), sizeof(V)); } template inline void construct_dispatch(I pos, P const& p, - boost::mpl::bool_ const& /*use_memcpy*/) + bcd::false_type const& /*use_memcpy*/) { typedef typename ::boost::container::iterator_traits::value_type V; - new (static_cast(boost::addressof(*pos))) V(p); // may throw + new (static_cast(boost::container::container_detail::addressof(*pos))) V(p); // may throw } template inline -void construct(DisableTrivialInit const&, - I pos, P const& p) +void construct(DisableTrivialInit const&, I pos, P const& p) { - typedef typename - ::boost::mpl::and_< - is_corresponding_value, - ::boost::has_trivial_copy

- >::type - use_memcpy; - - construct_dispatch(pos, p, use_memcpy()); // may throw + typedef bcd::bool_ + < is_corresponding_value::value && + bcd::is_trivially_copy_constructible

::value + > use_memcpy; + construct_dispatch(pos, p, use_memcpy()); // may throw } // Needed by push_back(V &&) @@ -560,13 +517,13 @@ inline void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p) { typedef typename ::boost::container::iterator_traits::value_type V; - new (static_cast(boost::addressof(*pos))) V(::boost::move(p)); // may throw + new (static_cast(boost::container::container_detail::addressof(*pos))) V(::boost::move(p)); // may throw } // Needed by emplace_back() and emplace() #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE) -#if !defined(BOOST_NO_VARIADIC_TEMPLATES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template inline @@ -575,33 +532,27 @@ void construct(DisableTrivialInit const&, BOOST_FWD_REF(Args) ...args) { typedef typename ::boost::container::iterator_traits::value_type V; - new (static_cast(boost::addressof(*pos))) V(::boost::forward(args)...); // may throw + new (static_cast(boost::container::container_detail::addressof(*pos))) V(::boost::forward(args)...); // may throw } -#else // !BOOST_NO_VARIADIC_TEMPLATES +#else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES // BOOST_NO_RVALUE_REFERENCES -> P0 const& p0 // !BOOST_NO_RVALUE_REFERENCES -> P0 && p0 // which means that version with one parameter may take V const& v -#define BOOST_PP_LOCAL_MACRO(n) \ -template \ -inline \ -void construct(DisableTrivialInit const&, \ - I pos, \ - BOOST_CONTAINER_PP_PARAM(P, p) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - typedef typename ::boost::container::iterator_traits::value_type V; \ - new \ - (static_cast(boost::addressof(*pos))) \ - V(p, BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); /*may throw*/ \ -} \ -// -#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) -#include BOOST_PP_LOCAL_ITERATE() +#define BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE(N) \ +template \ +inline void construct(DisableTrivialInit const&, I pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\ +{\ + typedef typename ::boost::container::iterator_traits::value_type V;\ + new (static_cast(boost::container::container_detail::addressof(*pos)))\ + V(boost::container::container_detail::addressof(*pos) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/\ +} +BOOST_MOVE_ITERATE_2TO9(BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE) +#undef BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE -#endif // !BOOST_NO_VARIADIC_TEMPLATES +#endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE // assign(I, V) @@ -609,15 +560,15 @@ void construct(DisableTrivialInit const&, template inline void assign_dispatch(I pos, V const& v, - boost::mpl::bool_ 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 inline void assign_dispatch(I pos, V const& v, - boost::mpl::bool_ const& /*use_memcpy*/) + bcd::false_type const& /*use_memcpy*/) { *pos = v; // may throw } @@ -626,14 +577,11 @@ template inline void assign(I pos, V const& v) { - typedef typename - ::boost::mpl::and_< - is_corresponding_value, - ::boost::has_trivial_assign - >::type - use_memcpy; - - assign_dispatch(pos, v, use_memcpy()); // may throw + typedef bcd::bool_ + < is_corresponding_value::value && + bcd::is_trivially_copy_assignable::value + > use_memcpy; + assign_dispatch(pos, v, use_memcpy()); // may throw } template diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 4118511..8b2ffe9 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -27,7 +27,7 @@ doxygen autodoc MACRO_EXPANSION=YES "PREDEFINED=\"insert_const_ref_type= const T&\" \\ \"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\ - \"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\ + \"BOOST_MOVE_IMPDEF(T)=implementation_defined\" \\ \"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\ \"BOOST_CONTAINER_NOEXCEPT=noexcept\" \\ \"BOOST_CONTAINER_NOEXCEPT_IF(T)=noexcept(T)\" \\ @@ -41,6 +41,8 @@ doxygen autodoc \"BOOST_CONTAINER_DOC1ST(T1, T2)=T1\" \\ \"BOOST_CONTAINER_DOCIGN(T) \"\\ \"BOOST_CONTAINER_DOCONLY(T) T\"\\ + \"BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE=\"\\ + \"BOOST_CONTAINER_SCOPEDALLOC_ALLINNER=InnerAllocs...\"\\ " "boost.doxygen.reftitle=Boost.Container Header Reference" ; diff --git a/doc/container.qbk b/doc/container.qbk index 0f4da15..b78921e 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -729,7 +729,7 @@ are movable, requirements for `value_type` are those specified for C++11 contain For compilers with variadic templates, [*Boost.Container] supports placement insertion (`emplace`, ...) functions from C++11. For those compilers without variadic templates support [*Boost.Container] uses the preprocessor to create a set of overloads up to -a finite (10) number of parameters. +a finite number of parameters. [endsect] @@ -777,7 +777,8 @@ is the outer allocator for use by the container, the second allocator is passed container's elements, and, if the elements themselves are containers, the third allocator is passed to the elements' elements, and so on. -[*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also +[*Boost.Container] implements its own [classref boost::container::scoped_allocator_adaptor scoped_allocator_adaptor] +class and [*backports this feature also to C++03 compilers]. Due to C++03 limitations, in those compilers the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions will be based on traits ([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix] @@ -791,12 +792,12 @@ will be used to detect if the allocator must be propagated with suffix or prefix [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] [@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] -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]]: * `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 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 the container. Using references to inserted elements yields to undefined behaviour (although in debug mode, this 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 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 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_boost_1_58_00 Boost 1.58 Release] +* Massive dependency reorganization. Now [*Boost.Container depends on very basic utilities like Boost.Core + and [*Boost.Intrusive]. Preprocessed code size have decreased considerably and compilation times have improved. * Added `nth` and `index_of` functions to containers with random-access iterators (except `basic_string`). * Fixed bugs: * [@https://svn.boost.org/trac/boost/ticket/10790 Trac #10790 (['long long errors from container"])]. * [@https://svn.boost.org/trac/boost/ticket/10808 Trac #10808 (['compare equal operator of vector is broken"])]. +* [*Source Breaking]: [classref boost::container::scoped_allocator_adaptor scoped_allocator_adaptor]'s + `propagate_on_container_copy_assignment`, `propagate_on_container_move_assignment` and `propagate_on_container_swap` + are no longer `::boost::integral_constant` 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::propagate_on_container_move_assignment::value>`. [endsect] diff --git a/include/boost/container/adaptive_pool.hpp b/include/boost/container/adaptive_pool.hpp index 02af997..abe9067 100644 --- a/include/boost/container/adaptive_pool.hpp +++ b/include/boost/container/adaptive_pool.hpp @@ -25,14 +25,11 @@ #include #include #include - #include #include -#include #include #include -#include #include @@ -56,7 +53,7 @@ template < class T , std::size_t NodesPerBlock BOOST_CONTAINER_DOCONLY(= ADP_nodes_per_block) , std::size_t MaxFreeBlocks BOOST_CONTAINER_DOCONLY(= ADP_max_free_blocks) , std::size_t OverheadPercent BOOST_CONTAINER_DOCONLY(= ADP_overhead_percent) - BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I unsigned Version) + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I unsigned Version) > class adaptive_pool { @@ -66,7 +63,7 @@ class adaptive_pool typedef unsigned int allocation_type; typedef adaptive_pool self_t; static const std::size_t nodes_per_block = NodesPerBlock; @@ -109,7 +106,7 @@ class adaptive_pool , NodesPerBlock , MaxFreeBlocks , OverheadPercent - BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I Version) + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version) > other; }; @@ -137,7 +134,7 @@ class adaptive_pool template adaptive_pool (const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)> &) BOOST_CONTAINER_NOEXCEPT {} //!Destructor @@ -153,7 +150,7 @@ class adaptive_pool //!Throws std::bad_alloc if there is no enough memory pointer allocate(size_type count, const void * = 0) { - if(count > this->max_size()) + if(BOOST_UNLIKELY(count > this->max_size())) boost::container::throw_bad_alloc(); if(Version == 1 && count == 1){ @@ -183,15 +180,13 @@ class adaptive_pool } } - std::pair - allocation_command(allocation_type command, + pointer allocation_command(allocation_type command, size_type limit_size, - size_type preferred_size, - size_type &received_size, pointer reuse = pointer()) + size_type &prefer_in_recvd_out_size, + pointer &reuse) { - std::pair ret = - this->priv_allocation_command(command, limit_size, preferred_size, received_size, reuse); - if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)) + pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); + if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))) boost::container::throw_bad_alloc(); return ret; } @@ -254,14 +249,15 @@ class adaptive_pool BOOST_STATIC_ASSERT(( Version > 1 ));/* boost_cont_memchain ch; BOOST_CONTAINER_MEMCHAIN_INIT(&ch); - if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){ + if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){ boost::container::throw_bad_alloc(); } chain.incorporate_after(chain.before_begin() ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch) ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/ - if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast(&chain))){ + if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes + (n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast(&chain)))){ boost::container::throw_bad_alloc(); } } @@ -273,14 +269,15 @@ class adaptive_pool BOOST_STATIC_ASSERT(( Version > 1 ));/* boost_cont_memchain ch; BOOST_CONTAINER_MEMCHAIN_INIT(&ch); - if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){ + if(BOOST_UNLIKELY(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){ boost::container::throw_bad_alloc(); } chain.incorporate_after(chain.before_begin() ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch) ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch) ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/ - if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast(&chain))){ + if(BOOST_UNLIKELY(!boost_cont_multialloc_arrays + (n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast(&chain)))){ boost::container::throw_bad_alloc(); } } @@ -320,23 +317,25 @@ class adaptive_pool { return false; } private: - std::pair priv_allocation_command + pointer priv_allocation_command (allocation_type command, std::size_t limit_size - ,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr) + ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr) { + std::size_t const preferred_size = prefer_in_recvd_out_size; boost_cont_command_ret_t ret = {0 , 0}; - if(limit_size > this->max_size() || preferred_size > this->max_size()){ -// ret.first = 0; - return std::pair(pointer(), false); + if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){ + return pointer(); } std::size_t l_size = limit_size*sizeof(T); std::size_t p_size = preferred_size*sizeof(T); std::size_t r_size; { - ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr); + void* reuse_ptr_void = reuse_ptr; + ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void); + reuse_ptr = ret.second ? static_cast(reuse_ptr_void) : 0; } - received_size = r_size/sizeof(T); - return std::pair(static_cast(ret.first), !!ret.second); + prefer_in_recvd_out_size = r_size/sizeof(T); + return (pointer)ret.first; } }; diff --git a/include/boost/container/allocator.hpp b/include/boost/container/allocator.hpp index 14d5645..c5e4b06 100644 --- a/include/boost/container/allocator.hpp +++ b/include/boost/container/allocator.hpp @@ -25,7 +25,6 @@ #include #include #include -#include namespace boost { namespace container { @@ -218,18 +217,16 @@ class allocator //!capabilities. Memory allocated with this function can only be deallocated with deallocate() //!or deallocate_many(). //!This function is available only with Version == 2 - std::pair - allocation_command(allocation_type command, + pointer allocation_command(allocation_type command, size_type limit_size, - size_type preferred_size, - size_type &received_size, pointer reuse = pointer()) + size_type &prefer_in_recvd_out_size, + pointer &reuse) { BOOST_STATIC_ASSERT(( Version > 1 )); const allocation_type mask(AllocationDisableMask); command &= ~mask; - std::pair ret = - priv_allocation_command(command, limit_size, preferred_size, received_size, reuse); - if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)) + pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); + if(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)) boost::container::throw_bad_alloc(); return ret; } @@ -339,22 +336,26 @@ class allocator private: - std::pair priv_allocation_command - (allocation_type command, std::size_t limit_size - ,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr) + pointer priv_allocation_command + (allocation_type command, std::size_t limit_size + ,size_type &prefer_in_recvd_out_size + ,pointer &reuse_ptr) { + std::size_t const preferred_size = prefer_in_recvd_out_size; boost_cont_command_ret_t ret = {0 , 0}; if((limit_size > this->max_size()) | (preferred_size > this->max_size())){ - return std::pair(pointer(), false); + return pointer(); } std::size_t l_size = limit_size*sizeof(T); std::size_t p_size = preferred_size*sizeof(T); std::size_t r_size; { - ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr); + void* reuse_ptr_void = reuse_ptr; + ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void); + reuse_ptr = ret.second ? static_cast(reuse_ptr_void) : 0; } - received_size = r_size/sizeof(T); - return std::pair(static_cast(ret.first), !!ret.second); + prefer_in_recvd_out_size = r_size/sizeof(T); + return (pointer)ret.first; } }; diff --git a/include/boost/container/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp index 728a7ce..2e2a869 100644 --- a/include/boost/container/allocator_traits.hpp +++ b/include/boost/container/allocator_traits.hpp @@ -13,7 +13,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP #define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP @@ -23,25 +22,52 @@ #include #include + +// container #include -#include #include #include - +#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP +#include +#endif +// intrusive #include #include +// move #include - +// move/detail #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include +#include #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 +#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 + +#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 namespace boost { namespace container { namespace allocator_traits_detail { +BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size) +BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction) + } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -50,7 +76,7 @@ namespace container_detail { //workaround needed for C++03 compilers with no construct() //supporting rvalue references -template +template struct is_std_allocator { static const bool value = false; }; @@ -59,11 +85,11 @@ struct is_std_allocator< std::allocator > { static const bool value = true; }; BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer) -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference) -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(void_pointer) -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_void_pointer) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment) @@ -76,50 +102,50 @@ BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) //! The class template allocator_traits supplies a uniform interface to all allocator types. //! This class is a C++03-compatible implementation of std::allocator_traits -template +template struct allocator_traits { //allocator_type - typedef Alloc allocator_type; + typedef Allocator allocator_type; //value_type - typedef typename Alloc::value_type value_type; + typedef typename allocator_type::value_type value_type; #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Alloc::pointer if such a type exists; otherwise, value_type* + //! Allocator::pointer if such a type exists; otherwise, value_type* //! typedef unspecified pointer; - //! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits::rebind::rebind::rebind. + //! Allocator::void_pointer if such a type exists ; otherwise, pointer_traits::rebind. //! typedef see_documentation void_pointer; - //! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits::rebind::rebind::difference_type. + //! Allocator::difference_type if such a type exists ; otherwise, pointer_traits::difference_type. //! typedef see_documentation difference_type; - //! Alloc::size_type if such a type exists ; otherwise, make_unsigned::type + //! Allocator::size_type if such a type exists ; otherwise, make_unsigned::type //! typedef see_documentation size_type; - //! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant - //! type with internal constant static member value == false. + //! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false. typedef see_documentation propagate_on_container_copy_assignment; - //! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant - //! type with internal constant static member value == false. + //! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise otherwise a type + //! with an internal constant static boolean member value == false. typedef see_documentation propagate_on_container_move_assignment; - //! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant - //! type with internal constant static member value == false. + //! Allocator::propagate_on_container_swap if such a type exists, otherwise an otherwise a type + //! with an internal constant static boolean member value == false. typedef see_documentation propagate_on_container_swap; - //! Defines an allocator: Alloc::rebind::other if such a type exists; otherwise, Alloc - //! if Alloc is a class template instantiation of the form Alloc, where Args is zero or + //! Defines an allocator: Allocator::rebind::other if such a type exists; otherwise, Allocator + //! if Allocator is a class template instantiation of the form Allocator, where Args is zero or //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed. //! //! In C++03 compilers rebind_alloc is a struct derived from an allocator @@ -132,114 +158,110 @@ struct allocator_traits template using rebind_traits = allocator_traits >; //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. - //! type is an allocator related to Alloc deduced deduced by rules explained in rebind_alloc. + //! type is an allocator related to Allocator deduced deduced by rules explained in rebind_alloc. template struct portable_rebind_alloc { typedef see_documentation type; }; #else //pointer - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, pointer, value_type*) pointer; //const_pointer - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator, const_pointer, typename boost::intrusive::pointer_traits::template rebind_pointer) const_pointer; //reference - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, reference, typename container_detail::unvoid::type&) reference; //const_reference - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, const_reference, const typename container_detail::unvoid::type&) const_reference; //void_pointer - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator, void_pointer, typename boost::intrusive::pointer_traits::template rebind_pointer) 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::template rebind_pointer) const_void_pointer; //difference_type - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, difference_type, std::ptrdiff_t) difference_type; //size_type - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, size_type, std::size_t) size_type; //propagate_on_container_copy_assignment - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, propagate_on_container_copy_assignment, container_detail::false_type) propagate_on_container_copy_assignment; //propagate_on_container_move_assignment - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, propagate_on_container_move_assignment, container_detail::false_type) propagate_on_container_move_assignment; //propagate_on_container_swap - typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, propagate_on_container_swap, container_detail::false_type) propagate_on_container_swap; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) //C++11 - template using rebind_alloc = typename boost::intrusive::pointer_rebind::type; + template using rebind_alloc = typename boost::intrusive::pointer_rebind::type; template using rebind_traits = allocator_traits< rebind_alloc >; #else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) //Some workaround for C++03 or C++11 compilers with no template aliases template - struct rebind_alloc : boost::intrusive::pointer_rebind::type + struct rebind_alloc : boost::intrusive::pointer_rebind::type { - typedef typename boost::intrusive::pointer_rebind::type Base; + typedef typename boost::intrusive::pointer_rebind::type Base; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - rebind_alloc(BOOST_FWD_REF(Args)... args) - : Base(boost::forward(args)...) - {} + template + rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward(args)...) {} #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - : Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \ - {} \ - // - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ + explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) }; template struct rebind_traits - : allocator_traits::type> + : allocator_traits::type> {}; #endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template struct portable_rebind_alloc - { typedef typename boost::intrusive::pointer_rebind::type type; }; + { typedef typename boost::intrusive::pointer_rebind::type type; }; #endif //BOOST_CONTAINER_DOXYGEN_INVOKED //! Returns: a.allocate(n) //! - static pointer allocate(Alloc &a, size_type n) + static pointer allocate(Allocator &a, size_type n) { return a.allocate(n); } //! Returns: a.deallocate(p, n) //! //! Throws: 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); } //! Effects: calls a.allocate(n, p) if that call is well-formed; //! otherwise, invokes a.allocate(n) - static pointer allocate(Alloc &a, size_type n, const_void_pointer p) + static pointer allocate(Allocator &a, size_type n, const_void_pointer p) { const bool value = boost::container::container_detail:: has_member_function_callable_with_allocate - ::value; + ::value; container_detail::bool_ flag; return allocator_traits::priv_allocate(flag, a, n, p); } @@ -247,23 +269,21 @@ struct allocator_traits //! Effects: calls a.destroy(p) if that call is well-formed; //! otherwise, invokes p->~T(). template - static void destroy(Alloc &a, T*p) BOOST_CONTAINER_NOEXCEPT + static void destroy(Allocator &a, T*p) BOOST_CONTAINER_NOEXCEPT { typedef T* destroy_pointer; const bool value = boost::container::container_detail:: has_member_function_callable_with_destroy - ::value; + ::value; container_detail::bool_ flag; allocator_traits::priv_destroy(flag, a, p); } //! Returns: a.max_size() if that expression is well-formed; otherwise, //! numeric_limits::max(). - static size_type max_size(const Alloc &a) BOOST_CONTAINER_NOEXCEPT + static size_type max_size(const Allocator &a) BOOST_CONTAINER_NOEXCEPT { - const bool value = boost::container::container_detail:: - has_member_function_callable_with_max_size - ::value; + const bool value = allocator_traits_detail::has_max_size::value; container_detail::bool_ flag; return allocator_traits::priv_max_size(flag, a); } @@ -273,20 +293,17 @@ struct allocator_traits static #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) typename container_detail::if_c - < boost::container::container_detail:: - has_member_function_callable_with_select_on_container_copy_construction - ::value - , Alloc - , const Alloc & + < allocator_traits_detail::has_select_on_container_copy_construction::value + , Allocator + , const Allocator & >::type #else - Alloc + Allocator #endif - select_on_container_copy_construction(const Alloc &a) + select_on_container_copy_construction(const Allocator &a) { - const bool value = boost::container::container_detail:: - has_member_function_callable_with_select_on_container_copy_construction - ::value; + const bool value = allocator_traits_detail::has_select_on_container_copy_construction + ::value; container_detail::bool_ flag; return allocator_traits::priv_select_on_container_copy_construction(flag, a); } @@ -295,119 +312,107 @@ struct allocator_traits //! Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; //! otherwise, invokes ::new (static_cast(p)) T(std::forward(args)...) template - 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_::value> flag; + container_detail::bool_::value> flag; allocator_traits::priv_construct(flag, a, p, ::boost::forward(args)...); } #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) private: - static pointer priv_allocate(container_detail::true_type, Alloc &a, size_type n, const_void_pointer p) + static pointer priv_allocate(container_detail::true_type, Allocator &a, size_type n, const_void_pointer p) { return a.allocate(n, p); } - static pointer priv_allocate(container_detail::false_type, Alloc &a, size_type n, const_void_pointer) + static pointer priv_allocate(container_detail::false_type, Allocator &a, size_type n, const_void_pointer) { return a.allocate(n); } template - static void priv_destroy(container_detail::true_type, Alloc &a, T* p) BOOST_CONTAINER_NOEXCEPT + static void priv_destroy(container_detail::true_type, Allocator &a, T* p) BOOST_CONTAINER_NOEXCEPT { a.destroy(p); } template - static void priv_destroy(container_detail::false_type, Alloc &, T* p) BOOST_CONTAINER_NOEXCEPT + static void priv_destroy(container_detail::false_type, Allocator &, T* p) BOOST_CONTAINER_NOEXCEPT { p->~T(); (void)p; } - static size_type priv_max_size(container_detail::true_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT + static size_type priv_max_size(container_detail::true_type, const Allocator &a) BOOST_CONTAINER_NOEXCEPT { return a.max_size(); } - static size_type priv_max_size(container_detail::false_type, const Alloc &) BOOST_CONTAINER_NOEXCEPT + static size_type priv_max_size(container_detail::false_type, const Allocator &) BOOST_CONTAINER_NOEXCEPT { return size_type(-1); } - static Alloc priv_select_on_container_copy_construction(container_detail::true_type, const Alloc &a) + static Allocator priv_select_on_container_copy_construction(container_detail::true_type, const Allocator &a) { return a.select_on_container_copy_construction(); } - static const Alloc &priv_select_on_container_copy_construction(container_detail::false_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT + static const Allocator &priv_select_on_container_copy_construction(container_detail::false_type, const Allocator &a) BOOST_CONTAINER_NOEXCEPT { return a; } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - static void priv_construct(container_detail::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args) + static void priv_construct(container_detail::false_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) { const bool value = boost::container::container_detail:: has_member_function_callable_with_construct - < Alloc, T*, Args... >::value; + < Allocator, T*, Args... >::value; container_detail::bool_ flag; - priv_construct_dispatch2(flag, a, p, ::boost::forward(args)...); + (priv_construct_dispatch_next)(flag, a, p, ::boost::forward(args)...); } template - static void priv_construct(container_detail::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args) - { - priv_construct_dispatch2(container_detail::false_type(), a, p, ::boost::forward(args)...); - } + 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)...); } template - 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)...); } template - 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)...); } #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) public: - #define BOOST_PP_LOCAL_MACRO(n) \ - template \ - static void construct(Alloc &a, T *p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - container_detail::bool_ \ - ::value> flag; \ - allocator_traits::priv_construct(flag, a, p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ + + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \ + template\ + static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + container_detail::bool_::value> flag;\ + (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ // - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL private: - #define BOOST_PP_LOCAL_MACRO(n) \ - template \ - static void priv_construct(container_detail::false_type, Alloc &a, T *p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \ - { \ - const bool value = \ - boost::container::container_detail::has_member_function_callable_with_construct \ - < Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value; \ - container_detail::bool_ flag; \ - priv_construct_dispatch2(flag, a, p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ - } \ - \ - template \ - static void priv_construct(container_detail::true_type, Alloc &a, T *p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \ - { \ - priv_construct_dispatch2(container_detail::false_type(), a, p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ - } \ - \ - template \ - 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 \ - static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ - { ::new((void*)p, boost_container_new_t()) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\ + + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \ + template\ + static void priv_construct(container_detail::false_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + const bool value = boost::container::container_detail::has_member_function_callable_with_construct\ + < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N>::value;\ + container_detail::bool_ flag;\ + (priv_construct_dispatch_next)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ + \ + template\ + static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { (priv_construct_dispatch_next)(container_detail::false_type(), a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + \ + template\ + static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\ + \ + template\ + static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\ // - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p, ::boost::container::default_init_t) + static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&) { ::new((void*)p) T; } #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) diff --git a/include/boost/container/container_fwd.hpp b/include/boost/container/container_fwd.hpp index ee3ba1b..97dad13 100644 --- a/include/boost/container/container_fwd.hpp +++ b/include/boost/container/container_fwd.hpp @@ -80,27 +80,30 @@ enum tree_type_enum #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +template +class new_allocator; + template > + ,class Allocator = new_allocator > class vector; template > + ,class Allocator = new_allocator > class stable_vector; template class static_vector; template > + ,class Allocator = new_allocator > class deque; template > + ,class Allocator = new_allocator > class list; template > + ,class Allocator = new_allocator > class slist; template @@ -110,67 +113,67 @@ typedef tree_opt tree_assoc_defaults; template - ,class A = std::allocator + ,class Allocator = new_allocator ,class Options = tree_assoc_defaults > class set; template - ,class A = std::allocator + ,class Allocator = new_allocator ,class Options = tree_assoc_defaults > class multiset; template - ,class A = std::allocator > + ,class Allocator = new_allocator > ,class Options = tree_assoc_defaults > class map; template - ,class A = std::allocator > + ,class Allocator = new_allocator > ,class Options = tree_assoc_defaults > class multimap; template - ,class A = std::allocator > + ,class Allocator = new_allocator > class flat_set; template - ,class A = std::allocator > + ,class Allocator = new_allocator > class flat_multiset; template - ,class A = std::allocator > > + ,class Allocator = new_allocator > > class flat_map; template - ,class A = std::allocator > > + ,class Allocator = new_allocator > > class flat_multimap; template - ,class A = std::allocator > + ,class Allocator = new_allocator > class basic_string; typedef basic_string - ,std::allocator > + ,new_allocator > string; typedef basic_string - ,std::allocator > + ,new_allocator > wstring; static const std::size_t ADP_nodes_per_block = 256u; diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index 69c4830..3383a21 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -7,7 +7,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_DEQUE_HPP #define BOOST_CONTAINER_DEQUE_HPP @@ -17,35 +16,39 @@ #include #include - -#include -#include -#include +// container #include #include +#include //new_allocator #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +// container/detail #include #include //algo_equal(), algo_lexicographical_compare +#include +#include +#include +#include +#include +#include +#include +#include +#include +// move +#include +#include +#include +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +// other +#include #include - +// std #include -#include //std::allocator #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -54,20 +57,15 @@ namespace boost { namespace container { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -template +template class deque; template struct deque_value_traits { typedef T value_type; - static const bool trivial_dctr = boost::has_trivial_destructor::value; + static const bool trivial_dctr = container_detail::is_trivially_destructible::value; static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move::value; - static const bool trivial_copy = has_trivial_copy::value; - static const bool nothrow_copy = has_nothrow_copy::value; - static const bool trivial_assign = has_trivial_assign::value; - //static const bool nothrow_assign = has_nothrow_assign::value; - static const bool nothrow_assign = false; }; // Note: this function is simply a kludge to work around several compilers' @@ -276,12 +274,12 @@ class deque_iterator // Deque base class. It has two purposes. First, its constructor // and destructor allocate (but don't initialize) storage. This makes // exception safety easier. -template +template class deque_base { BOOST_COPYABLE_AND_MOVABLE(deque_base) public: - typedef allocator_traits val_alloc_traits_type; + typedef allocator_traits val_alloc_traits_type; typedef typename val_alloc_traits_type::value_type val_alloc_val; typedef typename val_alloc_traits_type::pointer val_alloc_ptr; typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr; @@ -297,7 +295,7 @@ class deque_base typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr; typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref; typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref; - typedef A allocator_type; + typedef Allocator allocator_type; typedef allocator_type stored_allocator_type; typedef val_alloc_size size_type; @@ -476,16 +474,16 @@ class deque_base //! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle. //! //! \tparam T The type of object that is stored in the deque -//! \tparam A The allocator used for all internal memory management -template > +//! \tparam Allocator The allocator used for all internal memory management +template > #else -template +template #endif -class deque : protected deque_base +class deque : protected deque_base { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: - typedef deque_base Base; + typedef deque_base Base; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -497,18 +495,18 @@ class deque : protected deque_base ////////////////////////////////////////////// typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator; - typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_MOVE_IMPDEF(allocator_type) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(typename Base::iterator) iterator; + typedef BOOST_MOVE_IMPDEF(typename Base::const_iterator) const_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -517,7 +515,7 @@ class deque : protected deque_base typedef typename Base::ptr_alloc_ptr index_pointer; static size_type s_buffer_size() { return Base::s_buffer_size(); } - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -556,7 +554,7 @@ class deque : protected deque_base explicit deque(size_type n) : Base(n, allocator_type()) { - container_detail::insert_value_initialized_n_proxy proxy; + container_detail::insert_value_initialized_n_proxy proxy; proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); //deque_base will deallocate in case of exception... } @@ -573,7 +571,7 @@ class deque : protected deque_base deque(size_type n, default_init_t) : Base(n, allocator_type()) { - container_detail::insert_default_initialized_n_proxy proxy; + container_detail::insert_default_initialized_n_proxy proxy; proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); //deque_base will deallocate in case of exception... } @@ -1031,7 +1029,7 @@ class deque : protected deque_base this->priv_erase_last_n(len - new_size); else{ const size_type n = new_size - this->size(); - container_detail::insert_value_initialized_n_proxy proxy; + container_detail::insert_value_initialized_n_proxy proxy; priv_insert_back_aux_impl(n, proxy); } } @@ -1051,7 +1049,7 @@ class deque : protected deque_base this->priv_erase_last_n(len - new_size); else{ const size_type n = new_size - this->size(); - container_detail::insert_default_initialized_n_proxy proxy; + container_detail::insert_default_initialized_n_proxy proxy; priv_insert_back_aux_impl(n, proxy); } } @@ -1249,7 +1247,7 @@ class deque : protected deque_base // ////////////////////////////////////////////// - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the beginning of the deque. @@ -1258,7 +1256,7 @@ class deque : protected deque_base //! //! Complexity: Amortized constant time template - void emplace_front(Args&&... args) + void emplace_front(BOOST_FWD_REF(Args)... args) { if(this->priv_push_front_simple_available()){ allocator_traits_type::construct @@ -1268,7 +1266,7 @@ class deque : protected deque_base this->priv_push_front_simple_commit(); } else{ - typedef container_detail::insert_non_movable_emplace_proxy type; + typedef container_detail::insert_nonmovable_emplace_proxy type; this->priv_insert_front_aux_impl(1, type(boost::forward(args)...)); } } @@ -1280,7 +1278,7 @@ class deque : protected deque_base //! //! Complexity: Amortized constant time template - void emplace_back(Args&&... args) + void emplace_back(BOOST_FWD_REF(Args)... args) { if(this->priv_push_back_simple_available()){ allocator_traits_type::construct @@ -1290,7 +1288,7 @@ class deque : protected deque_base this->priv_push_back_simple_commit(); } else{ - typedef container_detail::insert_non_movable_emplace_proxy type; + typedef container_detail::insert_nonmovable_emplace_proxy type; this->priv_insert_back_aux_impl(1, type(boost::forward(args)...)); } } @@ -1305,7 +1303,7 @@ class deque : protected deque_base //! Complexity: If p is end(), amortized constant time //! Linear time otherwise. template - iterator emplace(const_iterator p, Args&&... args) + iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args) { if(p == this->cbegin()){ this->emplace_front(boost::forward(args)...); @@ -1316,75 +1314,66 @@ class deque : protected deque_base return (this->end()-1); } else{ - typedef container_detail::insert_emplace_proxy type; + typedef container_detail::insert_emplace_proxy type; return this->priv_insert_aux_impl(p, 1, type(boost::forward(args)...)); } } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - //advanced_insert_int.hpp includes all necessary preprocessor machinery... - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, > ) \ - void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - if(priv_push_front_simple_available()){ \ - allocator_traits_type::construct \ - ( this->alloc() \ - , this->priv_push_front_simple_pos() \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - priv_push_front_simple_commit(); \ - } \ - else{ \ - typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \ - type; \ - priv_insert_front_aux_impl \ - (1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - } \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - if(priv_push_back_simple_available()){ \ - allocator_traits_type::construct \ - ( this->alloc() \ - , this->priv_push_back_simple_pos() \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - priv_push_back_simple_commit(); \ - } \ - else{ \ - typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \ - type; \ - priv_insert_back_aux_impl \ - (1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - } \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - if(p == this->cbegin()){ \ - this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - return this->begin(); \ - } \ - else if(p == cend()){ \ - this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - return (this->end()-1); \ - } \ - else{ \ - typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \ - type; \ - return this->priv_insert_aux_impl \ - (p, 1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - } \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ + void emplace_front(BOOST_MOVE_UREF##N)\ + {\ + if(priv_push_front_simple_available()){\ + allocator_traits_type::construct\ + ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + priv_push_front_simple_commit();\ + }\ + else{\ + typedef container_detail::insert_nonmovable_emplace_proxy##N\ + type;\ + priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\ + }\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ + void emplace_back(BOOST_MOVE_UREF##N)\ + {\ + if(priv_push_back_simple_available()){\ + allocator_traits_type::construct\ + ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + priv_push_back_simple_commit();\ + }\ + else{\ + typedef container_detail::insert_nonmovable_emplace_proxy##N\ + type;\ + priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\ + }\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ + iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + if(p == this->cbegin()){\ + this->emplace_front(BOOST_MOVE_FWD##N);\ + return this->begin();\ + }\ + else if(p == cend()){\ + this->emplace_back(BOOST_MOVE_FWD##N);\ + return (--this->end());\ + }\ + else{\ + typedef container_detail::insert_emplace_proxy_arg##N\ + type;\ + return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\ + }\ + } + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE) + #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts a copy of x at the front of the deque. @@ -1526,7 +1515,7 @@ class deque : protected deque_base #endif ) { - container_detail::insert_range_proxy proxy(first); + container_detail::insert_range_proxy proxy(first); return priv_insert_aux_impl(p, boost::container::iterator_distance(first, last), proxy); } #endif @@ -1581,11 +1570,11 @@ class deque : protected deque_base ++next; size_type index = pos - this->members_.m_start; if (index < (this->size()/2)) { - boost::move_backward(this->begin(), pos.unconst(), next); + boost::container::move_backward(this->begin(), pos.unconst(), next); pop_front(); } else { - boost::move(next, this->end(), pos.unconst()); + boost::container::move(next, this->end(), pos.unconst()); pop_back(); } return this->members_.m_start + index; @@ -1609,7 +1598,7 @@ class deque : protected deque_base const size_type n = static_cast(last - first); const size_type elems_before = static_cast(first - this->members_.m_start); if (elems_before < (this->size() - n) - elems_before) { - boost::move_backward(begin(), first.unconst(), last.unconst()); + boost::container::move_backward(begin(), first.unconst(), last.unconst()); iterator new_start = this->members_.m_start + n; if(!Base::traits_t::trivial_dctr_after_move) this->priv_destroy_range(this->members_.m_start, new_start); @@ -1617,7 +1606,7 @@ class deque : protected deque_base this->members_.m_start = new_start; } else { - boost::move(last.unconst(), end(), first.unconst()); + boost::container::move(last.unconst(), end(), first.unconst()); iterator new_finish = this->members_.m_finish - n; if(!Base::traits_t::trivial_dctr_after_move) this->priv_destroy_range(new_finish, this->members_.m_finish); @@ -1749,7 +1738,7 @@ class deque : protected deque_base else { return priv_insert_aux_impl ( p, (size_type)1 - , container_detail::get_insert_value_proxy(::boost::forward(x))); + , container_detail::get_insert_value_proxy(::boost::forward(x))); } } @@ -1764,7 +1753,7 @@ class deque : protected deque_base else{ priv_insert_aux_impl ( this->cbegin(), (size_type)1 - , container_detail::get_insert_value_proxy(::boost::forward(x))); + , container_detail::get_insert_value_proxy(::boost::forward(x))); } } @@ -1779,7 +1768,7 @@ class deque : protected deque_base else{ priv_insert_aux_impl ( this->cend(), (size_type)1 - , container_detail::get_insert_value_proxy(::boost::forward(x))); + , container_detail::get_insert_value_proxy(::boost::forward(x))); } } @@ -1813,21 +1802,19 @@ class deque : protected deque_base void priv_destroy_range(iterator p, iterator p2) { - for(;p != p2; ++p){ - allocator_traits_type::destroy - ( this->alloc() - , container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p)) - ); + if(!Base::traits_t::trivial_dctr){ + for(;p != p2; ++p){ + allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p)); + } } } void priv_destroy_range(pointer p, pointer p2) { - for(;p != p2; ++p){ - allocator_traits_type::destroy - ( this->alloc() - , container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p)) - ); + if(!Base::traits_t::trivial_dctr){ + for(;p != p2; ++p){ + allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p)); + } } } @@ -1857,7 +1844,7 @@ class deque : protected deque_base ::boost::container::uninitialized_move_alloc (this->alloc(), this->members_.m_start, start_n, new_start); this->members_.m_start = new_start; - boost::move(start_n, pos, old_start); + boost::container::move(start_n, pos, old_start); proxy.copy_n_and_update(this->alloc(), pos - n, n); } else { @@ -1887,7 +1874,7 @@ class deque : protected deque_base ::boost::container::uninitialized_move_alloc (this->alloc(), finish_n, old_finish, old_finish); this->members_.m_finish = new_finish; - boost::move_backward(pos, finish_n, old_finish); + boost::container::move_backward(pos, finish_n, old_finish); proxy.copy_n_and_update(this->alloc(), pos, n); } else { @@ -2092,9 +2079,9 @@ class deque : protected deque_base new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2 + (add_at_front ? nodes_to_add : 0); if (new_nstart < this->members_.m_start.m_node) - boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); + boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); else - boost::move_backward + boost::container::move_backward (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes); } else { @@ -2104,7 +2091,7 @@ class deque : protected deque_base index_pointer new_map = this->priv_allocate_map(new_map_size); new_nstart = new_map + (new_map_size - new_num_nodes) / 2 + (add_at_front ? nodes_to_add : 0); - boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); + boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart); this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size); this->members_.m_map = new_map; @@ -2125,10 +2112,13 @@ namespace boost { //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > - : public ::boost::has_trivial_destructor_after_move -{}; +template +struct has_trivial_destructor_after_move > +{ + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; } diff --git a/include/boost/container/detail/adaptive_node_pool.hpp b/include/boost/container/detail/adaptive_node_pool.hpp index 4e73754..533a2bc 100644 --- a/include/boost/container/detail/adaptive_node_pool.hpp +++ b/include/boost/container/detail/adaptive_node_pool.hpp @@ -19,13 +19,14 @@ #include #include -#include #include #include #include #include #include #include +#include + #include #include #include diff --git a/include/boost/container/detail/adaptive_node_pool_impl.hpp b/include/boost/container/detail/adaptive_node_pool_impl.hpp index dc1a7f1..19e28e5 100644 --- a/include/boost/container/detail/adaptive_node_pool_impl.hpp +++ b/include/boost/container/detail/adaptive_node_pool_impl.hpp @@ -18,17 +18,23 @@ #include #include +// container #include -#include +#include +// container/detail +#include +#include +#include +#include +#include +#include +#include +// intrusive #include #include #include #include -#include -#include -#include -#include -#include +// other #include #include #include @@ -482,7 +488,7 @@ class private_adaptive_node_pool_impl free_nodes_iterator itf(nodes.begin()), itbf(itbb); size_type splice_node_count = size_type(-1); while(itf != ite){ - void *pElem = container_detail::to_raw_pointer(container_detail::iterator_to_pointer(itf)); + void *pElem = container_detail::to_raw_pointer(container_detail::iterator_to_raw_pointer(itf)); block_info_t &block_info = *this->priv_block_from_node(pElem); BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node); ++splice_node_count; diff --git a/include/boost/container/detail/addressof.hpp b/include/boost/container/detail/addressof.hpp new file mode 100644 index 0000000..d9fbf0d --- /dev/null +++ b/include/boost/container/detail/addressof.hpp @@ -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 + +namespace boost { +namespace container { +namespace container_detail { + +template +inline T* addressof(T& obj) +{ + return static_cast( + static_cast( + const_cast( + &reinterpret_cast(obj) + ))); +} + +} //namespace container_detail { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP diff --git a/include/boost/container/detail/advanced_insert_int.hpp b/include/boost/container/detail/advanced_insert_int.hpp index 528ec4d..99efc4a 100644 --- a/include/boost/container/detail/advanced_insert_int.hpp +++ b/include/boost/container/detail/advanced_insert_int.hpp @@ -18,38 +18,44 @@ #include #include +// container #include +// container/detail +#include #include -#include -#include #include -#include #include #include #include - +#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +// move +#include +// other #include #include namespace boost { namespace container { namespace container_detail { -template +template struct move_insert_range_proxy { - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::value_type value_type; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; explicit move_insert_range_proxy(FwdIt first) : first_(first) {} - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) { this->first_ = ::boost::container::uninitialized_move_alloc_n_source (a, this->first_, n, p); } - void copy_n_and_update(A &, Iterator p, size_type n) + void copy_n_and_update(Allocator &, Iterator p, size_type n) { this->first_ = ::boost::container::move_n_source(this->first_, n, p); } @@ -58,22 +64,22 @@ struct move_insert_range_proxy }; -template +template struct insert_range_proxy { - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::value_type value_type; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; explicit insert_range_proxy(FwdIt first) : first_(first) {} - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) { this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); } - void copy_n_and_update(A &, Iterator p, size_type n) + void copy_n_and_update(Allocator &, Iterator p, size_type n) { this->first_ = ::boost::container::copy_n_source(this->first_, n, p); } @@ -82,20 +88,20 @@ struct insert_range_proxy }; -template +template struct insert_n_copies_proxy { - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::value_type value_type; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; explicit insert_n_copies_proxy(const value_type &v) : v_(v) {} - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } - void copy_n_and_update(A &, Iterator p, size_type n) const + void copy_n_and_update(Allocator &, Iterator p, size_type n) const { for (; 0 < n; --n, ++p){ *p = v_; @@ -105,38 +111,38 @@ struct insert_n_copies_proxy const value_type &v_; }; -template +template struct insert_value_initialized_n_proxy { - typedef ::boost::container::allocator_traits alloc_traits; - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::value_type value_type; + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { boost::container::uninitialized_value_init_alloc_n(a, n, p); } - void copy_n_and_update(A &, Iterator, size_type) const + void copy_n_and_update(Allocator &, Iterator, size_type) const { BOOST_ASSERT(false); } }; -template +template struct insert_default_initialized_n_proxy { - typedef ::boost::container::allocator_traits alloc_traits; - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::value_type value_type; + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { boost::container::uninitialized_default_init_alloc_n(a, n, p); } - void copy_n_and_update(A &, Iterator, size_type) const + void copy_n_and_update(Allocator &, Iterator, size_type) const { BOOST_ASSERT(false); } }; -template +template struct insert_copy_proxy { - typedef boost::container::allocator_traits alloc_traits; + typedef boost::container::allocator_traits alloc_traits; typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::value_type value_type; @@ -144,13 +150,13 @@ struct insert_copy_proxy : v_(v) {} - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; alloc_traits::construct( a, iterator_to_raw_pointer(p), v_); } - void copy_n_and_update(A &, Iterator p, size_type n) const + void copy_n_and_update(Allocator &, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; *p =v_; @@ -160,10 +166,10 @@ struct insert_copy_proxy }; -template +template struct insert_move_proxy { - typedef boost::container::allocator_traits alloc_traits; + typedef boost::container::allocator_traits alloc_traits; typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::value_type value_type; @@ -171,13 +177,13 @@ struct insert_move_proxy : v_(v) {} - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) ); } - void copy_n_and_update(A &, Iterator p, size_type n) const + void copy_n_and_update(Allocator &, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; *p = ::boost::move(v_); @@ -186,50 +192,48 @@ struct insert_move_proxy value_type &v_; }; -template -insert_move_proxy get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits::value_type) v) +template +insert_move_proxy get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits::value_type) v) { - return insert_move_proxy(v); + return insert_move_proxy(v); } -template -insert_copy_proxy get_insert_value_proxy(const typename boost::container::iterator_traits::value_type &v) +template +insert_copy_proxy get_insert_value_proxy(const typename boost::container::iterator_traits::value_type &v) { - return insert_copy_proxy(v); + return insert_copy_proxy(v); } }}} //namespace boost { namespace container { namespace container_detail { -#ifdef BOOST_CONTAINER_PERFECT_FORWARDING +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include #include -#include -//#include //For debugging purposes namespace boost { namespace container { namespace container_detail { -template -struct insert_non_movable_emplace_proxy +template +struct insert_nonmovable_emplace_proxy { - typedef boost::container::allocator_traits alloc_traits; + typedef boost::container::allocator_traits alloc_traits; typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::value_type value_type; typedef typename build_number_seq::type index_tuple_t; - explicit insert_non_movable_emplace_proxy(Args&&... args) + explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args) : args_(args...) {} - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); } private: template - void priv_uninitialized_copy_some_and_update(A &a, const index_tuple&, Iterator p, size_type n) + void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple&, Iterator p, size_type n) { BOOST_ASSERT(n == 1); (void)n; alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward(get(this->args_))... ); @@ -239,30 +243,30 @@ struct insert_non_movable_emplace_proxy tuple args_; }; -template +template struct insert_emplace_proxy - : public insert_non_movable_emplace_proxy + : public insert_nonmovable_emplace_proxy { - typedef insert_non_movable_emplace_proxy base_t; - typedef boost::container::allocator_traits alloc_traits; + typedef insert_nonmovable_emplace_proxy base_t; + typedef boost::container::allocator_traits alloc_traits; typedef typename base_t::value_type value_type; typedef typename base_t::size_type size_type; typedef typename base_t::index_tuple_t index_tuple_t; - explicit insert_emplace_proxy(Args&&... args) + explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args) : base_t(::boost::forward(args)...) {} - void copy_n_and_update(A &a, Iterator p, size_type n) + void copy_n_and_update(Allocator &a, Iterator p, size_type n) { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } private: template - void priv_copy_some_and_update(A &a, const index_tuple&, Iterator p, size_type n) + void priv_copy_some_and_update(Allocator &a, const index_tuple&, Iterator p, size_type n) { BOOST_ASSERT(n ==1); (void)n; - aligned_storage::value> v; + typename aligned_storage::value>::type v; value_type *vp = static_cast(static_cast(&v)); alloc_traits::construct(a, vp, ::boost::forward(get(this->args_))...); @@ -279,191 +283,182 @@ struct insert_emplace_proxy }; //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type -template -struct insert_emplace_proxy::value_type> - : public insert_move_proxy +template +struct insert_emplace_proxy::value_type> + : public insert_move_proxy { - explicit insert_emplace_proxy(typename boost::container::allocator_traits::value_type &&v) - : insert_move_proxy(v) + explicit insert_emplace_proxy(typename boost::container::allocator_traits::value_type &&v) + : insert_move_proxy(v) {} }; //We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking //compiler error C2752 (“more than one partial specialization matches”). //Any problem is solvable with an extra layer of indirection? ;-) -template -struct insert_emplace_proxy::value_type>::type +template +struct insert_emplace_proxy::value_type>::type > - : public insert_copy_proxy + : public insert_copy_proxy { - explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) - : insert_copy_proxy(v) + explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) {} }; -template -struct insert_emplace_proxy::value_type &> - : public insert_copy_proxy +template +struct insert_emplace_proxy::value_type &> + : public insert_copy_proxy { - explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) - : insert_copy_proxy(v) + explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) {} }; -template -struct insert_emplace_proxy::value_type>::type & +template +struct insert_emplace_proxy::value_type>::type & > - : public insert_copy_proxy + : public insert_copy_proxy { - explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) - : insert_copy_proxy(v) + explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) {} }; }}} //namespace boost { namespace container { namespace container_detail { -#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include #include namespace boost { namespace container { namespace container_detail { -#define BOOST_PP_LOCAL_MACRO(N) \ -template \ -struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ -{ \ - typedef boost::container::allocator_traits alloc_traits; \ - typedef typename alloc_traits::size_type size_type; \ - typedef typename alloc_traits::value_type value_type; \ - \ - explicit BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ - ( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ - BOOST_PP_EXPR_IF(N, :) BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \ - {} \ - \ - void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) \ - { \ - BOOST_ASSERT(n == 1); (void)n; \ - alloc_traits::construct \ - ( a, iterator_to_raw_pointer(p) \ - BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ - ); \ - } \ - \ - void copy_n_and_update(A &, Iterator, size_type) \ - { BOOST_ASSERT(false); } \ - \ - protected: \ - BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \ -}; \ - \ -template \ -struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \ - : BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ - < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \ -{ \ - typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ - base_t; \ - typedef typename base_t::value_type value_type; \ - typedef typename base_t::size_type size_type; \ - typedef boost::container::allocator_traits alloc_traits; \ - \ - explicit BOOST_PP_CAT(insert_emplace_proxy_arg, N) \ - ( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ - : base_t(BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \ - {} \ - \ - void copy_n_and_update(A &a, Iterator p, size_type n) \ - { \ - BOOST_ASSERT(n == 1); (void)n; \ - aligned_storage::value> v; \ - value_type *vp = static_cast(static_cast(&v)); \ - alloc_traits::construct(a, vp \ - BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \ - BOOST_TRY{ \ - *p = ::boost::move(*vp); \ - } \ - BOOST_CATCH(...){ \ - alloc_traits::destroy(a, vp); \ - BOOST_RETHROW \ - } \ - BOOST_CATCH_END \ - alloc_traits::destroy(a, vp); \ - } \ -}; \ -//! -#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) -#include BOOST_PP_LOCAL_ITERATE() +#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \ +template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +struct insert_nonmovable_emplace_proxy##N\ +{\ + typedef boost::container::allocator_traits alloc_traits;\ + typedef typename alloc_traits::size_type size_type;\ + typedef typename alloc_traits::value_type value_type;\ + \ + explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\ + BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\ + \ + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + {\ + BOOST_ASSERT(n == 1); (void)n;\ + alloc_traits::construct(a, iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + }\ + \ + void copy_n_and_update(Allocator &, Iterator, size_type)\ + { BOOST_ASSERT(false); }\ + \ + protected:\ + BOOST_MOVE_MREF##N\ +};\ +\ +template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +struct insert_emplace_proxy_arg##N\ + : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\ +{\ + typedef insert_nonmovable_emplace_proxy##N\ + < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\ + typedef typename base_t::value_type value_type;\ + typedef typename base_t::size_type size_type;\ + typedef boost::container::allocator_traits alloc_traits;\ + \ + explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\ + : base_t(BOOST_MOVE_FWD##N){}\ + \ + void copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + {\ + BOOST_ASSERT(n == 1); (void)n;\ + typename aligned_storage::value>::type v;\ + BOOST_ASSERT((((size_type)(&v)) % alignment_of::value) == 0);\ + value_type *vp = static_cast(static_cast(&v));\ + alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + BOOST_TRY{\ + *p = ::boost::move(*vp);\ + }\ + BOOST_CATCH(...){\ + alloc_traits::destroy(a, vp);\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ + alloc_traits::destroy(a, vp);\ + }\ +};\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE) +#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type -template -struct insert_emplace_proxy_arg1::value_type> > - : public insert_move_proxy +template +struct insert_emplace_proxy_arg1::value_type> > + : public insert_move_proxy { - explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &v) - : insert_move_proxy(v) + explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &v) + : insert_move_proxy(v) {} }; -template -struct insert_emplace_proxy_arg1::value_type> - : public insert_copy_proxy +template +struct insert_emplace_proxy_arg1::value_type> + : public insert_copy_proxy { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) - : insert_copy_proxy(v) + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) {} }; #else //e.g. MSVC10 & MSVC11 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type -template -struct insert_emplace_proxy_arg1::value_type> - : public insert_move_proxy +template +struct insert_emplace_proxy_arg1::value_type> + : public insert_move_proxy { - explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &&v) - : insert_move_proxy(v) + explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &&v) + : insert_move_proxy(v) {} }; //We use "add_const" here as adding "const" only confuses MSVC10&11 provoking //compiler error C2752 (“more than one partial specialization matches”). //Any problem is solvable with an extra layer of indirection? ;-) -template -struct insert_emplace_proxy_arg1::value_type>::type +template +struct insert_emplace_proxy_arg1::value_type>::type > - : public insert_copy_proxy + : public insert_copy_proxy { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) - : insert_copy_proxy(v) + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) {} }; -template -struct insert_emplace_proxy_arg1::value_type &> - : public insert_copy_proxy +template +struct insert_emplace_proxy_arg1::value_type &> + : public insert_copy_proxy { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) - : insert_copy_proxy(v) + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) {} }; -template -struct insert_emplace_proxy_arg1::value_type>::type & +template +struct insert_emplace_proxy_arg1::value_type>::type & > - : public insert_copy_proxy + : public insert_copy_proxy { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) - : insert_copy_proxy(v) + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) {} }; @@ -471,7 +466,7 @@ struct insert_emplace_proxy_arg1 diff --git a/include/boost/container/detail/alloc_helpers.hpp b/include/boost/container/detail/alloc_helpers.hpp new file mode 100644 index 0000000..c3d4963 --- /dev/null +++ b/include/boost/container/detail/alloc_helpers.hpp @@ -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 +#include + +namespace boost { +namespace container { +namespace container_detail { + +template +inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type) + BOOST_CONTAINER_NOEXCEPT +{} + +template +inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type) +{ boost::adl_move_swap(l, r); } + +template +inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type) + BOOST_CONTAINER_NOEXCEPT +{} + +template +inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type) +{ l = r; } + +template +inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type) + BOOST_CONTAINER_NOEXCEPT +{} + +template +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 diff --git a/include/boost/container/detail/allocation_type.hpp b/include/boost/container/detail/allocation_type.hpp index 65d543a..bd109c0 100644 --- a/include/boost/container/detail/allocation_type.hpp +++ b/include/boost/container/detail/allocation_type.hpp @@ -36,7 +36,7 @@ enum allocation_type_v try_shrink_in_place_v = 0x40 }; -typedef int allocation_type; +typedef unsigned int allocation_type; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED static const allocation_type allocate_new = (allocation_type)allocate_new_v; static const allocation_type expand_fwd = (allocation_type)expand_fwd_v; diff --git a/include/boost/container/detail/allocator_version_traits.hpp b/include/boost/container/detail/allocator_version_traits.hpp index b4733da..309d79a 100644 --- a/include/boost/container/detail/allocator_version_traits.hpp +++ b/include/boost/container/detail/allocator_version_traits.hpp @@ -25,56 +25,50 @@ #include //allocation_type #include //integral_constant #include //pointer_traits -#include //pair #include //BOOST_TRY namespace boost { namespace container { namespace container_detail { -template::value> +template::value> struct allocator_version_traits { typedef ::boost::container::container_detail::integral_constant alloc_version; - typedef typename A::multiallocation_chain multiallocation_chain; + typedef typename Allocator::multiallocation_chain multiallocation_chain; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::size_type size_type; //Node allocation interface - static pointer allocate_one(A &a) + static pointer allocate_one(Allocator &a) { return a.allocate_one(); } - static void deallocate_one(A &a, const pointer &p) + static void deallocate_one(Allocator &a, const pointer &p) { a.deallocate_one(p); } - static void allocate_individual(A &a, size_type n, multiallocation_chain &m) + static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) { return a.allocate_individual(n, m); } - static void deallocate_individual(A &a, multiallocation_chain &holder) + static void deallocate_individual(Allocator &a, multiallocation_chain &holder) { a.deallocate_individual(holder); } - static std::pair - allocation_command(A &a, allocation_type command, - size_type limit_size, size_type preferred_size, - size_type &received_size, const pointer &reuse) - { - return a.allocation_command - (command, limit_size, preferred_size, received_size, reuse); - } + static pointer allocation_command(Allocator &a, allocation_type command, + size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) + { return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); } }; -template -struct allocator_version_traits +template +struct allocator_version_traits { typedef ::boost::container::container_detail::integral_constant alloc_version; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::size_type size_type; - typedef typename boost::container::allocator_traits::value_type value_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::value_type value_type; typedef typename boost::intrusive::pointer_traits:: template rebind_pointer::type void_ptr; @@ -85,13 +79,13 @@ struct allocator_version_traits < multialloc_cached_counted, value_type> multiallocation_chain; //Node allocation interface - static pointer allocate_one(A &a) + static pointer allocate_one(Allocator &a) { return a.allocate(1); } - static void deallocate_one(A &a, const pointer &p) + static void deallocate_one(Allocator &a, const pointer &p) { a.deallocate(p, 1); } - static void deallocate_individual(A &a, multiallocation_chain &holder) + static void deallocate_individual(Allocator &a, multiallocation_chain &holder) { size_type n = holder.size(); typename multiallocation_chain::iterator it = holder.begin(); @@ -104,7 +98,7 @@ struct allocator_version_traits struct allocate_individual_rollback { - allocate_individual_rollback(A &a, multiallocation_chain &chain) + allocate_individual_rollback(Allocator &a, multiallocation_chain &chain) : mr_a(a), mp_chain(&chain) {} @@ -119,11 +113,11 @@ struct allocator_version_traits mp_chain = 0; } - A &mr_a; + Allocator &mr_a; multiallocation_chain * mp_chain; }; - static void allocate_individual(A &a, size_type n, multiallocation_chain &m) + static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) { allocate_individual_rollback rollback(a, m); while(n--){ @@ -132,21 +126,16 @@ struct allocator_version_traits rollback.release(); } - static std::pair - allocation_command(A &a, allocation_type command, - size_type, size_type preferred_size, - size_type &received_size, const pointer &) + static pointer allocation_command(Allocator &a, allocation_type command, + size_type, size_type &prefer_in_recvd_out_size, pointer &reuse) { - std::pair ret(pointer(), false); - if(!(command & allocate_new)){ - if(!(command & nothrow_allocation)){ - throw_logic_error("version 1 allocator without allocate_new flag"); - } + pointer ret = pointer(); + if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){ + throw_logic_error("version 1 allocator without allocate_new flag"); } else{ - received_size = preferred_size; BOOST_TRY{ - ret.first = a.allocate(received_size); + ret = a.allocate(prefer_in_recvd_out_size); } BOOST_CATCH(...){ if(!(command & nothrow_allocation)){ @@ -154,6 +143,7 @@ struct allocator_version_traits } } BOOST_CATCH_END + reuse = pointer(); } return ret; } diff --git a/include/boost/container/detail/compare_functors.hpp b/include/boost/container/detail/compare_functors.hpp index bfc6bb8..1b2a0ab 100644 --- a/include/boost/container/detail/compare_functors.hpp +++ b/include/boost/container/detail/compare_functors.hpp @@ -18,10 +18,10 @@ namespace boost { namespace container { -template +template class equal_to_value { - typedef typename A::value_type value_type; + typedef typename Allocator::value_type value_type; const value_type &t_; public: diff --git a/include/boost/container/detail/config_begin.hpp b/include/boost/container/detail/config_begin.hpp index ca9dd59..61fc059 100644 --- a/include/boost/container/detail/config_begin.hpp +++ b/include/boost/container/detail/config_begin.hpp @@ -17,32 +17,33 @@ #ifdef BOOST_MSVC #pragma warning (push) - #pragma warning (disable : 4702) // unreachable code - #pragma warning (disable : 4706) // assignment within conditional expression #pragma warning (disable : 4127) // conditional expression is constant #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned - #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4197) // top-level volatile in cast is ignored #pragma warning (disable : 4244) // possible loss of data #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" #pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4324) // structure was padded due to __declspec(align()) #pragma warning (disable : 4355) // "this" : used in base member initializer list #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated + #pragma warning (disable : 4510) // default constructor could not be generated #pragma warning (disable : 4511) // copy constructor could not be generated #pragma warning (disable : 4512) // assignment operator could not be generated #pragma warning (disable : 4514) // unreferenced inline removed #pragma warning (disable : 4521) // Disable "multiple copy constructors specified" #pragma warning (disable : 4522) // "class" : multiple assignment operators specified + #pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result + #pragma warning (disable : 4584) // X is already a base-class of Y + #pragma warning (disable : 4610) // struct can never be instantiated - user defined constructor required + #pragma warning (disable : 4671) // the copy constructor is inaccessible + #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter + #pragma warning (disable : 4702) // unreachable code + #pragma warning (disable : 4706) // assignment within conditional expression #pragma warning (disable : 4710) // function not inlined #pragma warning (disable : 4711) // function selected for automatic inline expansion #pragma warning (disable : 4786) // identifier truncated in debug info #pragma warning (disable : 4996) // "function": was declared deprecated - #pragma warning (disable : 4197) // top-level volatile in cast is ignored - #pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception' - // with /GR-; unpredictable behavior may result - #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site - #pragma warning (disable : 4671) // the copy constructor is inaccessible - #pragma warning (disable : 4584) // X is already a base-class of Y - #pragma warning (disable : 4510) // default constructor could not be generated #endif //BOOST_MSVC diff --git a/include/boost/container/detail/construct_in_place.hpp b/include/boost/container/detail/construct_in_place.hpp index 6314b72..1837200 100644 --- a/include/boost/container/detail/construct_in_place.hpp +++ b/include/boost/container/detail/construct_in_place.hpp @@ -23,30 +23,30 @@ namespace boost { namespace container { -template -inline void construct_in_place(A &a, T* dest, InpIt source) -{ boost::container::allocator_traits::construct(a, dest, *source); } +template +inline void construct_in_place(Allocator &a, T* dest, InpIt source) +{ boost::container::allocator_traits::construct(a, dest, *source); } -template -inline void construct_in_place(A &a, T *dest, value_init_construct_iterator) +template +inline void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator) { - boost::container::allocator_traits::construct(a, dest); + boost::container::allocator_traits::construct(a, dest); } template class default_init_construct_iterator; -template -inline void construct_in_place(A &a, T *dest, default_init_construct_iterator) +template +inline void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator) { - boost::container::allocator_traits::construct(a, dest, default_init); + boost::container::allocator_traits::construct(a, dest, default_init); } template class emplace_iterator; -template -inline void construct_in_place(A &a, T *dest, emplace_iterator ei) +template +inline void construct_in_place(Allocator &a, T *dest, emplace_iterator ei) { ei.construct_in_place(a, dest); } diff --git a/include/boost/container/detail/utilities.hpp b/include/boost/container/detail/copy_move_algo.hpp similarity index 72% rename from include/boost/container/detail/utilities.hpp rename to include/boost/container/detail/copy_move_algo.hpp index d6a6d2e..d5dca77 100644 --- a/include/boost/container/detail/utilities.hpp +++ b/include/boost/container/detail/copy_move_algo.hpp @@ -7,7 +7,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP #define BOOST_CONTAINER_DETAIL_UTILITIES_HPP @@ -15,167 +14,26 @@ # pragma once #endif -#include -#include - -#include -#include //for ::memmove / ::memcpy -#include -#include -#include -#include -#include -#include -#include -#include -#include +// container +#include +// container/detail #include -#include -#include -#include -#include -#include -#include +#include #include #include -#include -#include -#include -#include -#include - +// move #include +#include +#include +// other +#include +// std +#include //for emmove/memcpy namespace boost { namespace container { - -////////////////////////////////////////////////////////////////////////////// -// -// swap -// -////////////////////////////////////////////////////////////////////////////// - namespace container_detail { -template -inline T* addressof(T& obj) -{ - return static_cast( - static_cast( - const_cast( - &reinterpret_cast(obj) - ))); -} - -template -const T &max_value(const T &a, const T &b) -{ return a > b ? a : b; } - -template -const T &min_value(const T &a, const T &b) -{ return a < b ? a : b; } - -enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent }; - -template -struct next_capacity_calculator; - -template -struct next_capacity_calculator -{ - 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 -struct next_capacity_calculator -{ - 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 -inline T* iterator_to_pointer(T* i) -{ return i; } - -template -inline typename boost::container::iterator_traits::pointer - iterator_to_pointer(const Iterator &i) -{ return i.operator->(); } - -template -inline - typename boost::intrusive::pointer_traits - ::pointer>::element_type* - iterator_to_raw_pointer(const Iterator &i) -{ return (to_raw_pointer)((iterator_to_pointer)(i)); } - - -template -inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type) - BOOST_CONTAINER_NOEXCEPT -{} - -template -inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type) -{ boost::adl_move_swap(l, r); } - -template -inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type) - BOOST_CONTAINER_NOEXCEPT -{} - -template -inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type) -{ l = r; } - -template -inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type) - BOOST_CONTAINER_NOEXCEPT -{} - -template -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 -inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to) -{ - return ((orig_size-1)/round_to+1)*round_to; -} - -template -struct ct_rounded_size -{ - enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo }; -}; - template struct are_elements_contiguous { @@ -266,34 +124,34 @@ template struct is_memtransfer_copy_assignable { static const bool value = are_contiguous_and_same::value && - boost::has_trivial_assign< typename ::boost::container::iterator_traits::value_type >::value; + container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits::value_type >::value; }; template struct is_memtransfer_copy_constructible { static const bool value = are_contiguous_and_same::value && - boost::has_trivial_copy< typename ::boost::container::iterator_traits::value_type >::value; + container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits::value_type >::value; }; template struct enable_if_memtransfer_copy_constructible - : public enable_if_c::value, R> + : enable_if_c::value, R> {}; template struct disable_if_memtransfer_copy_constructible - : public enable_if_c::value, R> + : enable_if_c::value, R> {}; template struct enable_if_memtransfer_copy_assignable - : public enable_if_c::value, R> + : enable_if_c::value, R> {}; template struct disable_if_memtransfer_copy_assignable - : public enable_if_c::value, R> + : enable_if_c::value, R> {}; template @@ -347,32 +205,45 @@ struct is_memzero_initializable { typedef typename ::boost::container::iterator_traits::value_type value_type; static const bool value = are_elements_contiguous::value && - ( ::boost::is_integral::value || ::boost::is_enum::value + ( container_detail::is_integral::value || container_detail::is_enum::value #if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL) - || ::boost::is_pointer::value + || container_detail::is_pointer::value #endif #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) - || ::boost::is_floating_point::value + || container_detail::is_floating_point::value #endif #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL) - || ::boost::is_pod::value + || container_detail::is_pod::value #endif ); }; template struct enable_if_memzero_initializable - : public enable_if_c::value, R> + : enable_if_c::value, R> {}; template struct disable_if_memzero_initializable - : public enable_if_c::value, R> + : enable_if_c::value, R> +{}; + +template +struct enable_if_trivially_destructible + : enable_if_c < false/*container_detail::is_trivially_destructible + ::value_type>::value*/ + , R> +{}; + +template +struct disable_if_trivially_destructible + : enable_if_c ::value_type>::value*/ + , R> {}; } //namespace container_detail { - ////////////////////////////////////////////////////////////////////////////// // // uninitialized_move_alloc @@ -388,22 +259,22 @@ struct disable_if_memzero_initializable //! //! Returns: r template - // F models ForwardIterator inline typename container_detail::disable_if_memtransfer_copy_constructible::type - uninitialized_move_alloc(A &a, I f, I l, F r) + uninitialized_move_alloc(Allocator &a, I f, I l, F r) { F back = r; BOOST_TRY{ while (f != l) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -412,11 +283,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible // F models ForwardIterator inline typename container_detail::enable_if_memtransfer_copy_constructible::type - uninitialized_move_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT + uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT { return container_detail::memmove(f, l, r); } ////////////////////////////////////////////////////////////////////////////// @@ -433,22 +304,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructibleReturns: r template - // F models ForwardIterator inline typename container_detail::disable_if_memtransfer_copy_constructible::type - uninitialized_move_alloc_n(A &a, I f, typename boost::container::iterator_traits::difference_type n, F r) + uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -457,11 +328,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible // F models ForwardIterator inline typename container_detail::enable_if_memtransfer_copy_constructible::type - uninitialized_move_alloc_n(A &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT + uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT { return container_detail::memmove_n(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -478,22 +349,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructibleReturns: f (after incremented) template - // F models ForwardIterator inline typename container_detail::disable_if_memtransfer_copy_constructible::type - uninitialized_move_alloc_n_source(A &a, I f, typename boost::container::iterator_traits::difference_type n, F r) + uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -502,11 +373,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible // F models ForwardIterator inline typename container_detail::enable_if_memtransfer_copy_constructible::type - uninitialized_move_alloc_n_source(A &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT + uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT { return container_detail::memmove_n_source(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -523,22 +394,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructibleReturns: r template - // F models ForwardIterator inline typename container_detail::disable_if_memtransfer_copy_constructible::type - uninitialized_copy_alloc(A &a, I f, I l, F r) + uninitialized_copy_alloc(Allocator &a, I f, I l, F r) { F back = r; BOOST_TRY{ while (f != l) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), *f); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), *f); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -547,11 +418,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible // F models ForwardIterator inline typename container_detail::enable_if_memtransfer_copy_constructible::type - uninitialized_copy_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT + uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT { return container_detail::memmove(f, l, r); } ////////////////////////////////////////////////////////////////////////////// @@ -568,22 +439,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructibleReturns: r template - // F models ForwardIterator inline typename container_detail::disable_if_memtransfer_copy_constructible::type - uninitialized_copy_alloc_n(A &a, I f, typename boost::container::iterator_traits::difference_type n, F r) + uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), *f); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), *f); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -592,11 +463,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible // F models ForwardIterator inline typename container_detail::enable_if_memtransfer_copy_constructible::type - uninitialized_copy_alloc_n(A &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT + uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT { return container_detail::memmove_n(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -613,22 +484,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructibleReturns: f (after incremented) template - // F models ForwardIterator inline typename container_detail::disable_if_memtransfer_copy_constructible::type - uninitialized_copy_alloc_n_source(A &a, I f, typename boost::container::iterator_traits::difference_type n, F r) + uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), *f); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), *f); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -637,11 +508,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible // F models ForwardIterator inline typename container_detail::enable_if_memtransfer_copy_constructible::type - uninitialized_copy_alloc_n_source(A &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT + uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT { return container_detail::memmove_n_source(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -658,21 +529,21 @@ inline typename container_detail::enable_if_memtransfer_copy_constructibleReturns: r template - // F models ForwardIterator inline typename container_detail::disable_if_memzero_initializable::type - uninitialized_value_init_alloc_n(A &a, typename allocator_traits::difference_type n, F r) + uninitialized_value_init_alloc_n(Allocator &a, typename allocator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r)); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r)); ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -681,10 +552,10 @@ inline typename container_detail::disable_if_memzero_initializable::type } template - // F models ForwardIterator inline typename container_detail::enable_if_memzero_initializable::type - uninitialized_value_init_alloc_n(A &, typename allocator_traits::difference_type n, F r) + uninitialized_value_init_alloc_n(Allocator &, typename allocator_traits::difference_type n, F r) { typedef typename boost::container::iterator_traits::value_type value_type; ::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n); @@ -706,20 +577,20 @@ inline typename container_detail::enable_if_memzero_initializable::type //! //! Returns: r template - // F models ForwardIterator -inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits::difference_type n, F r) +inline F uninitialized_default_init_alloc_n(Allocator &a, typename allocator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), default_init); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), default_init); ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -741,21 +612,21 @@ inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits:: //! //! Returns: r template - -inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t) +inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t) { F back = f; BOOST_TRY{ while (f != l) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(f), t); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(f), t); ++f; } } BOOST_CATCH(...){ for (; back != l; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -777,21 +648,21 @@ inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t) //! //! Returns: r template - // F models ForwardIterator -inline F uninitialized_fill_alloc_n(A &a, const T &v, typename allocator_traits::difference_type n, F r) +inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename allocator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), v); + allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), v); ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -955,31 +826,38 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable move_n(I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT { return container_detail::memmove_n(f, n, r); } + ////////////////////////////////////////////////////////////////////////////// // -// move_n_source +// move_backward // ////////////////////////////////////////////////////////////////////////////// template - // F models ForwardIterator -inline typename container_detail::disable_if_memtransfer_copy_assignable::type - move_n_source(I f, typename boost::container::iterator_traits::difference_type n, F r) + // F models ForwardIterator +inline typename container_detail::disable_if_memtransfer_copy_assignable::type + move_backward(I f, I l, F r) { - while (n--) { - *r = ::boost::move(*f); - ++f; ++r; + while (f != l) { + --l; --r; + *r = ::boost::move(*l); } - return f; + return r; } template - // F models ForwardIterator -inline typename container_detail::enable_if_memtransfer_copy_assignable::type - move_n_source(I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT -{ return container_detail::memmove_n_source(f, n, r); } + // F models ForwardIterator +inline typename container_detail::enable_if_memtransfer_copy_assignable::type + move_backward(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT +{ + typedef typename boost::container::iterator_traits::value_type value_type; + const typename boost::container::iterator_traits::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 ////////////////////////////////////////////////////////////////////////////// // -// destroy_n +// move_n_source // ////////////////////////////////////////////////////////////////////////////// template - // I models InputIterator -inline void destroy_alloc_n(A &a, I f, typename boost::container::iterator_traits::difference_type n - ,typename boost::container::container_detail::enable_if_c - < !boost::has_trivial_destructor::value_type>::value >::type* = 0) + // F models ForwardIterator +inline typename container_detail::disable_if_memtransfer_copy_assignable::type + move_n_source(I f, typename boost::container::iterator_traits::difference_type n, F r) +{ + while (n--) { + *r = ::boost::move(*f); + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +inline typename container_detail::enable_if_memtransfer_copy_assignable::type + move_n_source(I f, typename boost::container::iterator_traits::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT +{ return container_detail::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// destroy_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + // U models unsigned integral constant +inline typename container_detail::disable_if_trivially_destructible::type + destroy_alloc_n(Allocator &a, I f, U n) { while(n--){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(f++)); + allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(f)); + ++f; } } template - // I models InputIterator -inline void destroy_alloc_n(A &, I, typename boost::container::iterator_traits::difference_type - ,typename boost::container::container_detail::enable_if_c - < boost::has_trivial_destructor::value_type>::value >::type* = 0) + // U models unsigned integral constant +inline typename container_detail::enable_if_trivially_destructible::type + destroy_alloc_n(Allocator &, I, U) {} ////////////////////////////////////////////////////////////////////////////// @@ -1041,15 +946,15 @@ inline void destroy_alloc_n(A &, I, typename boost::container::iterator_traits inline typename container_detail::disable_if_memtransfer_copy_assignable::type - deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits::size_type n_i - , G large_range_f, typename allocator_traits::size_type n_j) + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) { - typename allocator_traits::size_type n = 0; + typename allocator_traits::size_type n = 0; for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){ boost::adl_move_swap(*short_range_f, *large_range_f); } @@ -1061,18 +966,18 @@ static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_ template inline typename container_detail::enable_if_c < container_detail::is_memtransfer_copy_assignable::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false , void>::type - deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits::size_type n_i - , G large_range_f, typename allocator_traits::size_type n_j) + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) { - typedef typename allocator_traits::value_type value_type; - typedef typename boost::aligned_storage + typedef typename allocator_traits::value_type value_type; + typedef typename container_detail::aligned_storage ::value>::type storage_type; storage_type storage; @@ -1091,18 +996,18 @@ inline typename container_detail::enable_if_c template inline typename container_detail::enable_if_c < container_detail::is_memtransfer_copy_assignable::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage) , void>::type - deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits::size_type n_i - , G large_range_f, typename allocator_traits::size_type n_j) + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) { - typedef typename allocator_traits::value_type value_type; - typedef typename boost::aligned_storage + typedef typename allocator_traits::value_type value_type; + typedef typename container_detail::aligned_storage ::value>::type storage_type; storage_type storage; const std::size_t sizeof_storage = sizeof(storage); @@ -1168,12 +1073,12 @@ inline typename container_detail::enable_if_c ////////////////////////////////////////////////////////////////////////////// template - -void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits::size_type n_i - , O out_start, typename allocator_traits::size_type n_o ) +void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits::size_type n_i + , O out_start, typename allocator_traits::size_type n_o ) { if (n_o < n_i){ inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw @@ -1192,12 +1097,12 @@ void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits: ////////////////////////////////////////////////////////////////////////////// template - -void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits::size_type n_i - , O out_start, typename allocator_traits::size_type n_o ) +void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits::size_type n_i + , O out_start, typename allocator_traits::size_type n_o ) { if (n_o < n_i){ inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw @@ -1212,6 +1117,4 @@ void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits: } //namespace container { } //namespace boost { -#include - #endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP diff --git a/include/boost/container/detail/destroyers.hpp b/include/boost/container/detail/destroyers.hpp index 96a61ef..c96b491 100644 --- a/include/boost/container/detail/destroyers.hpp +++ b/include/boost/container/detail/destroyers.hpp @@ -20,9 +20,9 @@ #include #include -#include -#include #include +#include +#include namespace boost { namespace container { @@ -30,22 +30,20 @@ namespace container_detail { //!A deleter for scoped_ptr that deallocates the memory //!allocated for an object using a STL allocator. -template +template struct scoped_deallocator { - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; typedef typename allocator_traits_type::pointer pointer; typedef container_detail::integral_constant::value> alloc_version; - typedef container_detail::integral_constant allocator_v1; - typedef container_detail::integral_constant allocator_v2; + version::value> alloc_version; private: - void priv_deallocate(allocator_v1) + void priv_deallocate(version_1) { m_alloc.deallocate(m_ptr, 1); } - void priv_deallocate(allocator_v2) + void priv_deallocate(version_2) { m_alloc.deallocate_one(m_ptr); } BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator) @@ -53,9 +51,9 @@ struct scoped_deallocator public: pointer m_ptr; - A& m_alloc; + Allocator& m_alloc; - scoped_deallocator(pointer p, A& a) + scoped_deallocator(pointer p, Allocator& a) : m_ptr(p), m_alloc(a) {} @@ -76,14 +74,14 @@ struct scoped_deallocator { m_ptr = 0; } }; -template +template struct null_scoped_deallocator { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; - null_scoped_deallocator(pointer, A&, size_type) + null_scoped_deallocator(pointer, Allocator&, size_type) {} void release() @@ -98,14 +96,14 @@ struct null_scoped_deallocator //!A deleter for scoped_ptr that deallocates the memory //!allocated for an array of objects using a STL allocator. -template +template struct scoped_array_deallocator { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; - scoped_array_deallocator(pointer p, A& a, size_type length) + scoped_array_deallocator(pointer p, Allocator& a, size_type length) : m_ptr(p), m_alloc(a), m_length(length) {} ~scoped_array_deallocator() @@ -116,37 +114,35 @@ struct scoped_array_deallocator private: pointer m_ptr; - A& m_alloc; + Allocator& m_alloc; size_type m_length; }; -template +template struct null_scoped_array_deallocator { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; - null_scoped_array_deallocator(pointer, A&, size_type) + null_scoped_array_deallocator(pointer, Allocator&, size_type) {} void release() {} }; -template +template struct scoped_destroy_deallocator { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; typedef container_detail::integral_constant::value> alloc_version; - typedef container_detail::integral_constant allocator_v1; - typedef container_detail::integral_constant allocator_v2; + version::value> alloc_version; - scoped_destroy_deallocator(pointer p, A& a) + scoped_destroy_deallocator(pointer p, Allocator& a) : m_ptr(p), m_alloc(a) {} ~scoped_destroy_deallocator() @@ -162,28 +158,28 @@ struct scoped_destroy_deallocator private: - void priv_deallocate(const pointer &p, allocator_v1) + void priv_deallocate(const pointer &p, version_1) { AllocTraits::deallocate(m_alloc, p, 1); } - void priv_deallocate(const pointer &p, allocator_v2) + void priv_deallocate(const pointer &p, version_2) { m_alloc.deallocate_one(p); } pointer m_ptr; - A& m_alloc; + Allocator& m_alloc; }; //!A deleter for scoped_ptr that destroys //!an object using a STL allocator. -template +template struct scoped_destructor_n { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::value_type value_type; typedef typename AllocTraits::size_type size_type; - scoped_destructor_n(pointer p, A& a, size_type n) + scoped_destructor_n(pointer p, Allocator& a, size_type n) : m_p(p), m_a(a), m_n(n) {} @@ -210,20 +206,20 @@ struct scoped_destructor_n private: pointer m_p; - A & m_a; + Allocator & m_a; size_type m_n; }; //!A deleter for scoped_ptr that destroys //!an object using a STL allocator. -template +template struct null_scoped_destructor_n { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; - null_scoped_destructor_n(pointer, A&, size_type) + null_scoped_destructor_n(pointer, Allocator&, size_type) {} void increment_size(size_type) @@ -239,13 +235,13 @@ struct null_scoped_destructor_n {} }; -template +template class scoped_destructor { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; public: - typedef typename A::value_type value_type; - scoped_destructor(A &a, value_type *pv) + typedef typename Allocator::value_type value_type; + scoped_destructor(Allocator &a, value_type *pv) : pv_(pv), a_(a) {} @@ -266,17 +262,17 @@ class scoped_destructor private: value_type *pv_; - A &a_; + Allocator &a_; }; -template +template class value_destructor { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; public: - typedef typename A::value_type value_type; - value_destructor(A &a, value_type &rv) + typedef typename Allocator::value_type value_type; + value_destructor(Allocator &a, value_type &rv) : rv_(rv), a_(a) {} @@ -287,33 +283,31 @@ class value_destructor private: value_type &rv_; - A &a_; + Allocator &a_; }; -template +template class allocator_destroyer { - typedef boost::container::allocator_traits AllocTraits; + typedef boost::container::allocator_traits AllocTraits; typedef typename AllocTraits::value_type value_type; typedef typename AllocTraits::pointer pointer; typedef container_detail::integral_constant::value> alloc_version; - typedef container_detail::integral_constant allocator_v1; - typedef container_detail::integral_constant allocator_v2; + version::value> alloc_version; private: - A & a_; + Allocator & a_; private: - void priv_deallocate(const pointer &p, allocator_v1) + void priv_deallocate(const pointer &p, version_1) { AllocTraits::deallocate(a_,p, 1); } - void priv_deallocate(const pointer &p, allocator_v2) + void priv_deallocate(const pointer &p, version_2) { a_.deallocate_one(p); } public: - allocator_destroyer(A &a) + allocator_destroyer(Allocator &a) : a_(a) {} @@ -324,41 +318,41 @@ class allocator_destroyer } }; -template +template class allocator_destroyer_and_chain_builder { - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; - typedef typename A::multiallocation_chain multiallocation_chain; + typedef typename Allocator::multiallocation_chain multiallocation_chain; - A & a_; + Allocator & a_; multiallocation_chain &c_; public: - allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c) + allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c) : a_(a), c_(c) {} - void operator()(const typename A::pointer &p) + void operator()(const typename Allocator::pointer &p) { - allocator_traits::destroy(a_, container_detail::to_raw_pointer(p)); + allocator_traits::destroy(a_, container_detail::to_raw_pointer(p)); c_.push_back(p); } }; -template +template class allocator_multialloc_chain_node_deallocator { - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; - typedef typename A::multiallocation_chain multiallocation_chain; - typedef allocator_destroyer_and_chain_builder chain_builder; + typedef typename Allocator::multiallocation_chain multiallocation_chain; + typedef allocator_destroyer_and_chain_builder chain_builder; - A & a_; + Allocator & a_; multiallocation_chain c_; public: - allocator_multialloc_chain_node_deallocator(A &a) + allocator_multialloc_chain_node_deallocator(Allocator &a) : a_(a), c_() {} diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index e066a0c..6acbfb1 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -20,10 +20,8 @@ #include -#include #include -#include #include #include #include @@ -34,11 +32,14 @@ #ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER #include #endif -#include +#include #include #include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif -#include //std::pair +#include //pair namespace boost { namespace container { @@ -94,11 +95,11 @@ struct get_flat_tree_iterators }; template + class Compare, class Allocator> class flat_tree { - typedef boost::container::vector vector_t; - typedef A allocator_t; + typedef boost::container::vector vector_t; + typedef Allocator allocator_t; public: typedef flat_tree_value_compare value_compare; @@ -123,11 +124,11 @@ class flat_tree : value_compare(boost::move(static_cast(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(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(d))), m_vect(boost::move(d.m_vect), a) {} @@ -496,12 +497,12 @@ class flat_tree ) { this->priv_insert_ordered_range(true, first, last); } - #ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - std::pair emplace_unique(Args&&... args) + std::pair emplace_unique(BOOST_FWD_REF(Args)... args) { - aligned_storage::value> v; + typename aligned_storage::value>::type v; value_type &val = *static_cast(static_cast(&v)); stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); @@ -510,9 +511,9 @@ class flat_tree } template - iterator emplace_hint_unique(const_iterator hint, Args&&... args) + iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args) { - aligned_storage::value> v; + typename aligned_storage::value>::type v; value_type &val = *static_cast(static_cast(&v)); stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); @@ -521,9 +522,9 @@ class flat_tree } template - iterator emplace_equal(Args&&... args) + iterator emplace_equal(BOOST_FWD_REF(Args)... args) { - aligned_storage::value> v; + typename aligned_storage::value>::type v; value_type &val = *static_cast(static_cast(&v)); stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); @@ -532,9 +533,9 @@ class flat_tree } template - iterator emplace_hint_equal(const_iterator hint, Args&&... args) + iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args) { - aligned_storage::value> v; + typename aligned_storage::value>::type v; value_type &val = *static_cast(static_cast(&v)); stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); @@ -542,64 +543,57 @@ class flat_tree return this->insert_equal(hint, ::boost::move(val)); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - std::pair \ - emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - aligned_storage::value> v; \ - value_type &val = *static_cast(static_cast(&v)); \ - stored_allocator_type &a = this->get_stored_allocator(); \ - stored_allocator_traits::construct(a, &val \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ - value_destructor d(a, val); \ - return this->insert_unique(::boost::move(val)); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint_unique(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - aligned_storage::value> v; \ - value_type &val = *static_cast(static_cast(&v)); \ - stored_allocator_type &a = this->get_stored_allocator(); \ - stored_allocator_traits::construct(a, &val \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ - value_destructor d(a, val); \ - return this->insert_unique(hint, ::boost::move(val)); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - aligned_storage::value> v; \ - value_type &val = *static_cast(static_cast(&v)); \ - stored_allocator_type &a = this->get_stored_allocator(); \ - stored_allocator_traits::construct(a, &val \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ - value_destructor d(a, val); \ - return this->insert_equal(::boost::move(val)); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint_equal(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - aligned_storage::value> v; \ - value_type &val = *static_cast(static_cast(&v)); \ - stored_allocator_type &a = this->get_stored_allocator(); \ - stored_allocator_traits::construct(a, &val \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ - value_destructor d(a, val); \ - return this->insert_equal(hint, ::boost::move(val)); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + std::pair emplace_unique(BOOST_MOVE_UREF##N)\ + {\ + typename aligned_storage::value>::type v;\ + value_type &val = *static_cast(static_cast(&v));\ + stored_allocator_type &a = this->get_stored_allocator();\ + stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + value_destructor d(a, val);\ + return this->insert_unique(::boost::move(val));\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + typename aligned_storage::value>::type v;\ + value_type &val = *static_cast(static_cast(&v));\ + stored_allocator_type &a = this->get_stored_allocator();\ + stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + value_destructor d(a, val);\ + return this->insert_unique(hint, ::boost::move(val));\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_equal(BOOST_MOVE_UREF##N)\ + {\ + typename aligned_storage::value>::type v;\ + value_type &val = *static_cast(static_cast(&v));\ + stored_allocator_type &a = this->get_stored_allocator();\ + stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + value_destructor d(a, val);\ + return this->insert_equal(::boost::move(val));\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + typename aligned_storage ::value>::type v;\ + value_type &val = *static_cast(static_cast(&v));\ + stored_allocator_type &a = this->get_stored_allocator();\ + stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + value_destructor d(a, val);\ + return this->insert_equal(hint, ::boost::move(val));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE) + #undef BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) iterator erase(const_iterator position) { return this->m_data.m_vect.erase(position); } @@ -965,7 +959,7 @@ class flat_tree for(; checked != burst; ++checked){ //Get the insertion position for each key, use iterator_traits::value_type //because it can be different from container::value_type - //(e.g. conversion between std::pair -> boost::container::pair + //(e.g. conversion between std::pair -> boost::container::pair const typename boost::container::iterator_traits::value_type & val = *first; pos = const_cast(*this).priv_lower_bound(pos, ce, KeyOfValue()(val)); //Check if already present @@ -1012,16 +1006,18 @@ class flat_tree } //namespace container_detail { } //namespace container { -/* + //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; -*/ + } //namespace boost { #include diff --git a/include/boost/container/detail/hash_table.hpp b/include/boost/container/detail/hash_table.hpp index 0fad5a4..4bc5c90 100644 --- a/include/boost/container/detail/hash_table.hpp +++ b/include/boost/container/detail/hash_table.hpp @@ -1,6 +1,6 @@ /* template , class Pred = equal_to, - class Alloc = allocator > + class Allocator = allocator > class hash_set { public: @@ -9,7 +9,7 @@ public: typedef key_type value_type; typedef Hash hasher; typedef Pred key_equal; - typedef Alloc allocator_type; + typedef Allocator allocator_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename allocator_traits::pointer pointer; @@ -37,13 +37,13 @@ public: const allocator_type& a = allocator_type()); explicit hash_set(const allocator_type&); hash_set(const hash_set&); - hash_set(const hash_set&, const A&); + hash_set(const hash_set&, const Allocator&); hash_set(hash_set&&) noexcept( is_nothrow_move_constructible::value && is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); - hash_set(hash_set&&, const A&); + hash_set(hash_set&&, const Allocator&); hash_set(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); @@ -71,9 +71,9 @@ public: const_iterator cend() const noexcept; template - pair emplace(Args&&... args); + pair emplace(BOOST_FWD_REF(Args)... args); template - iterator emplace_hint(const_iterator position, Args&&... args); + iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args); pair insert(const value_type& obj); pair insert(value_type&& obj); iterator insert(const_iterator hint, const value_type& obj); @@ -124,7 +124,7 @@ public: }; template , class Pred = equal_to, - class Alloc = allocator > > + class Allocator = allocator > > class hash_map { public: @@ -133,7 +133,7 @@ public: typedef T mapped_type; typedef Hash hasher; typedef Pred key_equal; - typedef Alloc allocator_type; + typedef Allocator allocator_type; typedef pair value_type; typedef value_type& reference; typedef const value_type& const_reference; @@ -162,13 +162,13 @@ public: const allocator_type& a = allocator_type()); explicit hash_map(const allocator_type&); hash_map(const hash_map&); - hash_map(const hash_map&, const A&); + hash_map(const hash_map&, const Allocator&); hash_map(hash_map&&) noexcept( is_nothrow_move_constructible::value && is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); - hash_map(hash_map&&, const A&); + hash_map(hash_map&&, const Allocator&); hash_map(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); @@ -196,9 +196,9 @@ public: const_iterator cend() const noexcept; template - pair emplace(Args&&... args); + pair emplace(BOOST_FWD_REF(Args)... args); template - iterator emplace_hint(const_iterator position, Args&&... args); + iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args); pair insert(const value_type& obj); template pair insert(P&& obj); @@ -259,7 +259,7 @@ public: */ template , class Pred = equal_to, - class Alloc = allocator > + class Allocator = allocator > class hash_table { public: @@ -268,7 +268,7 @@ public: typedef key_type value_type; typedef Hash hasher; typedef Pred key_equal; - typedef Alloc allocator_type; + typedef Allocator allocator_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename allocator_traits::pointer pointer; @@ -296,13 +296,13 @@ public: const allocator_type& a = allocator_type()); explicit hash_set(const allocator_type&); hash_set(const hash_set&); - hash_set(const hash_set&, const A&); + hash_set(const hash_set&, const Allocator&); hash_set(hash_set&&) noexcept( is_nothrow_move_constructible::value && is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); - hash_set(hash_set&&, const A&); + hash_set(hash_set&&, const Allocator&); hash_set(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); @@ -330,9 +330,9 @@ public: const_iterator cend() const noexcept; template - pair emplace(Args&&... args); + pair emplace(BOOST_FWD_REF(Args)... args); template - iterator emplace_hint(const_iterator position, Args&&... args); + iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args); pair insert(const value_type& obj); pair insert(value_type&& obj); iterator insert(const_iterator hint, const value_type& obj); diff --git a/include/boost/container/detail/iterator_to_raw_pointer.hpp b/include/boost/container/detail/iterator_to_raw_pointer.hpp new file mode 100644 index 0000000..b70abe0 --- /dev/null +++ b/include/boost/container/detail/iterator_to_raw_pointer.hpp @@ -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 +#include +#include + +namespace boost { +namespace container { +namespace container_detail { + +template +inline T* iterator_to_pointer(T* i) +{ return i; } + +template +inline typename boost::container::iterator_traits::pointer + iterator_to_pointer(const Iterator &i) +{ return i.operator->(); } + +template +struct iterator_to_element_ptr +{ + typedef typename boost::container::iterator_traits::pointer pointer; + typedef typename boost::intrusive::pointer_traits::element_type element_type; + typedef element_type* type; +}; + +template +inline typename iterator_to_element_ptr::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 diff --git a/include/boost/container/detail/iterators.hpp b/include/boost/container/detail/iterators.hpp index 732d1f1..4490e7b 100644 --- a/include/boost/container/detail/iterators.hpp +++ b/include/boost/container/detail/iterators.hpp @@ -26,12 +26,11 @@ #include #include -#ifdef BOOST_CONTAINER_PERFECT_FORWARDING -#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include #else -#include +#include #endif - #include namespace boost { @@ -564,8 +563,8 @@ class emplace_iterator //const T& operator[](difference_type) const; //const T* operator->() const; - template - void construct_in_place(A &a, T* ptr) + template + void construct_in_place(Allocator &a, T* ptr) { (*m_pe)(a, ptr); } private: @@ -597,54 +596,49 @@ class emplace_iterator { return difference_type(m_num - other.m_num); } }; -#ifdef BOOST_CONTAINER_PERFECT_FORWARDING +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template struct emplace_functor { typedef typename container_detail::build_number_seq::type index_tuple_t; - emplace_functor(Args&&... args) + emplace_functor(BOOST_FWD_REF(Args)... args) : args_(args...) {} - template - void operator()(A &a, T *ptr) + template + void operator()(Allocator &a, T *ptr) { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); } - template - void inplace_impl(A &a, T* ptr, const container_detail::index_tuple&) + template + void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple&) { - allocator_traits::construct + allocator_traits::construct (a, ptr, ::boost::forward(container_detail::get(args_))...); } container_detail::tuple args_; }; -#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template <) \ - BOOST_PP_ENUM_PARAMS(n, class P) \ - BOOST_PP_EXPR_IF(n, >) \ - struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ - { \ - BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ - ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ - BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \ - \ - template \ - void operator()(A &a, T *ptr) \ - { \ - allocator_traits::construct \ - (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \ - } \ - BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \ - }; \ - //! -#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) -#include BOOST_PP_LOCAL_ITERATE() +#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \ +BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ +struct emplace_functor##N\ +{\ + explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ + BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ + \ + template\ + void operator()(Allocator &a, T *ptr)\ + { allocator_traits::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\ + \ + BOOST_MOVE_MREF##N\ +};\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE) +#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE #endif diff --git a/include/boost/container/detail/memory_util.hpp b/include/boost/container/detail/memory_util.hpp deleted file mode 100644 index 16d03cd..0000000 --- a/include/boost/container/detail/memory_util.hpp +++ /dev/null @@ -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 -#include - -#include -#include -#include - - -#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, )) -#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, )) -#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, )) -#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, )) -#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, )) -#else -# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, )) -#endif -#include BOOST_PP_ITERATE() - -#include - -#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP) diff --git a/include/boost/container/detail/min_max.hpp b/include/boost/container/detail/min_max.hpp new file mode 100644 index 0000000..0957e8e --- /dev/null +++ b/include/boost/container/detail/min_max.hpp @@ -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 +const T &max_value(const T &a, const T &b) +{ return a > b ? a : b; } + +template +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 diff --git a/include/boost/container/detail/mpl.hpp b/include/boost/container/detail/mpl.hpp index ceac52a..f1494c0 100644 --- a/include/boost/container/detail/mpl.hpp +++ b/include/boost/container/detail/mpl.hpp @@ -169,6 +169,12 @@ struct ls_zeros<1> static const std::size_t value = 0; }; +template +struct ct_rounded_size +{ + static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo; +}; + template struct unvoid { typedef T type; }; template <> struct unvoid { struct type { }; }; template <> struct unvoid { struct type { }; }; diff --git a/include/boost/container/detail/multiallocation_chain.hpp b/include/boost/container/detail/multiallocation_chain.hpp index 96f6202..1ad26d9 100644 --- a/include/boost/container/detail/multiallocation_chain.hpp +++ b/include/boost/container/detail/multiallocation_chain.hpp @@ -17,14 +17,16 @@ #include #include - +// container #include -#include -#include +// container/detail +#include #include +#include +// intrusive #include #include -#include +// move #include namespace boost { @@ -47,7 +49,7 @@ class basic_multiallocation_chain typedef bi::slist< node , bi::linear , bi::cache_last - , bi::size_type::type> + , bi::size_type::type> > slist_impl_t; slist_impl_t slist_impl_; diff --git a/include/boost/container/detail/mutex.hpp b/include/boost/container/detail/mutex.hpp index c53afa1..f6184e0 100644 --- a/include/boost/container/detail/mutex.hpp +++ b/include/boost/container/detail/mutex.hpp @@ -162,7 +162,7 @@ #define BOOST_CONTAINER_TRY_LOCK(sl) !BOOST_CONTAINER_CAS_LOCK(sl) #define BOOST_CONTAINER_RELEASE_LOCK(sl) BOOST_CONTAINER_CLEAR_LOCK(sl) #define BOOST_CONTAINER_ACQUIRE_LOCK(sl) (BOOST_CONTAINER_CAS_LOCK(sl)? boost_interprocess_spin_acquire_lock(sl) : 0) - #define BOOST_CONTAINER_INITIAL_LOCK(sl) (*sl = 0) + #define BOOST_MOVE_INITIAL_LOCK(sl) (*sl = 0) #define BOOST_CONTAINER_DESTROY_LOCK(sl) (0) #elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32 // @@ -199,7 +199,7 @@ namespace container_detail { void operator=(const spin_mutex &); public: - spin_mutex() { BOOST_CONTAINER_INITIAL_LOCK(&sl); } + spin_mutex() { BOOST_MOVE_INITIAL_LOCK(&sl); } void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); } void unlock() { BOOST_CONTAINER_RELEASE_LOCK(&sl); } diff --git a/include/boost/container/detail/next_capacity.hpp b/include/boost/container/detail/next_capacity.hpp new file mode 100644 index 0000000..e951985 --- /dev/null +++ b/include/boost/container/detail/next_capacity.hpp @@ -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 +// container/detail +#include + +namespace boost { +namespace container { +namespace container_detail { + +enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent }; + +template +struct next_capacity_calculator; + +template +struct next_capacity_calculator +{ + 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 +struct next_capacity_calculator +{ + 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 diff --git a/include/boost/container/detail/node_alloc_holder.hpp b/include/boost/container/detail/node_alloc_holder.hpp index 50441e9..1c36482 100644 --- a/include/boost/container/detail/node_alloc_holder.hpp +++ b/include/boost/container/detail/node_alloc_holder.hpp @@ -18,29 +18,30 @@ #include #include -#include -#include - -#include -#include - -#include -#include -#include +// container #include +// container/detail +#include +#include #include -#include -#include -#include - -#include -#include - -#ifndef BOOST_CONTAINER_PERFECT_FORWARDING -#include -#endif - #include +#include +#include +#include +#include +#include +#include +#include +// intrusive +#include +#include +// move +#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +// other +#include namespace boost { @@ -50,7 +51,7 @@ namespace container_detail { BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type) -template +template struct node_alloc_holder { //If the intrusive container is an associative container, obtain the predicate, which will @@ -62,7 +63,7 @@ struct node_alloc_holder typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare, predicate_type, container_detail::nat) value_compare; - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef ICont intrusive_container; typedef typename ICont::value_type Node; @@ -70,13 +71,11 @@ struct node_alloc_holder portable_rebind_alloc::type NodeAlloc; typedef allocator_traits node_allocator_traits_type; typedef container_detail::allocator_version_traits node_allocator_version_traits_type; - typedef A ValAlloc; + typedef Allocator ValAlloc; typedef typename node_allocator_traits_type::pointer NodePtr; typedef container_detail::scoped_deallocator Deallocator; typedef typename node_allocator_traits_type::size_type size_type; typedef typename node_allocator_traits_type::difference_type difference_type; - typedef container_detail::integral_constant allocator_v1; - typedef container_detail::integral_constant allocator_v2; typedef container_detail::integral_constant::value> alloc_version; @@ -152,7 +151,7 @@ struct node_alloc_holder void deallocate_one(const NodePtr &p) { AllocVersionTraits::deallocate_one(this->node_alloc(), p); } - #ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template NodePtr create_node(Args &&...args) @@ -169,28 +168,90 @@ struct node_alloc_holder return (p); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + NodePtr create_node() + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + allocator_traits::construct + (this->node_alloc(), container_detail::addressof(p->m_data)); + node_deallocator.release(); + typedef typename Node::hook_type hook_type; + ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + return (p); + } - #define BOOST_PP_LOCAL_MACRO(n) \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - NodePtr p = this->allocate_one(); \ - Deallocator node_deallocator(p, this->node_alloc()); \ - allocator_traits::construct \ - (this->node_alloc(), container_detail::addressof(p->m_data) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - node_deallocator.release(); \ - typedef typename Node::hook_type hook_type; \ - ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; \ - return (p); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + template + NodePtr create_node(BOOST_MOVE_UREF1) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + allocator_traits::construct + (this->node_alloc(), container_detail::addressof(p->m_data) + , BOOST_MOVE_FWD1); + node_deallocator.release(); + typedef typename Node::hook_type hook_type; + ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + return (p); + } - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + template + NodePtr create_node(BOOST_MOVE_UREF2) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + allocator_traits::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(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + return (p); + } + + template + NodePtr create_node(BOOST_MOVE_UREF3) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + allocator_traits::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(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + return (p); + } + + template + NodePtr create_node(BOOST_MOVE_UREF4) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + allocator_traits::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(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + return (p); + } + + template + NodePtr create_node(BOOST_MOVE_UREF5) + { + NodePtr p = this->allocate_one(); + Deallocator node_deallocator(p, this->node_alloc()); + allocator_traits::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(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + return (p); + } + + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template NodePtr create_node_from_it(const It &it) @@ -237,7 +298,7 @@ struct node_alloc_holder Deallocator node_deallocator(NodePtr(), nalloc); container_detail::scoped_destructor sdestructor(nalloc, 0); while(n--){ - p = container_detail::to_raw_pointer(iterator_to_pointer(itbeg)); + p = container_detail::iterator_to_raw_pointer(itbeg); node_deallocator.set(p); ++itbeg; //This can throw @@ -264,10 +325,10 @@ struct node_alloc_holder } } - void clear(allocator_v1) + void clear(version_1) { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } - void clear(allocator_v2) + void clear(version_2) { typename NodeAlloc::multiallocation_chain chain; allocator_destroyer_and_chain_builder builder(this->node_alloc(), chain); @@ -277,10 +338,10 @@ struct node_alloc_holder this->node_alloc().deallocate_individual(chain); } - icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1) + icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1) { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); } - icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2) + icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2) { typedef typename NodeAlloc::multiallocation_chain multiallocation_chain; NodeAlloc & nalloc = this->node_alloc(); @@ -292,11 +353,11 @@ struct node_alloc_holder } template - size_type erase_key(const Key& k, const Comparator &comp, allocator_v1) + size_type erase_key(const Key& k, const Comparator &comp, version_1) { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); } template - 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 chain_holder(this->node_alloc()); return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder()); diff --git a/include/boost/container/detail/node_pool_impl.hpp b/include/boost/container/detail/node_pool_impl.hpp index 2450e51..7538fa4 100644 --- a/include/boost/container/detail/node_pool_impl.hpp +++ b/include/boost/container/detail/node_pool_impl.hpp @@ -7,7 +7,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP #define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP @@ -17,16 +16,18 @@ #include #include - #include -#include -#include -#include -#include -#include + #include #include #include +#include +#include + +#include +#include +#include + #include #include #include @@ -57,6 +58,10 @@ class private_node_pool_impl < node_t, bi::base_hook , bi::linear , bi::constant_time_size >::type blockslist_t; + + static size_type get_rounded_size(size_type orig_size, size_type round_to) + { return ((orig_size-1)/round_to+1)*round_to; } + public: //!Segment manager typedef @@ -145,7 +150,7 @@ class private_node_pool_impl nodelist_iterator backup_list_last = backup_list.before_begin(); //Execute the algorithm and get an iterator to the last value - size_type blocksize = get_rounded_size + size_type blocksize = (get_rounded_size) (m_real_node_size*m_nodes_per_block, (size_type) alignment_of::value); while(it != itend){ @@ -205,7 +210,7 @@ class private_node_pool_impl { //check for memory leaks BOOST_ASSERT(m_allocated==0); - size_type blocksize = get_rounded_size + size_type blocksize = (get_rounded_size) (m_real_node_size*m_nodes_per_block, (size_type)alignment_of::value); //We iterate though the NodeBlock list to free the memory @@ -298,7 +303,7 @@ class private_node_pool_impl { BOOST_ASSERT(num_blocks > 0); size_type blocksize = - get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of::value); + (get_rounded_size)(m_real_node_size*m_nodes_per_block, (size_type)alignment_of::value); BOOST_TRY{ for(size_type i = 0; i != num_blocks; ++i){ diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp index 91e4d1e..0b4e253 100644 --- a/include/boost/container/detail/pair.hpp +++ b/include/boost/container/detail/pair.hpp @@ -26,16 +26,9 @@ #include #include //swap -#include //std::pair - - +#include //pair #include - -#ifndef BOOST_CONTAINER_PERFECT_FORWARDING -#include -#endif - namespace boost { namespace container { namespace container_detail { @@ -167,37 +160,7 @@ struct pair //template // pair(piecewise_construct_t, tuple first_args, // tuple second_args); -/* - //Variadic versions - template - pair(BOOST_CONTAINER_PP_PARAM(U, u), typename container_detail::disable_if - < container_detail::is_pair< typename container_detail::remove_ref_const::type >, pair_nat>::type* = 0) - : first(::boost::forward(u)) - , second() - {} - #ifdef BOOST_CONTAINER_PERFECT_FORWARDING - - template - pair(U &&u, V &&v) - : first(::boost::forward(u)) - , second(::boost::forward(v), ::boost::forward(args)...) - {} - - #else - - #define BOOST_PP_LOCAL_MACRO(n) \ - template \ - pair(BOOST_CONTAINER_PP_PARAM(U, u) \ - ,BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - : first(::boost::forward(u)) \ - , second(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \ - {} \ - //! - #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() - #endif -*/ //pair copy assignment pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p) { diff --git a/include/boost/container/detail/preprocessor.hpp b/include/boost/container/detail/preprocessor.hpp deleted file mode 100644 index 838eff2..0000000 --- a/include/boost/container/detail/preprocessor.hpp +++ /dev/null @@ -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 -#include -#include - -#ifdef BOOST_CONTAINER_PERFECT_FORWARDING -//#error "This file is not needed when perfect forwarding is available" -#endif //BOOST_CONTAINER_PERFECT_FORWARDING - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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))) \ - //! -#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 - struct ref_holder; - - template - struct ref_holder - { - explicit ref_holder(T &t) - : t_(t) - {} - T &t_; - T & get() { return t_; } - }; - - template - struct ref_holder - { - explicit ref_holder(const T &t) - : t_(t) - {} - const T &t_; - const T & get() { return t_; } - }; - - template - struct ref_holder - { - explicit ref_holder(const T &t) - : t_(t) - {} - const T &t_; - const T & get() { return t_; } - }; - - template - struct ref_holder - { - explicit ref_holder(T &&t) - : t_(t) - {} - T &t_; - T && get() { return ::boost::move(t_); } - }; - - template - struct ref_holder - { - 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(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 - -//#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 diff --git a/include/boost/container/detail/to_raw_pointer.hpp b/include/boost/container/detail/to_raw_pointer.hpp new file mode 100644 index 0000000..76162b1 --- /dev/null +++ b/include/boost/container/detail/to_raw_pointer.hpp @@ -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 + +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 diff --git a/include/boost/container/detail/transform_iterator.hpp b/include/boost/container/detail/transform_iterator.hpp index de6f1ef..b309c23 100644 --- a/include/boost/container/detail/transform_iterator.hpp +++ b/include/boost/container/detail/transform_iterator.hpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace boost { namespace container { diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index 274ae46..d7b59ea 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -17,55 +17,56 @@ #include #include +// container +#include #include +#include -#include +// container/detail +#include //algo_equal(), algo_lexicographical_compare +#include +#include +#include #include #include -#include #include #include -#include //algo_equal(), algo_lexicographical_compare -#include -#include -#include -#include -// +// intrusive #include #include #include #include #include -// +// intrusive/detail +#include //pair +// move #include -#include -#include -// -#ifndef BOOST_CONTAINER_PERFECT_FORWARDING -#include +// move/detail +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include #endif - -#include //std::pair +// other +#include namespace boost { namespace container { namespace container_detail { -template +template struct tree_value_compare - : public KeyCompare + : public Compare { - typedef Value value_type; - typedef KeyCompare key_compare; + typedef T value_type; + typedef Compare key_compare; typedef KeyOfValue key_of_value; typedef Key key_type; explicit tree_value_compare(const key_compare &kcomp) - : KeyCompare(kcomp) + : Compare(kcomp) {} tree_value_compare() - : KeyCompare() + : Compare() {} const key_compare &key_comp() const @@ -74,20 +75,20 @@ struct tree_value_compare key_compare &key_comp() { return static_cast(*this); } - template + template struct is_key { - static const bool value = is_same::value; + static const bool value = is_same::value; }; - template - typename enable_if_c::value, const key_type &>::type - key_forward(const T &key) const + template + typename enable_if_c::value, const key_type &>::type + key_forward(const U &key) const { return key; } - template - typename enable_if_c::value, const key_type &>::type - key_forward(const T &key) const + template + typename enable_if_c::value, const key_type &>::type + key_forward(const U &key) const { return KeyOfValue()(key); } template @@ -186,17 +187,17 @@ struct tree_node internal_type m_data; - template - void do_assign(const std::pair &p) + template + void do_assign(const std::pair &p) { - const_cast(m_data.first) = p.first; + const_cast(m_data.first) = p.first; m_data.second = p.second; } - template - void do_assign(const pair &p) + template + void do_assign(const pair &p) { - const_cast(m_data.first) = p.first; + const_cast(m_data.first) = p.first; m_data.second = p.second; } @@ -204,17 +205,17 @@ struct tree_node void do_assign(const V &v) { m_data = v; } - template - void do_move_assign(std::pair &p) + template + void do_move_assign(std::pair &p) { - const_cast(m_data.first) = ::boost::move(p.first); + const_cast(m_data.first) = ::boost::move(p.first); m_data.second = ::boost::move(p.second); } - template - void do_move_assign(pair &p) + template + void do_move_assign(pair &p) { - const_cast(m_data.first) = ::boost::move(p.first); + const_cast(m_data.first) = ::boost::move(p.first); m_data.second = ::boost::move(p.second); } @@ -317,16 +318,16 @@ struct intrusive_tree_dispatch >::type type; }; -template +template struct intrusive_tree_type { private: typedef typename boost::container:: - allocator_traits::value_type value_type; + allocator_traits::value_type value_type; typedef typename boost::container:: - allocator_traits::void_pointer void_pointer; + allocator_traits::void_pointer void_pointer; typedef typename boost::container:: - allocator_traits::size_type size_type; + allocator_traits::size_type size_type; typedef typename container_detail::tree_node < value_type, void_pointer , tree_type_value, OptimizeSize> node_type; @@ -429,7 +430,7 @@ class RecyclingCloner }; template -//where KeyValueCompare is tree_value_compare +//where KeyValueCompare is tree_value_compare struct key_node_compare : private KeyValueCompare { @@ -458,35 +459,33 @@ struct key_node_compare { return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); } }; -template class tree : protected container_detail::node_alloc_holder - < A + < Allocator , typename container_detail::intrusive_tree_type - < A, tree_value_compare //ValComp + < Allocator, tree_value_compare //ValComp , Options::tree_type, Options::optimize_size>::type > { typedef tree_value_compare - ValComp; + ValComp; typedef typename container_detail::intrusive_tree_type - < A, ValComp, Options::tree_type + < Allocator, ValComp, Options::tree_type , Options::optimize_size>::type Icont; typedef container_detail::node_alloc_holder - AllocHolder; + AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; - typedef tree < Key, Value, KeyOfValue - , KeyCompare, A, Options> ThisType; + typedef tree < Key, T, KeyOfValue + , Compare, Allocator, Options> ThisType; typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef typename AllocHolder::ValAlloc ValAlloc; typedef typename AllocHolder::Node Node; typedef typename Icont::iterator iiterator; typedef typename Icont::const_iterator iconst_iterator; typedef container_detail::allocator_destroyer Destroyer; - typedef typename AllocHolder::allocator_v1 allocator_v1; - typedef typename AllocHolder::allocator_v2 allocator_v2; typedef typename AllocHolder::alloc_version alloc_version; typedef intrusive_tree_proxy intrusive_tree_proxy_t; @@ -495,22 +494,22 @@ class tree public: typedef Key key_type; - typedef Value value_type; - typedef A allocator_type; - typedef KeyCompare key_compare; + typedef T value_type; + typedef Allocator allocator_type; + typedef Compare key_compare; typedef ValComp value_compare; typedef typename boost::container:: - allocator_traits::pointer pointer; + allocator_traits::pointer pointer; typedef typename boost::container:: - allocator_traits::const_pointer const_pointer; + allocator_traits::const_pointer const_pointer; typedef typename boost::container:: - allocator_traits::reference reference; + allocator_traits::reference reference; typedef typename boost::container:: - allocator_traits::const_reference const_reference; + allocator_traits::const_reference const_reference; typedef typename boost::container:: - allocator_traits::size_type size_type; + allocator_traits::size_type size_type; typedef typename boost::container:: - allocator_traits::difference_type difference_type; + allocator_traits::difference_type difference_type; typedef difference_type tree_difference_type; typedef pointer tree_pointer; typedef const_pointer tree_const_pointer; @@ -546,7 +545,7 @@ class tree #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) , typename container_detail::enable_if_c < container_detail::is_input_iterator::value - || container_detail::is_same::value + || container_detail::is_same::value >::type * = 0 #endif ) @@ -574,7 +573,7 @@ class tree #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) , typename container_detail::enable_if_c < !(container_detail::is_input_iterator::value - || container_detail::is_same::value) + || container_detail::is_same::value) >::type * = 0 #endif ) @@ -603,7 +602,7 @@ class tree #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) , typename container_detail::enable_if_c < container_detail::is_input_iterator::value - || container_detail::is_same::value + || container_detail::is_same::value >::type * = 0 #endif ) @@ -620,7 +619,7 @@ class tree #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) , typename container_detail::enable_if_c < !(container_detail::is_input_iterator::value - || container_detail::is_same::value) + || container_detail::is_same::value) >::type * = 0 #endif ) @@ -929,18 +928,18 @@ class tree public: - #ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - std::pair emplace_unique(Args&&... args) + std::pair emplace_unique(BOOST_FWD_REF(Args)... args) { return this->emplace_unique_impl(AllocHolder::create_node(boost::forward(args)...)); } template - 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)...)); } template - iterator emplace_equal(Args&&... args) + iterator emplace_equal(BOOST_FWD_REF(Args)... args) { NodePtr tmp(AllocHolder::create_node(boost::forward(args)...)); scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); @@ -950,7 +949,7 @@ class tree } template - 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)...)); scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); @@ -959,49 +958,41 @@ class tree return ret; } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - std::pair emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - return this->emplace_unique_impl \ - (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint_unique(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - return this->emplace_unique_hint_impl \ - (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); \ - iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \ - destroy_deallocator.release(); \ - return ret; \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint_equal(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); \ - iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \ - destroy_deallocator.release(); \ - return ret; \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_TREE_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + std::pair emplace_unique(BOOST_MOVE_UREF##N)\ + { return this->emplace_unique_impl(AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_equal(BOOST_MOVE_UREF##N)\ + {\ + NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\ + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc());\ + iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));\ + destroy_deallocator.release();\ + return ret;\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\ + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc());\ + iterator ret(this->icont().insert_equal(hint.get(), *tmp));\ + destroy_deallocator.release();\ + return ret;\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_TREE_EMPLACE_CODE) + #undef BOOST_CONTAINER_TREE_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) iterator insert_unique(const_iterator hint, const value_type& v) { @@ -1168,17 +1159,25 @@ class tree } //namespace container_detail { } //namespace container { -/* + +template +struct has_trivial_destructor_after_move; + //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template +template struct has_trivial_destructor_after_move - > + < + ::boost::container::container_detail::tree + + > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; -*/ + } //namespace boost { #include diff --git a/include/boost/container/detail/type_traits.hpp b/include/boost/container/detail/type_traits.hpp index 395e9f7..496562d 100644 --- a/include/boost/container/detail/type_traits.hpp +++ b/include/boost/container/detail/type_traits.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // (C) Copyright John Maddock 2000. -// (C) Copyright Ion Gaztanaga 2005-2013. +// (C) Copyright Ion Gaztanaga 2005-2015. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -8,10 +8,11 @@ // // See http://www.boost.org/libs/container for documentation. // -// The alignment_of implementation comes from John Maddock's boost::alignment_of code +// The alignment and Type traits implementation comes from +// John Maddock's TypeTraits library. // +// Some other tricks come from Howard Hinnant's papers and StackOverflow replies ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP @@ -19,219 +20,41 @@ # pragma once #endif -#include -#include +#include namespace boost { namespace container { namespace container_detail { -struct nat{}; +using ::boost::move_detail::is_same; +using ::boost::move_detail::is_pointer; +using ::boost::move_detail::add_reference; +using ::boost::move_detail::add_const; +using ::boost::move_detail::add_const_reference; +using ::boost::move_detail::remove_const; +using ::boost::move_detail::remove_reference; +using ::boost::move_detail::make_unsigned; +using ::boost::move_detail::is_floating_point; +using ::boost::move_detail::is_integral; +using ::boost::move_detail::is_enum; +using ::boost::move_detail::is_pod; +using ::boost::move_detail::is_trivially_destructible; +using ::boost::move_detail::is_trivially_default_constructible; +using ::boost::move_detail::is_trivially_copy_constructible; +using ::boost::move_detail::is_trivially_move_constructible; +using ::boost::move_detail::is_trivially_copy_assignable; +using ::boost::move_detail::is_trivially_move_assignable; +using ::boost::move_detail::is_nothrow_default_constructible; +using ::boost::move_detail::is_nothrow_copy_constructible; +using ::boost::move_detail::is_nothrow_move_constructible; +using ::boost::move_detail::is_nothrow_copy_assignable; +using ::boost::move_detail::is_nothrow_move_assignable; +using ::boost::move_detail::alignment_of; +using ::boost::move_detail::aligned_storage; +using ::boost::move_detail::nat; -template -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 struct alignment_of; - -template -struct alignment_of_hack -{ - char c; - T t; - alignment_of_hack(); -}; - -template -struct alignment_logic -{ - enum{ value = A < S ? A : S }; -}; - -template< typename T > -struct alignment_of -{ - enum{ value = alignment_logic - < sizeof(alignment_of_hack) - 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 -struct remove_reference -{ - typedef T type; -}; - -template -struct remove_reference -{ - typedef T type; -}; - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - -template -struct remove_reference -{ - typedef T type; -}; - -#else - -} // namespace container_detail { -} //namespace container { - -template -class rv; - -namespace container { -namespace container_detail { - -template -struct remove_reference< ::boost::rv > -{ - typedef T type; -}; - -#endif - -template -struct is_reference -{ - enum { value = false }; -}; - -template -struct is_reference -{ - enum { value = true }; -}; - -template -struct is_pointer -{ - enum { value = false }; -}; - -template -struct is_pointer -{ - enum { value = true }; -}; - -template -struct add_reference -{ - typedef T& type; -}; - -template -struct add_reference -{ - typedef T& type; -}; - -template<> -struct add_reference -{ - typedef nat &type; -}; - -template<> -struct add_reference -{ - typedef const nat &type; -}; - -template -struct add_const_reference -{ typedef const T &type; }; - -template -struct add_const_reference -{ typedef T& type; }; - -template -struct add_const -{ typedef const T type; }; - -template -struct is_same -{ - typedef char yes_type; - struct no_type - { - char padding[8]; - }; - - template - 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 -struct remove_const -{ - typedef T type; -}; - -template -struct remove_const< const T> -{ - typedef T type; -}; - -template -struct remove_ref_const -{ - typedef typename remove_const< typename remove_reference::type >::type type; -}; - -template -struct make_unsigned -{ - typedef T type; -}; - -template <> struct make_unsigned {}; -template <> struct make_unsigned {typedef unsigned char type;}; -template <> struct make_unsigned {typedef unsigned short type;}; -template <> struct make_unsigned {typedef unsigned int type;}; -template <> struct make_unsigned {typedef unsigned long type;}; -#ifdef BOOST_HAS_LONG_LONG -template <> struct make_unsigned< ::boost::long_long_type > {typedef ::boost::ulong_long_type type;}; -#endif - -} // namespace container_detail +} //namespace container_detail { } //namespace container { } //namespace boost { -#include - #endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP diff --git a/include/boost/container/detail/version_type.hpp b/include/boost/container/detail/version_type.hpp index 2eabc62..622ffe1 100644 --- a/include/boost/container/detail/version_type.hpp +++ b/include/boost/container/detail/version_type.hpp @@ -30,8 +30,6 @@ namespace boost{ namespace container { namespace container_detail { -//using namespace boost; - template struct version_type : public container_detail::integral_constant @@ -95,6 +93,11 @@ struct is_version }; } //namespace container_detail { + +typedef container_detail::integral_constant version_0; +typedef container_detail::integral_constant version_1; +typedef container_detail::integral_constant version_2; + } //namespace container { } //namespace boost{ diff --git a/include/boost/container/detail/workaround.hpp b/include/boost/container/detail/workaround.hpp index 55ebe33..e0caaf9 100644 --- a/include/boost/container/detail/workaround.hpp +++ b/include/boost/container/detail/workaround.hpp @@ -46,7 +46,7 @@ #endif //Macros for documentation purposes. For code, expands to the argument -#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE +#define BOOST_MOVE_IMPDEF(TYPE) TYPE #define BOOST_CONTAINER_SEEDOC(TYPE) TYPE //Macros for memset optimization. In most platforms @@ -63,7 +63,7 @@ #endif #define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2 -#define BOOST_CONTAINER_I , +#define BOOST_MOVE_I , #define BOOST_CONTAINER_DOCIGN(T) T #define BOOST_CONTAINER_DOCONLY(T) diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index 47ed3e2..ff61ed8 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -7,7 +7,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_FLAT_MAP_HPP #define BOOST_CONTAINER_FLAT_MAP_HPP @@ -17,23 +16,30 @@ #include #include - +// container +#include #include - +#include //new_allocator +#include +// container/detail #include -#include +#include #include #include //equal() -#include -#include +// move #include -#include #include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +// intrusive +#include //pair +#include //less, equal +//others #include -#include //pair -#include //less -#include //allocator #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -72,7 +78,7 @@ static D force_copy(S s) //! //! Compare is the ordering function for Keys (e.g. std::less). //! -//! A is the allocator to allocate the value_types +//! Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair >). //! //! flat_map is similar to std::map but it's implemented like an ordered vector. @@ -87,12 +93,12 @@ static D force_copy(S s) //! \tparam Key is the key_type of the map //! \tparam Value is the mapped_type //! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam A is the allocator to allocate the value_types +//! \tparam Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair > ). #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator< std::pair< Key, T> > > +template , class Allocator = new_allocator< std::pair< Key, T> > > #else -template +template #endif class flat_map { @@ -104,14 +110,14 @@ class flat_map std::pair, container_detail::select1st< std::pair >, Compare, - A> tree_t; + Allocator> tree_t; //This is the real tree stored here. It's based on a movable pair typedef container_detail::flat_tree, container_detail::select1st >, Compare, - typename allocator_traits::template portable_rebind_alloc + typename allocator_traits::template portable_rebind_alloc >::type> impl_tree_t; impl_tree_t m_flat_tree; // flat tree representing flat_map @@ -124,13 +130,13 @@ class flat_map , container_detail::select1st< std::pair > , std::pair > value_compare_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::iterator iterator_impl; + ::pointer>::iterator iterator_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::const_iterator const_iterator_impl; + ::pointer>::const_iterator const_iterator_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::reverse_iterator reverse_iterator_impl; + ::pointer>::reverse_iterator reverse_iterator_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::const_reverse_iterator const_reverse_iterator_impl; + ::pointer>::const_reverse_iterator const_reverse_iterator_impl; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -143,22 +149,22 @@ class flat_map typedef Key key_type; typedef T mapped_type; typedef std::pair value_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::const_pointer const_pointer; - typedef typename boost::container::allocator_traits::reference reference; - typedef typename boost::container::allocator_traits::const_reference const_reference; - typedef typename boost::container::allocator_traits::size_type size_type; - typedef typename boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(A) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_MOVE_IMPDEF(Allocator) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare; typedef Compare key_compare; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; + typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator; + typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_MOVE_IMPDEF(reverse_iterator_impl) reverse_iterator; + typedef BOOST_MOVE_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; + typedef BOOST_MOVE_IMPDEF(impl_value_type) movable_value_type; public: ////////////////////////////////////////////// @@ -174,7 +180,7 @@ class flat_map : m_flat_tree() { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_map using the specified @@ -185,7 +191,7 @@ class flat_map : m_flat_tree(comp, container_detail::force(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_map using the specified allocator. @@ -195,7 +201,7 @@ class flat_map : m_flat_tree(container_detail::force(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty 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(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_map using the specified comparison object and @@ -228,7 +234,7 @@ class flat_map : m_flat_tree(ordered_range, first, last, comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -242,7 +248,7 @@ class flat_map : m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_map using the specified comparison object and @@ -260,7 +266,7 @@ class flat_map : m_flat_tree(ordered_range, il.begin(), il.end(), comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } #endif @@ -271,7 +277,7 @@ class flat_map : m_flat_tree(x.m_flat_tree) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a flat_map. @@ -284,7 +290,7 @@ class flat_map : m_flat_tree(boost::move(x.m_flat_tree)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Copy constructs a flat_map using the specified allocator. @@ -294,7 +300,7 @@ class flat_map : m_flat_tree(x.m_flat_tree, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a flat_map using the specified allocator. @@ -305,7 +311,7 @@ class flat_map : m_flat_tree(boost::move(x.m_flat_tree), a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Makes *this a copy of x. @@ -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) //! Effects: Inserts an object x of type T constructed with //! std::forward(args)... if and only if there is no element in the container @@ -624,7 +630,7 @@ class flat_map //! //! Note: If an element is inserted it might invalidate elements. template - std::pair emplace(Args&&... args) + std::pair emplace(BOOST_FWD_REF(Args)... args) { return container_detail::force_copy< std::pair >(m_flat_tree.emplace_unique(boost::forward(args)...)); } //! Effects: Inserts an object of type T constructed with @@ -640,32 +646,34 @@ class flat_map //! //! Note: If an element is inserted it might invalidate elements. template - iterator emplace_hint(const_iterator hint, Args&&... args) + iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) { return container_detail::force_copy (m_flat_tree.emplace_hint_unique( container_detail::force_copy(hint) , boost::forward(args)...)); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy< std::pair > \ - (m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy(m_flat_tree.emplace_hint_unique \ - (container_detail::force_copy(hint) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + std::pair emplace(BOOST_MOVE_UREF##N)\ + {\ + return container_detail::force_copy< std::pair >\ + (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + return container_detail::force_copy(m_flat_tree.emplace_hint_unique\ + (container_detail::force_copy(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE) + #undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) //! Effects: Inserts x if and only if there is no element in the container //! with key equivalent to the key of x. @@ -679,7 +687,7 @@ class flat_map //! //! Note: If an element is inserted it might invalidate elements. std::pair insert(const value_type& x) - { return container_detail::force_copy >( + { return container_detail::force_copy >( m_flat_tree.insert_unique(container_detail::force(x))); } //! Effects: Inserts a new value_type move constructed from the pair if and @@ -1039,10 +1047,13 @@ class flat_map //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; namespace container { @@ -1061,7 +1072,7 @@ namespace container { //! //! Compare is the ordering function for Keys (e.g. std::less). //! -//! A is the allocator to allocate the value_types +//! Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair >). //! //! flat_multimap is similar to std::multimap but it's implemented like an ordered vector. @@ -1076,12 +1087,12 @@ namespace container { //! \tparam Key is the key_type of the map //! \tparam Value is the mapped_type //! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam A is the allocator to allocate the value_types +//! \tparam Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair > ). #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator< std::pair< Key, T> > > +template , class Allocator = new_allocator< std::pair< Key, T> > > #else -template +template #endif class flat_multimap { @@ -1092,13 +1103,13 @@ class flat_multimap std::pair, container_detail::select1st< std::pair >, Compare, - A> tree_t; + Allocator> tree_t; //This is the real tree stored here. It's based on a movable pair typedef container_detail::flat_tree, container_detail::select1st >, Compare, - typename allocator_traits::template portable_rebind_alloc + typename allocator_traits::template portable_rebind_alloc >::type> impl_tree_t; impl_tree_t m_flat_tree; // flat tree representing flat_map @@ -1111,13 +1122,13 @@ class flat_multimap , container_detail::select1st< std::pair > , std::pair > value_compare_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::iterator iterator_impl; + ::pointer>::iterator iterator_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::const_iterator const_iterator_impl; + ::pointer>::const_iterator const_iterator_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::reverse_iterator reverse_iterator_impl; + ::pointer>::reverse_iterator reverse_iterator_impl; typedef typename container_detail::get_flat_tree_iterators - ::pointer>::const_reverse_iterator const_reverse_iterator_impl; + ::pointer>::const_reverse_iterator const_reverse_iterator_impl; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -1130,22 +1141,22 @@ class flat_multimap typedef Key key_type; typedef T mapped_type; typedef std::pair value_type; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::const_pointer const_pointer; - typedef typename boost::container::allocator_traits::reference reference; - typedef typename boost::container::allocator_traits::const_reference const_reference; - typedef typename boost::container::allocator_traits::size_type size_type; - typedef typename boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(A) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_MOVE_IMPDEF(Allocator) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare; typedef Compare key_compare; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; + typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator; + typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_MOVE_IMPDEF(reverse_iterator_impl) reverse_iterator; + typedef BOOST_MOVE_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; + typedef BOOST_MOVE_IMPDEF(impl_value_type) movable_value_type; ////////////////////////////////////////////// // @@ -1160,7 +1171,7 @@ class flat_multimap : m_flat_tree() { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_multimap using the specified comparison @@ -1172,7 +1183,7 @@ class flat_multimap : m_flat_tree(comp, container_detail::force(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_multimap using the specified allocator. @@ -1182,7 +1193,7 @@ class flat_multimap : m_flat_tree(container_detail::force(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_multimap using the specified comparison object @@ -1197,7 +1208,7 @@ class flat_multimap : m_flat_tree(false, first, last, comp, container_detail::force(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_multimap using the specified comparison object and @@ -1216,7 +1227,7 @@ class flat_multimap : m_flat_tree(ordered_range, first, last, comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1229,7 +1240,7 @@ class flat_multimap : m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force(a)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty flat_multimap using the specified comparison object and @@ -1246,7 +1257,7 @@ class flat_multimap : m_flat_tree(ordered_range, il.begin(), il.end(), comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } #endif @@ -1257,7 +1268,7 @@ class flat_multimap : m_flat_tree(x.m_flat_tree) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a flat_multimap. Constructs *this using x's resources. @@ -1269,7 +1280,7 @@ class flat_multimap : m_flat_tree(boost::move(x.m_flat_tree)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Copy constructs a flat_multimap using the specified allocator. @@ -1279,7 +1290,7 @@ class flat_multimap : m_flat_tree(x.m_flat_tree, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a flat_multimap using the specified allocator. @@ -1290,7 +1301,7 @@ class flat_multimap : m_flat_tree(boost::move(x.m_flat_tree), a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Makes *this a copy of x. @@ -1529,7 +1540,7 @@ class flat_multimap size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT { return m_flat_tree.index_of(container_detail::force_copy(p)); } - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type T constructed with //! std::forward(args)... and returns the iterator pointing to the @@ -1540,7 +1551,7 @@ class flat_multimap //! //! Note: If an element is inserted it might invalidate elements. template - iterator emplace(Args&&... args) + iterator emplace(BOOST_FWD_REF(Args)... args) { return container_detail::force_copy(m_flat_tree.emplace_equal(boost::forward(args)...)); } //! Effects: Inserts an object of type T constructed with @@ -1556,31 +1567,30 @@ class flat_multimap //! //! Note: If an element is inserted it might invalidate elements. template - iterator emplace_hint(const_iterator hint, Args&&... args) + iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) { return container_detail::force_copy(m_flat_tree.emplace_hint_equal (container_detail::force_copy(hint), boost::forward(args)...)); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy(m_flat_tree.emplace_equal \ - (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator hint \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return container_detail::force_copy(m_flat_tree.emplace_hint_equal \ - (container_detail::force_copy(hint) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(BOOST_MOVE_UREF##N)\ + { return container_detail::force_copy(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + return container_detail::force_copy(m_flat_tree.emplace_hint_equal\ + (container_detail::force_copy(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE) + #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) //! Effects: Inserts x and returns the iterator pointing to the //! newly inserted element. @@ -1917,10 +1927,13 @@ namespace boost { //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move< boost::container::flat_multimap > +template +struct has_trivial_destructor_after_move< boost::container::flat_multimap > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; } //namespace boost { diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index 0e46cb9..ab7d4f4 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -7,7 +7,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_FLAT_SET_HPP #define BOOST_CONTAINER_FLAT_SET_HPP @@ -18,17 +17,25 @@ #include #include +// container +#include #include +#include //new_allocator +// container/detail #include #include -#include -#include -#include +// move #include - -#include //pair -#include //less -#include //allocator +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +// intrusive/detail +#include //pair +#include //less, equal +// std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -50,21 +57,21 @@ namespace container { //! //! \tparam Key is the type to be inserted in the set, which is also the key_type //! \tparam Compare is the comparison functor used to order keys -//! \tparam A is the allocator to be used to allocate memory for this container +//! \tparam Allocator is the allocator to be used to allocate memory for this container #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = new_allocator > #else -template +template #endif class flat_set ///@cond - : public container_detail::flat_tree, Compare, A> + : public container_detail::flat_tree, Compare, Allocator> ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_set) - typedef container_detail::flat_tree, Compare, A> base_t; + typedef container_detail::flat_tree, Compare, Allocator> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -77,19 +84,19 @@ class flat_set typedef Key value_type; typedef Compare key_compare; typedef Compare value_compare; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; public: ////////////////////////////////////////////// @@ -411,7 +418,7 @@ class flat_set // ////////////////////////////////////////////// - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object x of type Key constructed with //! std::forward(args)... if and only if there is no element in the container @@ -426,7 +433,7 @@ class flat_set //! //! Note: If an element is inserted it might invalidate elements. template - std::pair emplace(Args&&... args) + std::pair emplace(BOOST_FWD_REF(Args)... args) { return this->base_t::emplace_unique(boost::forward(args)...); } //! Effects: Inserts an object of type Key constructed with @@ -442,26 +449,24 @@ class flat_set //! //! Note: If an element is inserted it might invalidate elements. template - 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)...); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_hint_unique \ - (p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + std::pair emplace(BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE) + #undef BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts x if and only if there is no element in the container @@ -802,10 +807,13 @@ class flat_set //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value &&has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; namespace container { @@ -827,21 +835,21 @@ namespace container { //! //! \tparam Key is the type to be inserted in the multiset, which is also the key_type //! \tparam Compare is the comparison functor used to order keys -//! \tparam A is the allocator to be used to allocate memory for this container +//! \tparam Allocator is the allocator to be used to allocate memory for this container #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = new_allocator > #else -template +template #endif class flat_multiset ///@cond - : public container_detail::flat_tree, Compare, A> + : public container_detail::flat_tree, Compare, Allocator> ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_multiset) - typedef container_detail::flat_tree, Compare, A> base_t; + typedef container_detail::flat_tree, Compare, Allocator> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -854,19 +862,19 @@ class flat_multiset typedef Key value_type; typedef Compare key_compare; typedef Compare value_compare; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; //! @copydoc ::boost::container::flat_set::flat_set() explicit flat_multiset() @@ -1034,7 +1042,7 @@ class flat_multiset // ////////////////////////////////////////////// - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... and returns the iterator pointing to the @@ -1045,7 +1053,7 @@ class flat_multiset //! //! Note: If an element is inserted it might invalidate elements. template - iterator emplace(Args&&... args) + iterator emplace(BOOST_FWD_REF(Args)... args) { return this->base_t::emplace_equal(boost::forward(args)...); } //! Effects: Inserts an object of type Key constructed with @@ -1060,26 +1068,24 @@ class flat_multiset //! //! Note: If an element is inserted it might invalidate elements. template - 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)...); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_hint_equal \ - (p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE) + #undef BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts x and returns the iterator pointing to the @@ -1297,10 +1303,13 @@ class flat_multiset //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; namespace container { diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp index 83fe5a4..a2a8202 100644 --- a/include/boost/container/list.hpp +++ b/include/boost/container/list.hpp @@ -6,7 +6,7 @@ // // See http://www.boost.org/libs/container for documentation. // - +////////////////////////////////////////////////////////////////////////////// #ifndef BOOST_CONTAINER_LIST_HPP #define BOOST_CONTAINER_LIST_HPP @@ -16,32 +16,35 @@ #include #include + +// container #include -#include +#include //new_allocator +#include +// container/detail +#include +#include +#include #include #include -#include -#include -#include - +#include +#include +// move #include #include -#include #include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -#else -//Preprocessor library to emulate perfect forwarding -#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# include #endif +#include -#include //std::allocator +// intrusive +#include +#include +// other +#include +// std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -84,10 +87,10 @@ struct iiterator_node_value_type< list_node > { typedef T type; }; -template +template struct intrusive_list_type { - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef typename boost::intrusive::pointer_traits ::template @@ -120,30 +123,28 @@ struct intrusive_list_type //! or mutation is explicit. //! //! \tparam T The type of object that is stored in the list -//! \tparam A The allocator used for all internal memory management +//! \tparam Allocator The allocator used for all internal memory management #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif class list : protected container_detail::node_alloc_holder - ::type> + ::type> { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef typename - container_detail::intrusive_list_type::type Icont; - typedef container_detail::node_alloc_holder AllocHolder; + container_detail::intrusive_list_type::type Icont; + typedef container_detail::node_alloc_holder AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef typename AllocHolder::ValAlloc ValAlloc; typedef typename AllocHolder::Node Node; typedef container_detail::allocator_destroyer Destroyer; - typedef typename AllocHolder::allocator_v1 allocator_v1; - typedef typename AllocHolder::allocator_v2 allocator_v2; typedef typename AllocHolder::alloc_version alloc_version; - typedef boost::container::allocator_traits allocator_traits_type; - typedef boost::container::equal_to_value equal_to_value_type; + typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::equal_to_value equal_to_value_type; BOOST_COPYABLE_AND_MOVABLE(list) @@ -159,18 +160,18 @@ class list ////////////////////////////////////////////// typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_MOVE_IMPDEF(NodeAlloc) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator; + typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; ////////////////////////////////////////////// // @@ -204,7 +205,7 @@ class list //! //! Complexity: Linear to n. explicit list(size_type n) - : AllocHolder(A()) + : AllocHolder(Allocator()) { this->resize(n); } //! Effects: Constructs a list that will use a copy of allocator a @@ -214,7 +215,7 @@ class list //! throws or T's default or copy constructor throws. //! //! Complexity: Linear to n. - list(size_type n, const T& value, const A& a = A()) + list(size_type n, const T& value, const Allocator& a = Allocator()) : AllocHolder(a) { this->insert(this->cbegin(), n, value); } @@ -274,7 +275,7 @@ class list //! //! Complexity: Linear to the range [first, last). template - list(InpIt first, InpIt last, const A &a = A()) + list(InpIt first, InpIt last, const Allocator &a = Allocator()) : AllocHolder(a) { this->insert(this->cbegin(), first, last); } @@ -288,7 +289,7 @@ class list //! std::initializer_list iterator throws. //! //! Complexity: Linear to the range [il.begin(), il.end()). - list(std::initializer_list il, const A &a = A()) + list(std::initializer_list il, const Allocator &a = Allocator()) : AllocHolder(a) { this->insert(this->cbegin(), il.begin(), il.end()); } #endif @@ -677,7 +678,7 @@ class list // ////////////////////////////////////////////// - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the end of the list. @@ -687,7 +688,7 @@ class list //! //! Complexity: Constant template - void emplace_back(Args&&... args) + void emplace_back(BOOST_FWD_REF(Args)... args) { this->emplace(this->cend(), boost::forward(args)...); } //! Effects: Inserts an object of type T constructed with @@ -698,7 +699,7 @@ class list //! //! Complexity: Constant template - void emplace_front(Args&&... args) + void emplace_front(BOOST_FWD_REF(Args)... args) { this->emplace(this->cbegin(), boost::forward(args)...); } //! Effects: Inserts an object of type T constructed with @@ -709,42 +710,34 @@ class list //! //! Complexity: Constant template - 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)...)); return iterator(this->icont().insert(p.get(), *pnode)); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - this->emplace(this->cend() \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - this->emplace(this->cbegin() \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - NodePtr pnode (AllocHolder::create_node \ - (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - return iterator(this->icont().insert(p.get(), *pnode)); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + void emplace_back(BOOST_MOVE_UREF##N)\ + { this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + void emplace_front(BOOST_MOVE_UREF##N)\ + { this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\ + return iterator(this->icont().insert(p.get(), *pnode));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE) + #undef BOOST_CONTAINER_LIST_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts a copy of x at the beginning of the list. @@ -843,7 +836,7 @@ class list , typename container_detail::enable_if_c < !container_detail::is_convertible::value && (container_detail::is_input_iterator::value - || container_detail::is_same::value + || container_detail::is_same::value ) >::type * = 0 #endif @@ -867,7 +860,7 @@ class list , typename container_detail::enable_if_c < !container_detail::is_convertible::value && !(container_detail::is_input_iterator::value - || container_detail::is_same::value + || container_detail::is_same::value ) >::type * = 0 ) @@ -1403,10 +1396,13 @@ class list //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > - : public ::boost::has_trivial_destructor_after_move -{}; +template +struct has_trivial_destructor_after_move > +{ + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; namespace container { diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index 50ce6ab..e730f73 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -7,7 +7,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #ifndef BOOST_CONTAINER_MAP_HPP #define BOOST_CONTAINER_MAP_HPP @@ -18,25 +17,31 @@ #include #include +// container #include -#include -#include -#include -#include -#include -#include -#include +#include //new_allocator #include -#include -#include -#include -#include +// container/detail +#include +#include +#include #include +#include +// move +#include +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +// intrusive/detail +#include //pair +#include //less, equal +// other +#include #include - -#include //pair -#include //less -#include //allocator +// std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -55,22 +60,22 @@ namespace container { //! by this container is the value_type is std::pair. //! //! \tparam Key is the key_type of the map -//! \tparam Value is the mapped_type +//! \tparam T is the mapped_type //! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam A is the allocator to allocate the value_types +//! \tparam Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair > ). //! \tparam MapOptions is an packed option type generated using using boost::container::tree_assoc_options. template < class Key, class T, class Compare = std::less - , class A = std::allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults > + , class Allocator = new_allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults > #else -template +template #endif class map ///@cond : public container_detail::tree < Key, std::pair , container_detail::select1st< std::pair > - , Compare, A, MapOptions> + , Compare, Allocator, MapOptions> ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -79,7 +84,7 @@ class map typedef std::pair value_type_impl; typedef container_detail::tree - , Compare, A, MapOptions> base_t; + , Compare, Allocator, MapOptions> base_t; typedef container_detail::pair movable_value_type_impl; typedef container_detail::tree_value_compare < Key, value_type_impl, Compare, container_detail::select1st @@ -94,25 +99,25 @@ class map ////////////////////////////////////////////// typedef Key key_type; - typedef ::boost::container::allocator_traits allocator_traits_type; + typedef ::boost::container::allocator_traits allocator_traits_type; typedef T mapped_type; typedef std::pair value_type; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::const_pointer const_pointer; - typedef typename boost::container::allocator_traits::reference reference; - typedef typename boost::container::allocator_traits::const_reference const_reference; - typedef typename boost::container::allocator_traits::size_type size_type; - typedef typename boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare; typedef Compare key_compare; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; typedef std::pair nonconst_value_type; - typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; + typedef BOOST_MOVE_IMPDEF(movable_value_type_impl) movable_value_type; ////////////////////////////////////////////// // @@ -127,7 +132,7 @@ class map : base_t() { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty map using the specified comparison object @@ -139,7 +144,7 @@ class map : base_t(comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty map using the specified allocator. @@ -149,7 +154,7 @@ class map : base_t(a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty map using the specified comparison object and @@ -163,7 +168,7 @@ class map : base_t(true, first, last, comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty map using the specified comparison object and @@ -182,7 +187,7 @@ class map : base_t(ordered_range, first, last, comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -195,7 +200,7 @@ class map : base_t(true, il.begin(), il.end(), comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } map(ordered_unique_range_t, std::initializer_list il, const Compare& comp = Compare(), @@ -203,7 +208,7 @@ class map : base_t(ordered_range, il.begin(), il.end(), comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } #endif @@ -214,7 +219,7 @@ class map : base_t(static_cast(x)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a map. Constructs *this using x's resources. @@ -226,7 +231,7 @@ class map : base_t(BOOST_MOVE_BASE(base_t, x)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Copy constructs a map using the specified allocator. @@ -236,7 +241,7 @@ class map : base_t(static_cast(x), a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a map using the specified allocator. @@ -249,7 +254,7 @@ class map : base_t(BOOST_MOVE_BASE(base_t, x), a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Makes *this a copy of x. @@ -598,7 +603,7 @@ class map { this->base_t::insert_unique(il.begin(), il.end()); } #endif - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object x of type T constructed with //! std::forward(args)... in the container if and only if there is @@ -612,7 +617,7 @@ class map //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. template - std::pair emplace(Args&&... args) + std::pair emplace(BOOST_FWD_REF(Args)... args) { return this->base_t::emplace_unique(boost::forward(args)...); } //! Effects: Inserts an object of type T constructed with @@ -626,26 +631,24 @@ class map //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. template - 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)...); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_hint_unique(p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + std::pair emplace(BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE) + #undef BOOST_CONTAINER_MAP_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -835,10 +838,13 @@ class map //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; namespace container { @@ -859,20 +865,20 @@ namespace container { //! \tparam Key is the key_type of the map //! \tparam Value is the mapped_type //! \tparam Compare is the ordering function for Keys (e.g. std::less). -//! \tparam A is the allocator to allocate the value_types +//! \tparam Allocator is the allocator to allocate the value_types //! (e.g. allocator< std::pair > ). //! \tparam MultiMapOptions is an packed option type generated using using boost::container::tree_assoc_options. template < class Key, class T, class Compare = std::less - , class A = std::allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults> + , class Allocator = new_allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults> #else -template +template #endif class multimap ///@cond : public container_detail::tree < Key, std::pair , container_detail::select1st< std::pair > - , Compare, A, MultiMapOptions> + , Compare, Allocator, MultiMapOptions> ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -881,7 +887,7 @@ class multimap typedef std::pair value_type_impl; typedef container_detail::tree - , Compare, A, MultiMapOptions> base_t; + , Compare, Allocator, MultiMapOptions> base_t; typedef container_detail::pair movable_value_type_impl; typedef container_detail::tree_value_compare < Key, value_type_impl, Compare, container_detail::select1st @@ -898,22 +904,22 @@ class multimap typedef Key key_type; typedef T mapped_type; typedef std::pair value_type; - typedef typename boost::container::allocator_traits::pointer pointer; - typedef typename boost::container::allocator_traits::const_pointer const_pointer; - typedef typename boost::container::allocator_traits::reference reference; - typedef typename boost::container::allocator_traits::const_reference const_reference; - typedef typename boost::container::allocator_traits::size_type size_type; - typedef typename boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::const_pointer const_pointer; + typedef typename boost::container::allocator_traits::reference reference; + typedef typename boost::container::allocator_traits::const_reference const_reference; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(value_compare_impl) value_compare; typedef Compare key_compare; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; typedef std::pair nonconst_value_type; - typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; + typedef BOOST_MOVE_IMPDEF(movable_value_type_impl) movable_value_type; ////////////////////////////////////////////// // @@ -928,7 +934,7 @@ class multimap : base_t() { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty multimap using the specified allocator. @@ -938,7 +944,7 @@ class multimap : base_t(comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty multimap using the specified comparison @@ -949,7 +955,7 @@ class multimap : base_t(a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty multimap using the specified comparison object @@ -964,7 +970,7 @@ class multimap : base_t(false, first, last, comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Constructs an empty multimap using the specified comparison object and @@ -993,7 +999,7 @@ class multimap : base_t(false, il.begin(), il.end(), comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } multimap(ordered_range_t, std::initializer_list il, const Compare& comp = Compare(), @@ -1001,7 +1007,7 @@ class multimap : base_t(ordered_range, il.begin(), il.end(), comp, a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } #endif @@ -1012,7 +1018,7 @@ class multimap : base_t(static_cast(x)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a multimap. Constructs *this using x's resources. @@ -1024,7 +1030,7 @@ class multimap : base_t(BOOST_MOVE_BASE(base_t, x)) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Copy constructs a multimap. @@ -1034,7 +1040,7 @@ class multimap : base_t(static_cast(x), a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Move constructs a multimap using the specified allocator. @@ -1046,7 +1052,7 @@ class multimap : base_t(BOOST_MOVE_BASE(base_t, x), a) { //A type must be std::pair - BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value)); + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } //! Effects: Makes *this a copy of x. @@ -1130,7 +1136,7 @@ class multimap #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the container. @@ -1142,7 +1148,7 @@ class multimap //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. template - iterator emplace(Args&&... args) + iterator emplace(BOOST_FWD_REF(Args)... args) { return this->base_t::emplace_equal(boost::forward(args)...); } //! Effects: Inserts an object of type T constructed with @@ -1155,26 +1161,24 @@ class multimap //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. template - 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)...); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_hint_equal(p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE) + #undef BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) //! Effects: Inserts x and returns the iterator pointing to the //! newly inserted element. @@ -1388,10 +1392,13 @@ class multimap //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; namespace container { diff --git a/include/boost/container/new_allocator.hpp b/include/boost/container/new_allocator.hpp new file mode 100644 index 0000000..747b6f3 --- /dev/null +++ b/include/boost/container/new_allocator.hpp @@ -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 +#include +#include +#include + +//!\file + +namespace boost { +namespace container { + +template +struct new_allocator_bool +{ static const bool value = Value; }; + +template +class new_allocator; + +template<> +class new_allocator +{ + public: + typedef void value_type; + typedef void * pointer; + typedef const void* const_pointer; + typedef new_allocator_bool propagate_on_container_move_assignment; + // reference-to-void members are impossible + + //!Obtains an new_allocator that allocates + //!objects of type T2 + template + 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 + new_allocator(const new_allocator &) 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 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 propagate_on_container_move_assignment; + + //!Obtains an new_allocator that allocates + //!objects of type T2 + template + struct rebind + { + typedef new_allocator 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 + new_allocator(const new_allocator &) 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(::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 + +#endif //BOOST_CONTAINER_ALLOCATOR_HPP diff --git a/include/boost/container/node_allocator.hpp b/include/boost/container/node_allocator.hpp index 691334e..f28b6de 100644 --- a/include/boost/container/node_allocator.hpp +++ b/include/boost/container/node_allocator.hpp @@ -26,9 +26,7 @@ #include #include -#include #include -#include #include namespace boost { @@ -145,7 +143,7 @@ class node_allocator //!Throws std::bad_alloc if there is no enough memory pointer allocate(size_type count, const void * = 0) { - if(count > this->max_size()) + if(BOOST_UNLIKELY(count > this->max_size())) boost::container::throw_bad_alloc(); if(Version == 1 && count == 1){ @@ -156,7 +154,7 @@ class node_allocator } else{ void *ret = boost_cont_malloc(count*sizeof(T)); - if(!ret) + if(BOOST_UNLIKELY(!ret)) boost::container::throw_bad_alloc(); return static_cast(ret); } @@ -187,16 +185,12 @@ class node_allocator singleton_t::instance().deallocate_free_blocks(); } - std::pair - allocation_command(allocation_type command, - size_type limit_size, - size_type preferred_size, - size_type &received_size, pointer reuse = pointer()) + pointer allocation_command + (allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) { BOOST_STATIC_ASSERT(( Version > 1 )); - std::pair ret = - priv_allocation_command(command, limit_size, preferred_size, received_size, reuse); - if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)) + pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); + if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))) boost::container::throw_bad_alloc(); return ret; } @@ -263,7 +257,7 @@ class node_allocator BOOST_STATIC_ASSERT(( Version > 1 )); boost_cont_memchain ch; BOOST_CONTAINER_MEMCHAIN_INIT(&ch); - if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){ + if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){ boost::container::throw_bad_alloc(); } chain.incorporate_after( chain.before_begin() @@ -279,7 +273,7 @@ class node_allocator BOOST_STATIC_ASSERT(( Version > 1 )); boost_cont_memchain ch; boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch); - if(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch)){ + if(BOOST_UNLIKELY(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch))){ boost::container::throw_bad_alloc(); } chain.incorporate_after( chain.before_begin() @@ -315,23 +309,26 @@ class node_allocator { return false; } private: - std::pair priv_allocation_command + pointer priv_allocation_command (allocation_type command, std::size_t limit_size - ,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr) + ,size_type &prefer_in_recvd_out_size + ,pointer &reuse) { + std::size_t const preferred_size = prefer_in_recvd_out_size; boost_cont_command_ret_t ret = {0 , 0}; - if(limit_size > this->max_size() || preferred_size > this->max_size()){ - //ret.first = 0; - return std::pair(pointer(), false); + if((limit_size > this->max_size()) | (preferred_size > this->max_size())){ + return pointer(); } std::size_t l_size = limit_size*sizeof(T); std::size_t p_size = preferred_size*sizeof(T); std::size_t r_size; { - ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr); + void* reuse_ptr_void = reuse; + ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void); + reuse = static_cast(reuse_ptr_void); } - received_size = r_size/sizeof(T); - return std::pair(static_cast(ret.first), !!ret.second); + prefer_in_recvd_out_size = r_size/sizeof(T); + return (pointer)ret.first; } }; diff --git a/include/boost/container/scoped_allocator.hpp b/include/boost/container/scoped_allocator.hpp index df3bcd3..f633804 100644 --- a/include/boost/container/scoped_allocator.hpp +++ b/include/boost/container/scoped_allocator.hpp @@ -23,35 +23,41 @@ #include #include -#include -#include + #include -#include -#include -#include +#include + +#include +#include #include -#include -#include +#include + #include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include + +#include namespace boost { namespace container { -//! Remark: if a specialization is derived from true_type, indicates that T may be constructed +//! Remark: if a specialization constructible_with_allocator_suffix::value is true, indicates that T may be constructed //! with an allocator as its last constructor argument. Ideally, all constructors of T (including the //! copy and move constructors) should have a variant that accepts a final argument of //! allocator_type. //! -//! Requires: if a specialization is derived from true_type, T must have a nested type, +//! Requires: if a specialization constructible_with_allocator_suffix::value is true, T must have a nested type, //! allocator_type and at least one constructor for which allocator_type is the last //! parameter. If not all constructors of T can be called with a final allocator_type argument, //! and if T is used in a context where a container must call such a constructor, then the program is //! ill-formed. //! //! -//! template > +//! template > //! class Z { //! public: -//! typedef A allocator_type; +//! typedef Allocator allocator_type; //! //! // Default constructor with optional allocator suffix //! Z(const allocator_type& a = allocator_type()); @@ -62,9 +68,9 @@ namespace boost { namespace container { //! }; //! //! // Specialize trait for class template Z -//! template > -//! struct constructible_with_allocator_suffix > -//! : ::boost::true_type { }; +//! template > +//! struct constructible_with_allocator_suffix > +//! { static const bool value = true; }; //! //! //! Note: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)" @@ -77,25 +83,24 @@ namespace boost { namespace container { //! to detect if a type should be constructed with suffix or prefix allocator arguments. template struct constructible_with_allocator_suffix - : ::boost::false_type -{}; +{ static const bool value = false; }; -//! Remark: if a specialization is derived from true_type, indicates that T may be constructed +//! Remark: if a specialization constructible_with_allocator_prefix::value is true, indicates that T may be constructed //! with allocator_arg and T::allocator_type as its first two constructor arguments. //! Ideally, all constructors of T (including the copy and move constructors) should have a variant //! that accepts these two initial arguments. //! -//! Requires: if a specialization is derived from true_type, T must have a nested type, +//! Requires: specialization constructible_with_allocator_prefix::value is true, T must have a nested type, //! allocator_type and at least one constructor for which allocator_arg_t is the first //! parameter and allocator_type is the second parameter. If not all constructors of T can be //! called with these initial arguments, and if T is used in a context where a container must call such //! a constructor, then the program is ill-formed. //! //! -//! template > +//! template > //! class Y { //! public: -//! typedef A allocator_type; +//! typedef Allocator allocator_type; //! //! // Default constructor with and allocator-extended default constructor //! Y(); @@ -108,13 +113,13 @@ struct constructible_with_allocator_suffix //! // Variadic constructor and allocator-extended variadic constructor //! template Y(Args&& args...); //! template -//! Y(allocator_arg_t, const allocator_type& a, Args&&... args); +//! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args); //! }; //! //! // Specialize trait for class template Y -//! template > -//! struct constructible_with_allocator_prefix > -//! : ::boost::true_type { }; +//! template > +//! struct constructible_with_allocator_prefix > +//! { static const bool value = true; }; //! //! //! @@ -128,34 +133,34 @@ struct constructible_with_allocator_suffix //! to detect if a type should be constructed with suffix or prefix allocator arguments. template struct constructible_with_allocator_prefix - : ::boost::false_type -{}; +{ static const bool value = false; }; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace container_detail { -template +template struct uses_allocator_imp { // Use SFINAE (Substitution Failure Is Not An Error) to detect the - // presence of an 'allocator_type' nested type convertilble from Alloc. - + // presence of an 'allocator_type' nested type convertilble from Allocator. private: + typedef char yes_type; + struct no_type{ char dummy[2]; }; + // Match this function if TypeT::allocator_type exists and is - // implicitly convertible from Alloc - template - static char test(int, typename U::allocator_type); + // implicitly convertible from Allocator + template + static yes_type test(typename U::allocator_type); // Match this function if TypeT::allocator_type does not exist or is - // not convertible from Alloc. + // not convertible from Allocator. template - static int test(LowPriorityConversion, LowPriorityConversion); - - static Alloc alloc; // Declared but not defined + static no_type test(...); + static Allocator alloc; // Declared but not defined public: - enum { value = sizeof(test(0, alloc)) == sizeof(char) }; + static const bool value = sizeof(test(alloc)) == sizeof(yes_type); }; } //namespace container_detail { @@ -163,31 +168,34 @@ struct uses_allocator_imp #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! Remark: Automatically detects if T has a nested allocator_type that is convertible from -//! Alloc. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may -//! specialize this type to derive from true_type for a T of user-defined type if T does not -//! have a nested allocator_type but is nonetheless constructible using the specified Alloc. +//! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may +//! specialize this type to define uses_allocator::value as true for a T of user-defined type if T does not +//! have a nested allocator_type but is nonetheless constructible using the specified Allocator. //! -//! Result: derived from true_type if Convertible and -//! derived from false_type otherwise. -template +//! Result: uses_allocator::value== true if Convertible, +//! false otherwise. +template struct uses_allocator - : boost::integral_constant::value> + : container_detail::uses_allocator_imp {}; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace container_detail { -template +template struct is_scoped_allocator_imp { - template - static char test(int, typename T::outer_allocator_type*); + typedef char yes_type; + struct no_type{ char dummy[2]; }; template - static int test(LowPriorityConversion, void*); + static yes_type test(typename T::outer_allocator_type*); - static const bool value = (sizeof(char) == sizeof(test(0, 0))); + template + static int test(...); + + static const bool value = (sizeof(yes_type) == sizeof(test(0))); }; template::value > @@ -230,38 +238,36 @@ struct outermost_allocator_imp } //namespace container_detail { -template +template struct is_scoped_allocator - : boost::integral_constant::value> + : container_detail::is_scoped_allocator_imp {}; -template +template struct outermost_allocator - : container_detail::outermost_allocator_imp + : container_detail::outermost_allocator_imp {}; -template -typename container_detail::outermost_allocator_imp::type & - get_outermost_allocator(Alloc &a) -{ return container_detail::outermost_allocator_imp::get(a); } +template +typename container_detail::outermost_allocator_imp::type & + get_outermost_allocator(Allocator &a) +{ return container_detail::outermost_allocator_imp::get(a); } -template -const typename container_detail::outermost_allocator_imp::type & - get_outermost_allocator(const Alloc &a) -{ return container_detail::outermost_allocator_imp::get(a); } +template +const typename container_detail::outermost_allocator_imp::type & + get_outermost_allocator(const Allocator &a) +{ return container_detail::outermost_allocator_imp::get(a); } namespace container_detail { // Check if we can detect is_convertible using advanced SFINAE expressions -#if !defined(BOOST_NO_SFINAE_EXPR) +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) //! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list //! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html //! Thanks Mathias! //With variadic templates, we need a single class to implement the trait - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template struct is_constructible_impl { @@ -273,7 +279,7 @@ namespace container_detail { struct dummy; template - static yes_type test(dummy()...))>*); + static decltype(X(boost::move_detail::declval()...), true_type()) test(int); template static no_type test(...); @@ -283,7 +289,7 @@ namespace container_detail { template struct is_constructible - : boost::integral_constant::value> + : is_constructible_impl {}; template @@ -291,101 +297,7 @@ namespace container_detail { : is_constructible {}; - #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - //Without variadic templates, we need to use the preprocessor to generate - //some specializations. - - #define BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS \ - BOOST_PP_ADD(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, 3) - //! - - //Generate N+1 template parameters so that we can specialize N - template - struct is_constructible_impl; - - //Generate N specializations, from 0 to - //BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS parameters - #define BOOST_PP_LOCAL_MACRO(n) \ - template \ - struct is_constructible_impl \ - \ - { \ - typedef char yes_type; \ - struct no_type \ - { char padding[2]; }; \ - \ - template \ - struct dummy; \ - \ - template \ - static yes_type test(dummy*); \ - \ - template \ - static no_type test(...); \ - \ - static const bool value = sizeof(test(0)) == sizeof(yes_type); \ - }; \ - //! - - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() - - //Finally just inherit from the implementation to define he trait - template< class T - BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > - struct is_constructible - : boost::integral_constant - < bool - , is_constructible_impl - < T - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, P) - , void>::value - > - {}; - - //Finally just inherit from the implementation to define he trait - template - struct is_constructible_with_allocator_prefix - : is_constructible - < T, allocator_arg_t, InnerAlloc - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 2), P) - > - {}; -/* - template - struct is_constructible_with_allocator_suffix - : is_constructible - < T - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 1), P) - , InnerAlloc - > - {};*/ - - #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -#else // #if !defined(BOOST_NO_SFINAE_EXPR) +#else // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) //Without advanced SFINAE expressions, we can't use is_constructible //so backup to constructible_with_allocator_xxx @@ -396,33 +308,23 @@ namespace container_detail { struct is_constructible_with_allocator_prefix : constructible_with_allocator_prefix {}; -/* + template < class T, class InnerAlloc, class ...Args> struct is_constructible_with_allocator_suffix : constructible_with_allocator_suffix - {};*/ + {}; #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template < class T - , class InnerAlloc - BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > + template < class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9> struct is_constructible_with_allocator_prefix : constructible_with_allocator_prefix {}; -/* - template < class T - , class InnerAlloc - BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > + + template < class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9> struct is_constructible_with_allocator_suffix : constructible_with_allocator_suffix - {};*/ + {}; #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -436,7 +338,7 @@ template < typename OutermostAlloc , class ...Args > inline void dispatch_allocator_prefix_suffix - ( boost::true_type use_alloc_prefix, OutermostAlloc& outermost_alloc + ( true_type use_alloc_prefix, OutermostAlloc& outermost_alloc , InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args) ...args) { (void)use_alloc_prefix; @@ -450,7 +352,7 @@ template < typename OutermostAlloc , class ...Args > inline void dispatch_allocator_prefix_suffix - ( boost::false_type use_alloc_prefix, OutermostAlloc& outermost_alloc + ( false_type use_alloc_prefix, OutermostAlloc& outermost_alloc , InnerAlloc &inner_alloc, T* p, BOOST_FWD_REF(Args)...args) { (void)use_alloc_prefix; @@ -464,14 +366,14 @@ template < typename OutermostAlloc , class ...Args > inline void dispatch_uses_allocator - ( boost::true_type uses_allocator, OutermostAlloc& outermost_alloc + ( true_type uses_allocator, OutermostAlloc& outermost_alloc , InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args)...args) { (void)uses_allocator; //BOOST_STATIC_ASSERT((is_constructible_with_allocator_prefix::value || // is_constructible_with_allocator_suffix::value )); dispatch_allocator_prefix_suffix - ( is_constructible_with_allocator_prefix() + ( bool_::value >() , outermost_alloc, inner_alloc, p, ::boost::forward(args)...); } @@ -481,7 +383,7 @@ template < typename OutermostAlloc , class ...Args > inline void dispatch_uses_allocator - ( boost::false_type uses_allocator, OutermostAlloc & outermost_alloc + ( false_type uses_allocator, OutermostAlloc & outermost_alloc , InnerAlloc & inner_alloc ,T* p, BOOST_FWD_REF(Args)...args) { @@ -492,78 +394,54 @@ inline void dispatch_uses_allocator #else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#define BOOST_PP_LOCAL_MACRO(n) \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_allocator_prefix_suffix( \ - boost::true_type use_alloc_prefix, \ - OutermostAlloc& outermost_alloc, \ - InnerAlloc& inner_alloc, \ - T* p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)use_alloc_prefix, \ - allocator_traits::construct \ - (outermost_alloc, p, allocator_arg, inner_alloc \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ -} \ - \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_allocator_prefix_suffix( \ - boost::false_type use_alloc_prefix, \ - OutermostAlloc& outermost_alloc, \ - InnerAlloc& inner_alloc, \ - T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)use_alloc_prefix; \ - allocator_traits::construct \ - (outermost_alloc, p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \ - , inner_alloc); \ -} \ - \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_uses_allocator(boost::true_type uses_allocator, \ - OutermostAlloc& outermost_alloc, \ - InnerAlloc& inner_alloc, \ - T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)uses_allocator; \ - dispatch_allocator_prefix_suffix \ - (is_constructible_with_allocator_prefix \ - < T, InnerAlloc BOOST_PP_ENUM_TRAILING_PARAMS(n, P)>() \ - , outermost_alloc, inner_alloc, p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ -} \ - \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_uses_allocator(boost::false_type uses_allocator \ - ,OutermostAlloc & outermost_alloc \ - ,InnerAlloc & inner_alloc \ - ,T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)uses_allocator; (void)inner_alloc; \ - allocator_traits::construct \ - (outermost_alloc, p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ -} \ -//! -#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) -#include BOOST_PP_LOCAL_ITERATE() +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ +inline void dispatch_allocator_prefix_suffix\ + (true_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\ + InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)use_alloc_prefix,\ + allocator_traits::construct\ + (outermost_alloc, p, allocator_arg, inner_alloc BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ +}\ +\ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +inline void dispatch_allocator_prefix_suffix\ + (false_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\ + InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)use_alloc_prefix;\ + allocator_traits::construct\ + (outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, inner_alloc);\ +}\ +\ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +inline void dispatch_uses_allocator\ + (true_type uses_allocator, OutermostAlloc& outermost_alloc,\ + InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)uses_allocator;\ + dispatch_allocator_prefix_suffix\ + (bool_< is_constructible_with_allocator_prefix\ + < T, InnerAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::value>()\ + , outermost_alloc, inner_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ +}\ +\ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +inline void dispatch_uses_allocator\ + (false_type uses_allocator, OutermostAlloc &outermost_alloc,\ + InnerAlloc &inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)uses_allocator; (void)inner_alloc;\ + allocator_traits::construct(outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ +}\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -588,18 +466,15 @@ class scoped_allocator_adaptor_base typedef allocator_traits inner_traits_type; typedef scoped_allocator_adaptor scoped_allocator_type; - typedef boost::integral_constant< - bool, + typedef container_detail::bool_< outer_traits_type::propagate_on_container_copy_assignment::value || inner_allocator_type::propagate_on_container_copy_assignment::value > propagate_on_container_copy_assignment; - typedef boost::integral_constant< - bool, + typedef container_detail::bool_< outer_traits_type::propagate_on_container_move_assignment::value || inner_allocator_type::propagate_on_container_move_assignment::value > propagate_on_container_move_assignment; - typedef boost::integral_constant< - bool, + typedef container_detail::bool_< outer_traits_type::propagate_on_container_swap::value || inner_allocator_type::propagate_on_container_swap::value > propagate_on_container_swap; @@ -705,186 +580,152 @@ class scoped_allocator_adaptor_base //Let's add a dummy first template parameter to allow creating //specializations up to maximum InnerAlloc count -template < - typename OuterAlloc - , bool Dummy - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q) - > +template class scoped_allocator_adaptor_base; //Specializations for the adaptor with InnerAlloc allocators -#define BOOST_PP_LOCAL_MACRO(n) \ -template \ -class scoped_allocator_adaptor_base \ - : public OuterAlloc \ -{ \ - typedef allocator_traits outer_traits_type; \ - BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) \ - \ - public: \ - template \ - struct rebind_base \ - { \ - typedef scoped_allocator_adaptor_base other; \ - }; \ - \ - typedef OuterAlloc outer_allocator_type; \ - typedef scoped_allocator_adaptor inner_allocator_type; \ - typedef scoped_allocator_adaptor scoped_allocator_type; \ - typedef allocator_traits inner_traits_type; \ - typedef boost::integral_constant< \ - bool, \ - outer_traits_type::propagate_on_container_copy_assignment::value || \ - inner_allocator_type::propagate_on_container_copy_assignment::value \ - > propagate_on_container_copy_assignment; \ - typedef boost::integral_constant< \ - bool, \ - outer_traits_type::propagate_on_container_move_assignment::value || \ - inner_allocator_type::propagate_on_container_move_assignment::value \ - > propagate_on_container_move_assignment; \ - typedef boost::integral_constant< \ - bool, \ - outer_traits_type::propagate_on_container_swap::value || \ - inner_allocator_type::propagate_on_container_swap::value \ - > propagate_on_container_swap; \ - \ - scoped_allocator_adaptor_base() \ - {} \ - \ - template \ - scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \ - : outer_allocator_type(::boost::forward(outerAlloc)) \ - , m_inner(BOOST_PP_ENUM_PARAMS(n, q)) \ - {} \ - \ - scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) \ - : outer_allocator_type(other.outer_allocator()) \ - , m_inner(other.inner_allocator()) \ - {} \ - \ - scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \ - : outer_allocator_type(::boost::move(other.outer_allocator())) \ - , m_inner(::boost::move(other.inner_allocator())) \ - {} \ - \ - template \ - scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) \ - : outer_allocator_type(other.outer_allocator()) \ - , m_inner(other.inner_allocator()) \ - {} \ - \ - template \ - scoped_allocator_adaptor_base \ - (BOOST_RV_REF_BEG scoped_allocator_adaptor_base BOOST_RV_REF_END other) \ - : outer_allocator_type(other.outer_allocator()) \ - , m_inner(other.inner_allocator()) \ - {} \ - \ - public: \ - struct internal_type_t{}; \ - \ - template \ - scoped_allocator_adaptor_base \ - ( internal_type_t \ - , BOOST_FWD_REF(OuterA2) outerAlloc \ - , const inner_allocator_type &inner) \ - : outer_allocator_type(::boost::forward(outerAlloc)) \ - , m_inner(inner) \ - {} \ - \ - public: \ - scoped_allocator_adaptor_base &operator= \ - (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) \ - { \ - outer_allocator_type::operator=(other.outer_allocator()); \ - m_inner = other.inner_allocator(); \ - return *this; \ - } \ - \ - scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \ - { \ - outer_allocator_type::operator=(boost::move(other.outer_allocator())); \ - m_inner = ::boost::move(other.inner_allocator()); \ - return *this; \ - } \ - \ - void swap(scoped_allocator_adaptor_base &r) \ - { \ - boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); \ - boost::adl_move_swap(this->m_inner, r.inner_allocator()); \ - } \ - \ - friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) \ - { l.swap(r); } \ - \ - inner_allocator_type& inner_allocator() \ - { return m_inner; } \ - \ - inner_allocator_type const& inner_allocator() const \ - { return m_inner; } \ - \ - outer_allocator_type & outer_allocator() \ - { return static_cast(*this); } \ - \ - const outer_allocator_type &outer_allocator() const \ - { return static_cast(*this); } \ - \ - scoped_allocator_type select_on_container_copy_construction() const \ - { \ - return scoped_allocator_type \ - (internal_type_t() \ - ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) \ - ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) \ - ); \ - } \ - private: \ - inner_allocator_type m_inner; \ -}; \ +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\ +template \ +class scoped_allocator_adaptor_base\ + : public OuterAlloc\ +{\ + typedef allocator_traits outer_traits_type;\ + BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\ + \ + public:\ + template \ + struct rebind_base\ + {\ + typedef scoped_allocator_adaptor_base other;\ + };\ + \ + typedef OuterAlloc outer_allocator_type;\ + typedef scoped_allocator_adaptor inner_allocator_type;\ + typedef scoped_allocator_adaptor scoped_allocator_type;\ + typedef allocator_traits inner_traits_type;\ + typedef container_detail::bool_<\ + outer_traits_type::propagate_on_container_copy_assignment::value ||\ + inner_allocator_type::propagate_on_container_copy_assignment::value\ + > propagate_on_container_copy_assignment;\ + typedef container_detail::bool_<\ + outer_traits_type::propagate_on_container_move_assignment::value ||\ + inner_allocator_type::propagate_on_container_move_assignment::value\ + > propagate_on_container_move_assignment;\ + typedef container_detail::bool_<\ + outer_traits_type::propagate_on_container_swap::value ||\ + inner_allocator_type::propagate_on_container_swap::value\ + > propagate_on_container_swap;\ + \ + scoped_allocator_adaptor_base(){}\ + \ + template \ + scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\ + : outer_allocator_type(::boost::forward(outerAlloc))\ + , m_inner(BOOST_MOVE_ARG##N)\ + {}\ + \ + scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + : outer_allocator_type(::boost::move(other.outer_allocator()))\ + , m_inner(::boost::move(other.inner_allocator()))\ + {}\ + \ + template \ + scoped_allocator_adaptor_base\ + (const scoped_allocator_adaptor_base& other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + template \ + scoped_allocator_adaptor_base\ + (BOOST_RV_REF_BEG scoped_allocator_adaptor_base BOOST_RV_REF_END other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + public:\ + struct internal_type_t{};\ + \ + template \ + scoped_allocator_adaptor_base\ + ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\ + : outer_allocator_type(::boost::forward(outerAlloc))\ + , m_inner(inner)\ + {}\ + \ + public:\ + scoped_allocator_adaptor_base &operator=\ + (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\ + {\ + outer_allocator_type::operator=(other.outer_allocator());\ + m_inner = other.inner_allocator();\ + return *this;\ + }\ + \ + scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + {\ + outer_allocator_type::operator=(boost::move(other.outer_allocator()));\ + m_inner = ::boost::move(other.inner_allocator());\ + return *this;\ + }\ + \ + void swap(scoped_allocator_adaptor_base &r)\ + {\ + boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\ + boost::adl_move_swap(this->m_inner, r.inner_allocator());\ + }\ + \ + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\ + { l.swap(r); }\ + \ + inner_allocator_type& inner_allocator()\ + { return m_inner; }\ + \ + inner_allocator_type const& inner_allocator() const\ + { return m_inner; }\ + \ + outer_allocator_type & outer_allocator()\ + { return static_cast(*this); }\ + \ + const outer_allocator_type &outer_allocator() const\ + { return static_cast(*this); }\ + \ + scoped_allocator_type select_on_container_copy_construction() const\ + {\ + return scoped_allocator_type\ + (internal_type_t()\ + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\ + ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\ + );\ + }\ + private:\ + inner_allocator_type m_inner;\ +};\ //! -#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) -#include BOOST_PP_LOCAL_ITERATE() +BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9 + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9 +#else + #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs... + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs +#endif + //Specialization for adaptor without any InnerAlloc template -class scoped_allocator_adaptor_base - < OuterAlloc - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, nat) - #endif - > +class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> : public OuterAlloc { BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) @@ -895,11 +736,7 @@ class scoped_allocator_adaptor_base { typedef scoped_allocator_adaptor_base ::template portable_rebind_alloc::type - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat) - #endif - > other; + BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other; }; typedef OuterAlloc outer_allocator_type; @@ -932,25 +769,13 @@ class scoped_allocator_adaptor_base template scoped_allocator_adaptor_base - (const scoped_allocator_adaptor_base< - OuterA2 - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat) - #endif - >& other) + (const scoped_allocator_adaptor_base& other) : outer_allocator_type(other.outer_allocator()) {} template scoped_allocator_adaptor_base - (BOOST_RV_REF_BEG scoped_allocator_adaptor_base< - OuterA2 - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat) - #endif - > BOOST_RV_REF_END other) + (BOOST_RV_REF_BEG scoped_allocator_adaptor_base BOOST_RV_REF_END other) : outer_allocator_type(other.outer_allocator()) {} @@ -1014,78 +839,65 @@ class scoped_allocator_adaptor_base //Scoped allocator #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) +#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - //! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor. - //! The class template scoped_allocator_adaptor is an allocator template that specifies - //! the memory resource (the outer allocator) to be used by a container (as any other - //! allocator does) and also specifies an inner allocator resource to be passed to - //! the constructor of every element within the container. - //! - //! This adaptor is - //! instantiated with one outer and zero or more inner allocator types. If - //! instantiated with only one allocator type, the inner allocator becomes the - //! scoped_allocator_adaptor itself, thus using the same allocator resource for the - //! container and every element within the container and, if the elements themselves - //! are containers, each of their elements recursively. If instantiated with more than - //! one allocator, the first allocator is the outer allocator for use by the container, - //! the second allocator is passed to the constructors of the container's elements, - //! and, if the elements themselves are containers, the third allocator is passed to - //! the elements' elements, and so on. If containers are nested to a depth greater - //! than the number of allocators, the last allocator is used repeatedly, as in the - //! single-allocator case, for any remaining recursions. - //! - //! [Note: The - //! scoped_allocator_adaptor is derived from the outer allocator type so it can be - //! substituted for the outer allocator type in most expressions. -end note] - //! - //! In the construct member functions, OUTERMOST(x) is x if x does not have - //! an outer_allocator() member function and - //! OUTERMOST(x.outer_allocator()) otherwise; OUTERMOST_ALLOC_TRAITS(x) is - //! allocator_traits. - //! - //! [Note: OUTERMOST(x) and - //! OUTERMOST_ALLOC_TRAITS(x) are recursive operations. It is incumbent upon - //! the definition of outer_allocator() to ensure that the recursion terminates. - //! It will terminate for all instantiations of scoped_allocator_adaptor. -end note] - template - class scoped_allocator_adaptor +//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor. +//! The class template scoped_allocator_adaptor is an allocator template that specifies +//! the memory resource (the outer allocator) to be used by a container (as any other +//! allocator does) and also specifies an inner allocator resource to be passed to +//! the constructor of every element within the container. +//! +//! This adaptor is +//! instantiated with one outer and zero or more inner allocator types. If +//! instantiated with only one allocator type, the inner allocator becomes the +//! scoped_allocator_adaptor itself, thus using the same allocator resource for the +//! container and every element within the container and, if the elements themselves +//! are containers, each of their elements recursively. If instantiated with more than +//! one allocator, the first allocator is the outer allocator for use by the container, +//! the second allocator is passed to the constructors of the container's elements, +//! and, if the elements themselves are containers, the third allocator is passed to +//! the elements' elements, and so on. If containers are nested to a depth greater +//! than the number of allocators, the last allocator is used repeatedly, as in the +//! single-allocator case, for any remaining recursions. +//! +//! [Note: The +//! scoped_allocator_adaptor is derived from the outer allocator type so it can be +//! substituted for the outer allocator type in most expressions. -end note] +//! +//! In the construct member functions, OUTERMOST(x) is x if x does not have +//! an outer_allocator() member function and +//! OUTERMOST(x.outer_allocator()) otherwise; OUTERMOST_ALLOC_TRAITS(x) is +//! allocator_traits. +//! +//! [Note: OUTERMOST(x) and +//! OUTERMOST_ALLOC_TRAITS(x) are recursive operations. It is incumbent upon +//! the definition of outer_allocator() to ensure that the recursion terminates. +//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note] +template +class scoped_allocator_adaptor - #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) +#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - template - class scoped_allocator_adaptor +template +class scoped_allocator_adaptor - #endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) +#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -template +template class scoped_allocator_adaptor #endif + : public container_detail::scoped_allocator_adaptor_base - + { BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor) public: #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef container_detail::scoped_allocator_adaptor_base - base_type; + base_type; typedef typename base_type::internal_type_t internal_type_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef OuterAlloc outer_allocator_type; @@ -1103,16 +915,20 @@ class scoped_allocator_adaptor typedef typename outer_traits_type::const_pointer const_pointer; typedef typename outer_traits_type::void_pointer void_pointer; typedef typename outer_traits_type::const_void_pointer const_void_pointer; - //! Type: true_type if allocator_traits::propagate_on_container_copy_assignment::value is - //! true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_type. + //! Type: A type with a constant boolean value == true if + //!allocator_traits::propagate_on_container_copy_assignment::value is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs...; otherwise, false otherwise. typedef typename base_type:: propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - //! Type: true_type if allocator_traits::propagate_on_container_move_assignment::value is - //! true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_type. + //! Type: A type with a constant boolean value == true if + //!allocator_traits::propagate_on_container_move_assignment::value is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs...; otherwise, false otherwise. typedef typename base_type:: propagate_on_container_move_assignment propagate_on_container_move_assignment; - //! Type: true_type if allocator_traits::propagate_on_container_swap::value is true for any - //! A in the set of OuterAlloc and InnerAllocs...; otherwise, false_type. + + //! Type: A type with a constant boolean value == true if + //!allocator_traits::propagate_on_container_swap::value is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs...; otherwise, false otherwise. typedef typename base_type:: propagate_on_container_swap propagate_on_container_swap; @@ -1125,12 +941,7 @@ class scoped_allocator_adaptor { typedef scoped_allocator_adaptor < typename outer_traits_type::template portable_rebind_alloc::type - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - > other; + , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other; }; //! Effects: value-initializes the OuterAlloc base class @@ -1166,17 +977,14 @@ class scoped_allocator_adaptor {} #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #define BOOST_PP_LOCAL_MACRO(n) \ - template \ - scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \ - : base_type(::boost::forward(outerAlloc) \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, q) \ - ) \ - {} \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\ + template \ + scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\ + : base_type(::boost::forward(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\ + {}\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE) + #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1184,13 +992,7 @@ class scoped_allocator_adaptor //! //! Effects: initializes each allocator within the adaptor with the corresponding allocator from other. template - scoped_allocator_adaptor(const scoped_allocator_adaptor &other) + scoped_allocator_adaptor(const scoped_allocator_adaptor &other) : base_type(other.base()) {} @@ -1199,13 +1001,8 @@ class scoped_allocator_adaptor //! Effects: initializes each allocator within the adaptor with the corresponding allocator //! rvalue from other. template - scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor BOOST_RV_REF_END other) + scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor + BOOST_RV_REF_END other) : base_type(::boost::move(other.base())) {} @@ -1213,7 +1010,7 @@ class scoped_allocator_adaptor { return static_cast(base_type::operator=(static_cast(other))); } scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) - { return static_cast(base_type::operator=(boost::move(static_cast(other)))); } + { return static_cast(base_type::operator=(boost::move(other.base()))); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! Effects: swaps *this with r. @@ -1245,9 +1042,7 @@ class scoped_allocator_adaptor //! Returns: //! allocator_traits::max_size(outer_allocator()). size_type max_size() const BOOST_CONTAINER_NOEXCEPT - { - return outer_traits_type::max_size(this->outer_allocator()); - } + { return outer_traits_type::max_size(this->outer_allocator()); } //! Effects: //! calls OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p). @@ -1261,28 +1056,22 @@ class scoped_allocator_adaptor //! Returns: //! allocator_traits::allocate(outer_allocator(), n). pointer allocate(size_type n) - { - return outer_traits_type::allocate(this->outer_allocator(), n); - } + { return outer_traits_type::allocate(this->outer_allocator(), n); } //! Returns: //! allocator_traits::allocate(outer_allocator(), n, hint). pointer allocate(size_type n, const_void_pointer hint) - { - return outer_traits_type::allocate(this->outer_allocator(), n, hint); - } + { return outer_traits_type::allocate(this->outer_allocator(), n, hint); } //! Effects: //! allocator_traits::deallocate(outer_allocator(), p, n). void deallocate(pointer p, size_type n) - { - outer_traits_type::deallocate(this->outer_allocator(), p, n); - } + { outer_traits_type::deallocate(this->outer_allocator(), p, n); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! Returns: A new scoped_allocator_adaptor object where each allocator - //! A in the adaptor is initialized from the result of calling - //! allocator_traits::select_on_container_copy_construction() on + //! Allocator in the adaptor is initialized from the result of calling + //! allocator_traits::select_on_container_copy_construction() on //! the corresponding allocator in *this. scoped_allocator_adaptor select_on_container_copy_construction() const; #endif //BOOST_CONTAINER_DOXYGEN_INVOKED @@ -1332,7 +1121,7 @@ class scoped_allocator_adaptor construct(T* p, BOOST_FWD_REF(Args)...args) { container_detail::dispatch_uses_allocator - ( uses_allocator() + ( container_detail::bool_::value>() , get_outermost_allocator(this->outer_allocator()) , this->inner_allocator() , p, ::boost::forward(args)...); @@ -1342,22 +1131,19 @@ class scoped_allocator_adaptor //Disable this overload if the first argument is pair as some compilers have //overload selection problems when the first parameter is a pair. - #define BOOST_PP_LOCAL_MACRO(n) \ - template < typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ - typename container_detail::enable_if_c::value, void>::type \ - construct(T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - container_detail::dispatch_uses_allocator \ - ( uses_allocator() \ - , get_outermost_allocator(this->outer_allocator()) \ - , this->inner_allocator() \ - , p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \ + template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + typename container_detail::enable_if_c::value, void>::type\ + construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + container_detail::dispatch_uses_allocator\ + ( container_detail::bool_::value>()\ + , get_outermost_allocator(this->outer_allocator())\ + , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1428,31 +1214,11 @@ class scoped_allocator_adaptor template void construct_pair(Pair* p, const Pair2& pr) - { - this->construct(container_detail::addressof(p->first), pr.first); - BOOST_TRY{ - this->construct(container_detail::addressof(p->second), pr.second); - } - BOOST_CATCH(...){ - this->destroy(container_detail::addressof(p->first)); - BOOST_RETHROW - } - BOOST_CATCH_END - } + { this->construct_pair(p, pr.first, pr.second); } template void construct_pair(Pair* p, BOOST_RV_REF(Pair2) pr) - { - this->construct(container_detail::addressof(p->first), ::boost::move(pr.first)); - BOOST_TRY{ - this->construct(container_detail::addressof(p->second), ::boost::move(pr.second)); - } - BOOST_CATCH(...){ - this->destroy(container_detail::addressof(p->first)); - BOOST_RETHROW - } - BOOST_CATCH_END - } + { this->construct_pair(p, ::boost::move(pr.first), ::boost::move(pr.second)); } //template //void construct(pair* p, piecewise_construct_t, tuple x, tuple y); @@ -1467,66 +1233,23 @@ class scoped_allocator_adaptor #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -template -inline bool operator==( - const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b) +template +inline bool operator==(const scoped_allocator_adaptor& a + ,const scoped_allocator_adaptor& b) { #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) const bool has_zero_inner = sizeof...(InnerAllocs) == 0u; #else - const bool has_zero_inner = - boost::container::container_detail::is_same - ::value; + const bool has_zero_inner = boost::container::container_detail::is_same::value; #endif - - return a.outer_allocator() == b.outer_allocator() + return a.outer_allocator() == b.outer_allocator() && (has_zero_inner || a.inner_allocator() == b.inner_allocator()); } -template -inline bool operator!=( - const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b) -{ - return ! (a == b); -} +template +inline bool operator!=(const scoped_allocator_adaptor& a + ,const scoped_allocator_adaptor& b) +{ return !(a == b); } }} // namespace boost { namespace container { diff --git a/include/boost/container/scoped_allocator_fwd.hpp b/include/boost/container/scoped_allocator_fwd.hpp index 5392ef4..b65324e 100644 --- a/include/boost/container/scoped_allocator_fwd.hpp +++ b/include/boost/container/scoped_allocator_fwd.hpp @@ -23,8 +23,7 @@ #include #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#include +#include #endif namespace boost { namespace container { @@ -51,10 +50,7 @@ namespace boost { namespace container { #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template +template class scoped_allocator_adaptor; #endif @@ -77,7 +73,7 @@ struct constructible_with_allocator_suffix; template struct constructible_with_allocator_prefix; -template +template struct uses_allocator; }} // namespace boost { namespace container { diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp index 4864a03..9b8664f 100644 --- a/include/boost/container/set.hpp +++ b/include/boost/container/set.hpp @@ -17,21 +17,24 @@ #include #include +// container #include - -#include -#include -#include +// container/detail #include #include +#include //new_allocator +// intrusive/detail +#include //pair +#include //less, equal +// move +#include #include -#ifndef BOOST_CONTAINER_PERFECT_FORWARDING -#include +// move/detail +#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include #endif - -#include //pair -#include //less -#include //allocator +// std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -51,23 +54,23 @@ namespace container { //! //! \tparam Key is the type to be inserted in the set, which is also the key_type //! \tparam Compare is the comparison functor used to order keys -//! \tparam A is the allocator to be used to allocate memory for this container +//! \tparam Allocator is the allocator to be used to allocate memory for this container //! \tparam SetOptions is an packed option type generated using using boost::container::tree_assoc_options. -template , class A = std::allocator, class SetOptions = tree_assoc_defaults > +template , class Allocator = new_allocator, class SetOptions = tree_assoc_defaults > #else -template +template #endif class set ///@cond : public container_detail::tree - < Key, Key, container_detail::identity, Compare, A, SetOptions> + < Key, Key, container_detail::identity, Compare, Allocator, SetOptions> ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(set) typedef container_detail::tree - < Key, Key, container_detail::identity, Compare, A, SetOptions> base_t; + < Key, Key, container_detail::identity, Compare, Allocator, SetOptions> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -80,19 +83,19 @@ class set typedef Key value_type; typedef Compare key_compare; typedef Compare value_compare; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; ////////////////////////////////////////////// // @@ -371,7 +374,7 @@ class set size_type max_size() const; #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object x of type Key constructed with //! std::forward(args)... if and only if there is @@ -388,7 +391,7 @@ class set //! //! Complexity: Logarithmic. template - std::pair emplace(Args&&... args) + std::pair emplace(BOOST_FWD_REF(Args)... args) { return this->base_t::emplace_unique(boost::forward(args)...); } //! Effects: Inserts an object of type Key constructed with @@ -401,26 +404,24 @@ class set //! //! Complexity: Logarithmic. template - 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)...); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_hint_unique(p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + std::pair emplace(BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE) + #undef BOOST_CONTAINER_SET_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts x if and only if there is no element in the container @@ -680,10 +681,13 @@ class set //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; namespace container { @@ -702,23 +706,23 @@ namespace container { //! //! \tparam Key is the type to be inserted in the set, which is also the key_type //! \tparam Compare is the comparison functor used to order keys -//! \tparam A is the allocator to be used to allocate memory for this container +//! \tparam Allocator is the allocator to be used to allocate memory for this container //! \tparam MultiSetOptions is an packed option type generated using using boost::container::tree_assoc_options. -template , class A = std::allocator, class MultiSetOptions = tree_assoc_defaults > +template , class Allocator = new_allocator, class MultiSetOptions = tree_assoc_defaults > #else -template +template #endif class multiset /// @cond : public container_detail::tree - , Compare, A, MultiSetOptions> + , Compare, Allocator, MultiSetOptions> /// @endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(multiset) typedef container_detail::tree - , Compare, A, MultiSetOptions> base_t; + , Compare, Allocator, MultiSetOptions> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -732,19 +736,19 @@ class multiset typedef Key value_type; typedef Compare key_compare; typedef Compare value_compare; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_MOVE_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_MOVE_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; ////////////////////////////////////////////// // @@ -900,7 +904,7 @@ class multiset #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... and returns the iterator pointing to the @@ -908,7 +912,7 @@ class multiset //! //! Complexity: Logarithmic. template - iterator emplace(Args&&... args) + iterator emplace(BOOST_FWD_REF(Args)... args) { return this->base_t::emplace_equal(boost::forward(args)...); } //! Effects: Inserts an object of type Key constructed with @@ -920,26 +924,24 @@ class multiset //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. template - 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)...); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_hint(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return this->base_t::emplace_hint_equal(p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE) + #undef BOOST_CONTAINER_MULTISET_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts x and returns the iterator pointing to the @@ -1108,10 +1110,13 @@ class multiset //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > +template +struct has_trivial_destructor_after_move > { - static const bool value = has_trivial_destructor_after_move::value && has_trivial_destructor_after_move::value; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; }; namespace container { diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index 35c794c..d11c560 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -18,46 +18,43 @@ #include #include +// container #include +#include //new_allocator #include -#include +// container/detail +#include //algo_equal(), algo_lexicographical_compare +#include +#include #include #include -#include -#include - #include -#include -#include //algo_equal(), algo_lexicographical_compare - - -#include -#include -#include -#include -#include +#include +// intrusive #include - - - -#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -//Preprocessor library to emulate perfect forwarding -#else -#include +#include +// move +#include +#include +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include #endif - -#include //std::allocator +#include +// other +#include +// std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif - namespace boost { namespace container { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -template +template class slist; namespace container_detail { @@ -94,10 +91,10 @@ struct iiterator_node_value_type< slist_node > { typedef T type; }; -template +template struct intrusive_slist_type { - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef typename boost::intrusive::pointer_traits ::template @@ -154,31 +151,29 @@ struct intrusive_slist_type //! then you should probably use list instead of slist. //! //! \tparam T The type of object that is stored in the list -//! \tparam A The allocator used for all internal memory management +//! \tparam Allocator The allocator used for all internal memory management #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif class slist : protected container_detail::node_alloc_holder - ::type> + ::type> { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef typename - container_detail::intrusive_slist_type::type Icont; - typedef container_detail::node_alloc_holder AllocHolder; + container_detail::intrusive_slist_type::type Icont; + typedef container_detail::node_alloc_holder AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef typename AllocHolder::ValAlloc ValAlloc; typedef typename AllocHolder::Node Node; typedef container_detail::allocator_destroyer Destroyer; - typedef typename AllocHolder::allocator_v1 allocator_v1; - typedef typename AllocHolder::allocator_v2 allocator_v2; typedef typename AllocHolder::alloc_version alloc_version; typedef boost::container:: - allocator_traits allocator_traits_type; - typedef boost::container::equal_to_value equal_to_value_type; + allocator_traits allocator_traits_type; + typedef boost::container::equal_to_value equal_to_value_type; BOOST_COPYABLE_AND_MOVABLE(slist) typedef container_detail::iterator_from_iiterator iterator_impl; @@ -193,16 +188,16 @@ class slist ////////////////////////////////////////////// typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_MOVE_IMPDEF(NodeAlloc) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator; + typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator; public: @@ -687,7 +682,7 @@ class slist // ////////////////////////////////////////////// - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the front of the list @@ -697,7 +692,7 @@ class slist //! //! Complexity: Amortized constant time. template - void emplace_front(Args&&... args) + void emplace_front(BOOST_FWD_REF(Args)... args) { this->emplace_after(this->cbefore_begin(), boost::forward(args)...); } //! Effects: Inserts an object of type T constructed with @@ -708,35 +703,30 @@ class slist //! //! Complexity: Constant template - 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)...)); return iterator(this->icont().insert_after(prev.get(), *pnode)); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - this->emplace(this->cbegin() \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace_after(const_iterator prev \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - NodePtr pnode (AllocHolder::create_node \ - (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - return iterator(this->icont().insert_after(prev.get(), *pnode)); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + void emplace_front(BOOST_MOVE_UREF##N)\ + { this->emplace_after(this->cbefore_begin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace_after(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\ + return iterator(this->icont().insert_after(p.get(), *pnode));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE) + #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts a copy of x at the beginning of the list. @@ -830,7 +820,7 @@ class slist , typename container_detail::enable_if_c < !container_detail::is_convertible::value && (container_detail::is_input_iterator::value - || container_detail::is_same::value + || container_detail::is_same::value ) >::type * = 0 #endif @@ -868,7 +858,7 @@ class slist , typename container_detail::enable_if_c < !container_detail::is_convertible::value && !(container_detail::is_input_iterator::value - || container_detail::is_same::value + || container_detail::is_same::value ) >::type * = 0 ) @@ -1269,7 +1259,7 @@ class slist // ////////////////////////////////////////////// - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type T constructed with //! std::forward(args)... before p @@ -1279,24 +1269,22 @@ class slist //! //! Complexity: Linear to the elements before p template - 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)...); } - #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #else - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace (const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - return this->emplace_after \ - (this->previous(p) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + return this->emplace_after(this->previous(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE) + #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE + + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Requires: p must be a valid iterator of *this. @@ -1631,10 +1619,13 @@ namespace boost { //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > - : public ::boost::has_trivial_destructor_after_move -{}; +template +struct has_trivial_destructor_after_move > +{ + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; namespace container { @@ -1651,11 +1642,14 @@ namespace container { //there is no other way namespace std { -template -class insert_iterator > +template +class insert_iterator; + +template +class insert_iterator > { protected: - typedef boost::container::slist Container; + typedef boost::container::slist Container; Container* container; typename Container::iterator iter; public: diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index 2f4f907..bfdd171 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -25,29 +25,37 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include //algo_equal(), algo_lexicographical_compare + +// container #include -#include +#include +#include //new_allocator #include +// container/detail +#include +#include //algo_equal(), algo_lexicographical_compare +#include +#include +#include +#include +#include +#include +#include +#include +// intrusive #include -#include -#include +// intrusive/detail +#include //pair +// move #include #include -#include -#include #include - - -#include //std::pair -#include +// move/detail +#include +// other +#include +#include +// std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -407,16 +415,16 @@ class stable_vector_iterator //! operations provide stronger exception safety guarantees than in std::vector. //! //! \tparam T The type of object that is stored in the stable_vector -//! \tparam A The allocator used for all internal memory management +//! \tparam Allocator The allocator used for all internal memory management #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template > +template > #else -template +template #endif class stable_vector { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; typedef boost::intrusive:: pointer_traits ptr_traits; @@ -452,13 +460,9 @@ class stable_vector typedef typename node_ptr_traits::reference node_reference; typedef typename const_node_ptr_traits::reference const_node_reference; - typedef ::boost::container::container_detail:: - integral_constant allocator_v1; - typedef ::boost::container::container_detail:: - integral_constant allocator_v2; typedef ::boost::container::container_detail::integral_constant ::value> alloc_version; + version::value> alloc_version; typedef typename allocator_traits_type:: template portable_rebind_alloc ::type node_allocator_type; @@ -481,10 +485,10 @@ class stable_vector friend class stable_vector_detail::clear_on_destroy; typedef stable_vector_iterator - < typename allocator_traits::pointer + < typename allocator_traits::pointer , false> iterator_impl; typedef stable_vector_iterator - < typename allocator_traits::pointer + < typename allocator_traits::pointer , false> const_iterator_impl; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -495,18 +499,18 @@ class stable_vector // ////////////////////////////////////////////// typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; typedef node_allocator_type stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator; + typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: @@ -1315,7 +1319,7 @@ class stable_vector // ////////////////////////////////////////////// - #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the end of the stable_vector. @@ -1354,40 +1358,33 @@ class stable_vector #else - #define BOOST_PP_LOCAL_MACRO(n) \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ - BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \ - EmplaceFunctor; \ - typedef emplace_iterator EmplaceIterator; \ - EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \ - BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \ - BOOST_PP_RPAREN_IF(n); \ - this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \ - } \ - \ - BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ - iterator emplace(const_iterator p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ - BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \ - EmplaceFunctor; \ - typedef emplace_iterator EmplaceIterator; \ - EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \ - BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \ - BOOST_PP_RPAREN_IF(n); \ - size_type pos_n = p - this->cbegin(); \ - this->insert(p, EmplaceIterator(ef), EmplaceIterator()); \ - return iterator(this->begin() + pos_n); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + void emplace_back(BOOST_MOVE_UREF##N)\ + {\ + typedef emplace_functor##N\ + BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\ + typedef emplace_iterator EmplaceIterator;\ + EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\ + this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + typedef emplace_functor##N\ + BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\ + typedef emplace_iterator EmplaceIterator;\ + EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\ + const size_type pos_n = p - this->cbegin();\ + this->insert(p, EmplaceIterator(ef), EmplaceIterator());\ + return this->begin() += pos_n;\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE) + #undef BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts a copy of x at the end of the stable_vector. @@ -1997,20 +1994,23 @@ class stable_vector #undef STABLE_VECTOR_CHECK_INVARIANT -#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - -/* +} //namespace container { //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > - : public has_trivial_destructor_after_move::value -{}; +template +struct has_trivial_destructor_after_move > +{ + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; -*/ +namespace container { -}} +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +}} //namespace boost{ namespace container { #include diff --git a/include/boost/container/static_vector.hpp b/include/boost/container/static_vector.hpp index 628de2b..d701473 100644 --- a/include/boost/container/static_vector.hpp +++ b/include/boost/container/static_vector.hpp @@ -17,8 +17,8 @@ #include #include +#include #include -#include #include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -63,8 +63,7 @@ class static_storage_allocator { return true; } private: - typename boost::aligned_storage - ::value>::type storage; + typename aligned_storage::value>::type storage; }; } //namespace container_detail { @@ -264,8 +263,8 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c boost::has_nothrow_move::value is \c true and Value's move constructor throws. - //! @li If \c boost::has_nothrow_move::value is \c false and Value's copy constructor throws. + //! @li If \c has_nothrow_move::value is \c true and Value's move constructor throws. + //! @li If \c has_nothrow_move::value is \c false and Value's copy constructor throws. //! //! @par Complexity //! Linear O(N). @@ -280,14 +279,14 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c boost::has_nothrow_move::value is \c true and Value's move constructor throws. - //! @li If \c boost::has_nothrow_move::value is \c false and Value's copy constructor throws. + //! @li If \c has_nothrow_move::value is \c true and Value's move constructor throws. + //! @li If \c has_nothrow_move::value is \c false and Value's copy constructor throws. //! //! @par Complexity //! Linear O(N). template static_vector(BOOST_RV_REF_BEG static_vector BOOST_RV_REF_END other) - : base_t(BOOST_MOVE_BASE(typename static_vector::base_t, other)) + : base_t(BOOST_MOVE_BASE(typename static_vector::base_t, other)) {} //! @brief Copy assigns Values stored in the other static_vector to this one. @@ -341,8 +340,8 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c boost::has_nothrow_move::value is \c true and Value's move constructor or move assignment throws. - //! @li If \c boost::has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws. + //! @li If \c has_nothrow_move::value is \c true and Value's move constructor or move assignment throws. + //! @li If \c has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). @@ -358,8 +357,8 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c boost::has_nothrow_move::value is \c true and Value's move constructor or move assignment throws. - //! @li If \c boost::has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws. + //! @li If \c has_nothrow_move::value is \c true and Value's move constructor or move assignment throws. + //! @li If \c has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). @@ -367,7 +366,7 @@ public: static_vector & operator=(BOOST_RV_REF_BEG static_vector BOOST_RV_REF_END other) { return static_cast(base_t::operator= - (BOOST_MOVE_BASE(typename static_vector::base_t, other))); + (BOOST_MOVE_BASE(typename static_vector::base_t, other))); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -386,8 +385,8 @@ public: //! @param other The static_vector which content will be swapped with this one's content. //! //! @par Throws - //! @li If \c boost::has_nothrow_move::value is \c true and Value's move constructor or move assignment throws, - //! @li If \c boost::has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws, + //! @li If \c has_nothrow_move::value is \c true and Value's move constructor or move assignment throws, + //! @li If \c has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws, //! //! @par Complexity //! Linear O(N). @@ -400,8 +399,8 @@ public: //! @param other The static_vector which content will be swapped with this one's content. //! //! @par Throws - //! @li If \c boost::has_nothrow_move::value is \c true and Value's move constructor or move assignment throws, - //! @li If \c boost::has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws, + //! @li If \c has_nothrow_move::value is \c true and Value's move constructor or move assignment throws, + //! @li If \c has_nothrow_move::value is \c false and Value's copy constructor or copy assignment throws, //! //! @par Complexity //! Linear O(N). diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 3d654ca..17b0d59 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -16,31 +16,37 @@ #endif #include -#include - #include #include -#include -#include -#include -#include -#include +// container #include +#include //new_allocator +#include +// container/detail +#include #include -#include +#include #include +#include +#include +#include +#include +#include +#include + #include #include #include -#include #include #include + +#include + + #include -#include +#include //bind2nd, etc. #include -#include -#include #include #include #include @@ -49,8 +55,6 @@ #include #include #include -#include -#include #include namespace boost { @@ -68,15 +72,15 @@ namespace container_detail { // memory. The destructor assumes that the memory either is the internal buffer, // or else points to a block of memory that was allocated using string_base's // allocator and whose size is this->m_storage. -template +template class basic_string_base { basic_string_base & operator=(const basic_string_base &); basic_string_base(const basic_string_base &); - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; public: - typedef A allocator_type; + typedef Allocator allocator_type; typedef allocator_type stored_allocator_type; typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::value_type value_type; @@ -152,8 +156,8 @@ class basic_string_base //This type has the same alignment and size as long_t but it's POD //so, unlike long_t, it can be placed in a union - typedef typename boost::aligned_storage< sizeof(long_t), - container_detail::alignment_of::value>::type long_raw_t; + typedef typename container_detail::aligned_storage + ::value>::type long_raw_t; protected: static const size_type MinInternalBufferChars = 8; @@ -192,24 +196,24 @@ class basic_string_base }; struct members_holder - : public A + : public Allocator { members_holder() - : A() + : Allocator() {} template explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a) - : A(boost::forward(a)) + : Allocator(boost::forward(a)) {} repr_t m_repr; } members_; - const A &alloc() const + const Allocator &alloc() const { return members_; } - A &alloc() + Allocator &alloc() { return members_; } static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type); @@ -250,23 +254,20 @@ class basic_string_base protected: - typedef container_detail::integral_constant allocator_v1; - typedef container_detail::integral_constant allocator_v2; typedef container_detail::integral_constant::value> alloc_version; + boost::container::container_detail::version::value> alloc_version; - std::pair - allocation_command(allocation_type command, + pointer allocation_command(allocation_type command, size_type limit_size, - size_type preferred_size, - size_type &received_size, pointer reuse = 0) + size_type &prefer_in_recvd_out_size, + pointer &reuse) { if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){ - reuse = pointer(); + reuse = 0; command &= ~(expand_fwd | expand_bwd); } - return container_detail::allocator_version_traits::allocation_command - (this->alloc(), command, limit_size, preferred_size, received_size, reuse); + return container_detail::allocator_version_traits::allocation_command + (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse); } size_type next_capacity(size_type additional_objects) const @@ -313,7 +314,8 @@ class basic_string_base if (n <= this->max_size()) { if(n > InternalBufferChars){ size_type new_cap = this->next_capacity(n); - pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first; + pointer reuse = 0; + pointer p = this->allocation_command(allocate_new, n, new_cap, reuse); this->is_short(false); this->priv_long_addr(p); this->priv_long_size(0); @@ -475,24 +477,24 @@ class basic_string_base //! //! \tparam CharT The type of character it contains. //! \tparam Traits The Character Traits type, which encapsulates basic character operations -//! \tparam A The allocator, used for internal memory management. +//! \tparam Allocator The allocator, used for internal memory management. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template , class A = std::allocator > +template , class Allocator = new_allocator > #else -template +template #endif class basic_string - : private container_detail::basic_string_base + : private container_detail::basic_string_base { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: - typedef allocator_traits allocator_traits_type; + typedef allocator_traits allocator_traits_type; BOOST_COPYABLE_AND_MOVABLE(basic_string) - typedef container_detail::basic_string_base base_t; + typedef container_detail::basic_string_base base_t; static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars; protected: - // A helper class to use a char_traits as a function object. + // Allocator helper class to use a char_traits as a function object. template struct Eq_traits @@ -535,25 +537,23 @@ class basic_string ////////////////////////////////////////////// typedef Traits traits_type; typedef CharT value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(pointer) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef BOOST_MOVE_IMPDEF(allocator_type) stored_allocator_type; + typedef BOOST_MOVE_IMPDEF(pointer) iterator; + typedef BOOST_MOVE_IMPDEF(const_pointer) const_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; static const size_type npos = size_type(-1); #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: typedef constant_iterator cvalue_iterator; - typedef typename base_t::allocator_v1 allocator_v1; - typedef typename base_t::allocator_v2 allocator_v2; typedef typename base_t::alloc_version alloc_version; typedef ::boost::intrusive::pointer_traits pointer_traits; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -1465,22 +1465,23 @@ class basic_string const size_type remaining = this->capacity() - old_size; const pointer old_start = this->priv_addr(); bool enough_capacity = false; - std::pair allocation_ret; size_type new_cap = 0; //Check if we have enough capacity + pointer hint = pointer(); + pointer allocation_ret = pointer(); if (remaining >= n){ enough_capacity = true; } else { //Otherwise expand current buffer or allocate new storage new_cap = this->next_capacity(n); + hint = old_start; allocation_ret = this->allocation_command - (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, - new_cap, new_cap, old_start); + (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint); //Check forward expansion - if(old_start == allocation_ret.first){ + if(old_start == allocation_ret){ enough_capacity = true; this->priv_storage(new_cap); } @@ -1516,8 +1517,8 @@ class basic_string } } else{ - pointer new_start = allocation_ret.first; - if(!allocation_ret.second){ + pointer new_start = allocation_ret; + if(!hint){ //Copy data to new buffer size_type new_length = 0; //This can't throw, since characters are POD @@ -1941,7 +1942,7 @@ class basic_string //! //! Throws: Nothing //! - //! Returns: find(basic_string(s,n),pos). + //! Returns: find(basic_string(s,n),pos). size_type find(const CharT* s, size_type pos, size_type n) const { if (pos + n > this->size()) @@ -1967,7 +1968,7 @@ class basic_string //! Throws: Nothing //! - //! Returns: find(basic_string(1,c), pos). + //! Returns: find(basic_string(1,c), pos). size_type find(CharT c, size_type pos = 0) const { const size_type sz = this->size(); @@ -2027,7 +2028,7 @@ class basic_string //! Throws: Nothing //! - //! Returns: rfind(basic_string(1,c),pos). + //! Returns: rfind(basic_string(1,c),pos). size_type rfind(CharT c, size_type pos = npos) const { const size_type len = this->size(); @@ -2084,7 +2085,7 @@ class basic_string //! //! Throws: Nothing //! - //! Returns: find_first_of(basic_string(1,c), pos). + //! Returns: find_first_of(basic_string(1,c), pos). size_type find_first_of(CharT c, size_type pos = 0) const { return find(c, pos); } @@ -2123,7 +2124,7 @@ class basic_string //! //! Throws: Nothing //! - //! Returns: find_last_of(basic_string(1,c),pos). + //! Returns: find_last_of(basic_string(1,c),pos). size_type find_last_of(const CharT* s, size_type pos = npos) const { return find_last_of(s, pos, Traits::length(s)); } @@ -2250,7 +2251,7 @@ class basic_string //! //! Throws: If memory allocation throws or out_of_range if pos > size(). //! - //! Returns: basic_string(data()+pos,rlen). + //! Returns: basic_string(data()+pos,rlen). basic_string substr(size_type pos = 0, size_type n = npos) const { if (pos > this->size()) @@ -2359,8 +2360,8 @@ class basic_string if (this->capacity() < res_arg){ size_type n = container_detail::max_value(res_arg, this->size()) + 1; size_type new_cap = this->next_capacity(n); - pointer new_start = this->allocation_command - (allocate_new, n, new_cap, new_cap).first; + pointer reuse = 0; + pointer new_start = this->allocation_command(allocate_new, n, new_cap, reuse); size_type new_length = 0; const pointer addr = this->priv_addr(); @@ -2391,7 +2392,7 @@ class basic_string template void priv_shrink_to_fit_dynamic_buffer ( AllocVersion - , typename container_detail::enable_if >::type* = 0) + , typename container_detail::enable_if >::type* = 0) { //Allocate a new buffer. size_type real_cap = 0; @@ -2400,13 +2401,14 @@ class basic_string const size_type long_storage = this->priv_long_storage(); //We can make this nothrow as chars are always NoThrowCopyables BOOST_TRY{ - const std::pair ret = this->allocation_command - (allocate_new, long_size+1, long_size+1, real_cap, long_addr); + pointer reuse = 0; + real_cap = long_size+1; + const pointer ret = this->allocation_command(allocate_new, long_size+1, real_cap, reuse); //Copy and update - Traits::copy( container_detail::to_raw_pointer(ret.first) + Traits::copy( container_detail::to_raw_pointer(ret) , container_detail::to_raw_pointer(this->priv_long_addr()) , long_size+1); - this->priv_long_addr(ret.first); + this->priv_long_addr(ret); this->priv_storage(real_cap); //And release old buffer this->alloc().deallocate(long_addr, long_storage); @@ -2420,13 +2422,12 @@ class basic_string template void priv_shrink_to_fit_dynamic_buffer ( AllocVersion - , typename container_detail::enable_if >::type* = 0) + , typename container_detail::enable_if >::type* = 0) { - size_type received_size; + size_type received_size = this->priv_long_size()+1; + pointer hint = this->priv_long_addr(); if(this->alloc().allocation_command - ( shrink_in_place | nothrow_allocation - , this->priv_long_storage(), this->priv_long_size()+1 - , received_size, this->priv_long_addr()).first){ + ( shrink_in_place | nothrow_allocation, this->priv_long_storage(), received_size, hint)){ this->priv_storage(received_size); } } @@ -2520,7 +2521,7 @@ class basic_string typedef basic_string - ,std::allocator > + ,new_allocator > string; //!Typedef for a basic_string of @@ -2528,7 +2529,7 @@ string; typedef basic_string - ,std::allocator > + ,new_allocator > wstring; #endif @@ -2538,12 +2539,12 @@ wstring; // Operator+ -template inline - basic_string - operator+(const basic_string& x - ,const basic_string& y) +template inline + basic_string + operator+(const basic_string& x + ,const basic_string& y) { - typedef basic_string str_t; + typedef basic_string str_t; typedef typename str_t::reserve_t reserve_t; reserve_t reserve; str_t result(reserve, x.size() + y.size(), x.get_stored_allocator()); @@ -2552,60 +2553,60 @@ template inline return result; } -template inline - basic_string operator+ - ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END x - , BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END y) +template inline + basic_string operator+ + ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END x + , BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END y) { x += y; return boost::move(x); } -template inline - basic_string operator+ - ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END x - , const basic_string& y) +template inline + basic_string operator+ + ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END x + , const basic_string& y) { x += y; return boost::move(x); } -template inline - basic_string operator+ - (const basic_string& x - ,BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END y) +template inline + basic_string operator+ + (const basic_string& x + ,BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END y) { y.insert(y.begin(), x.begin(), x.end()); return boost::move(y); } -template inline - basic_string operator+ - (const CharT* s, basic_string y) +template inline + basic_string operator+ + (const CharT* s, basic_string y) { y.insert(y.begin(), s, s + Traits::length(s)); return y; } -template inline - basic_string operator+ - (basic_string x, const CharT* s) +template inline + basic_string operator+ + (basic_string x, const CharT* s) { x += s; return x; } -template inline - basic_string operator+ - (CharT c, basic_string y) +template inline + basic_string operator+ + (CharT c, basic_string y) { y.insert(y.begin(), c); return y; } -template inline - basic_string operator+ - (basic_string x, const CharT c) +template inline + basic_string operator+ + (basic_string x, const CharT c) { x += c; return x; @@ -2613,137 +2614,137 @@ template inline // Operator== and operator!= -template +template inline bool -operator==(const basic_string& x, - const basic_string& y) +operator==(const basic_string& x, + const basic_string& y) { return x.size() == y.size() && Traits::compare(x.data(), y.data(), x.size()) == 0; } -template +template inline bool -operator==(const CharT* s, const basic_string& y) +operator==(const CharT* s, const basic_string& y) { - typename basic_string::size_type n = Traits::length(s); + typename basic_string::size_type n = Traits::length(s); return n == y.size() && Traits::compare(s, y.data(), n) == 0; } -template +template inline bool -operator==(const basic_string& x, const CharT* s) +operator==(const basic_string& x, const CharT* s) { - typename basic_string::size_type n = Traits::length(s); + typename basic_string::size_type n = Traits::length(s); return x.size() == n && Traits::compare(x.data(), s, n) == 0; } -template +template inline bool -operator!=(const basic_string& x, - const basic_string& y) +operator!=(const basic_string& x, + const basic_string& y) { return !(x == y); } -template +template inline bool -operator!=(const CharT* s, const basic_string& y) +operator!=(const CharT* s, const basic_string& y) { return !(s == y); } -template +template inline bool -operator!=(const basic_string& x, const CharT* s) +operator!=(const basic_string& x, const CharT* s) { return !(x == s); } // Operator< (and also >, <=, and >=). -template +template inline bool -operator<(const basic_string& x, const basic_string& y) +operator<(const basic_string& x, const basic_string& y) { return x.compare(y) < 0; -// return basic_string +// return basic_string // ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0; } -template +template inline bool -operator<(const CharT* s, const basic_string& y) +operator<(const CharT* s, const basic_string& y) { return y.compare(s) > 0; -// basic_string::size_type n = Traits::length(s); -// return basic_string +// basic_string::size_type n = Traits::length(s); +// return basic_string // ::s_compare(s, s + n, y.begin(), y.end()) < 0; } -template +template inline bool -operator<(const basic_string& x, +operator<(const basic_string& x, const CharT* s) { return x.compare(s) < 0; -// basic_string::size_type n = Traits::length(s); -// return basic_string +// basic_string::size_type n = Traits::length(s); +// return basic_string // ::s_compare(x.begin(), x.end(), s, s + n) < 0; } -template +template inline bool -operator>(const basic_string& x, - const basic_string& y) { +operator>(const basic_string& x, + const basic_string& y) { return y < x; } -template +template inline bool -operator>(const CharT* s, const basic_string& y) { +operator>(const CharT* s, const basic_string& y) { return y < s; } -template +template inline bool -operator>(const basic_string& x, const CharT* s) +operator>(const basic_string& x, const CharT* s) { return s < x; } -template +template inline bool -operator<=(const basic_string& x, - const basic_string& y) +operator<=(const basic_string& x, + const basic_string& y) { return !(y < x); } -template +template inline bool -operator<=(const CharT* s, const basic_string& y) +operator<=(const CharT* s, const basic_string& y) { return !(y < s); } -template +template inline bool -operator<=(const basic_string& x, const CharT* s) +operator<=(const basic_string& x, const CharT* s) { return !(s < x); } -template +template inline bool -operator>=(const basic_string& x, - const basic_string& y) +operator>=(const basic_string& x, + const basic_string& y) { return !(x < y); } -template +template inline bool -operator>=(const CharT* s, const basic_string& y) +operator>=(const CharT* s, const basic_string& y) { return !(s < y); } -template +template inline bool -operator>=(const basic_string& x, const CharT* s) +operator>=(const basic_string& x, const CharT* s) { return !(x < s); } // Swap. -template -inline void swap(basic_string& x, basic_string& y) +template +inline void swap(basic_string& x, basic_string& y) { x.swap(y); } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -2768,17 +2769,17 @@ string_fill(std::basic_ostream& os, } //namespace container_detail { #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -template +template std::basic_ostream& -operator<<(std::basic_ostream& os, const basic_string& s) +operator<<(std::basic_ostream& os, const basic_string& s) { typename std::basic_ostream::sentry sentry(os); bool ok = false; if (sentry) { ok = true; - typename basic_string::size_type n = s.size(); - typename basic_string::size_type pad_len = 0; + typename basic_string::size_type n = s.size(); + typename basic_string::size_type pad_len = 0; const bool left = (os.flags() & std::ios::left) != 0; const std::size_t w = os.width(0); std::basic_streambuf* buf = os.rdbuf(); @@ -2803,9 +2804,9 @@ operator<<(std::basic_ostream& os, const basic_string +template std::basic_istream& -operator>>(std::basic_istream& is, basic_string& s) +operator>>(std::basic_istream& is, basic_string& s) { typename std::basic_istream::sentry sentry(is); @@ -2850,11 +2851,11 @@ operator>>(std::basic_istream& is, basic_string& return is; } -template +template std::basic_istream& -getline(std::istream& is, basic_string& s,CharT delim) +getline(std::istream& is, basic_string& s,CharT delim) { - typename basic_string::size_type nread = 0; + typename basic_string::size_type nread = 0; typename std::basic_istream::sentry sentry(is, true); if (sentry) { std::basic_streambuf* buf = is.rdbuf(); @@ -2882,15 +2883,15 @@ getline(std::istream& is, basic_string& s,CharT delim) return is; } -template +template inline std::basic_istream& -getline(std::basic_istream& is, basic_string& s) +getline(std::basic_istream& is, basic_string& s) { return getline(is, s, '\n'); } -template -inline std::size_t hash_value(basic_string, A> const& v) +template +inline std::size_t hash_value(basic_string, Allocator> const& v) { return hash_range(v.begin(), v.end()); } @@ -2901,15 +2902,15 @@ inline std::size_t hash_value(basic_string, A> const& v namespace boost { -template -struct has_trivial_destructor_after_move; - //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > - : public ::boost::has_trivial_destructor_after_move -{}; +template +struct has_trivial_destructor_after_move > +{ + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; } diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index ad5fb25..b498fc3 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -17,42 +17,44 @@ #include #include + +// container #include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include #include -#include +#include //new_allocator #include -#include -#include +// container detail #include #include //equal() +#include +#include +#include +#include #include - +#include +#include +#include +#include +#include +#include +#include +// intrusive #include +// move +#include +#include +#include +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +// other +#include +#include -#include -#include -#include -#include -#include -#include - -#include //for std::allocator -#include //for std::pair +//std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include //for std::initializer_list #endif @@ -230,87 +232,88 @@ static const uninitialized_size_t uninitialized_size = uninitialized_size_t(); template struct vector_value_traits_base { - static const bool trivial_dctr = boost::has_trivial_destructor::value; - static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move::value; - static const bool trivial_copy = has_trivial_copy::value; - static const bool nothrow_copy = has_nothrow_copy::value || trivial_copy; - static const bool trivial_assign = has_trivial_assign::value; - static const bool nothrow_assign = has_nothrow_assign::value || trivial_assign; + static const bool trivial_dctr = is_trivially_destructible::value; + static const bool trivial_dctr_after_move = trivial_dctr;//has_trivial_destructor_after_move::value; + static const bool trivial_copy = is_trivially_copy_constructible::value; + static const bool nothrow_copy = is_nothrow_copy_constructible::value || trivial_copy; + static const bool trivial_assign = is_trivially_copy_assignable::value; + static const bool nothrow_assign = is_nothrow_copy_assignable::value || trivial_assign; }; -template +template struct vector_value_traits - : public vector_value_traits_base + : public vector_value_traits_base { - typedef vector_value_traits_base base_t; + typedef vector_value_traits_base base_t; //This is the anti-exception array destructor //to deallocate values already constructed typedef typename container_detail::if_c - ,container_detail::scoped_destructor_n + ,container_detail::null_scoped_destructor_n + ,container_detail::scoped_destructor_n >::type ArrayDestructor; //This is the anti-exception array deallocator - typedef container_detail::scoped_array_deallocator ArrayDeallocator; + typedef container_detail::scoped_array_deallocator ArrayDeallocator; }; //!This struct deallocates and allocated memory -template < class A - , class AllocatorVersion = typename container_detail::version::type +template < class Allocator + , class AllocatorVersion = typename container_detail::version::type > struct vector_alloc_holder - : public A + : public Allocator { private: BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) public: - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::value_type value_type; //Constructor, does not throw vector_alloc_holder() - BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value) - : A(), m_start(), m_size(), m_capacity() + BOOST_CONTAINER_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible::value) + : Allocator(), m_start(), m_size(), m_capacity() {} //Constructor, does not throw template explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT - : A(boost::forward(a)), m_start(), m_size(), m_capacity() + : Allocator(boost::forward(a)), m_start(), m_size(), m_capacity() {} //Constructor, does not throw template vector_alloc_holder(uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) - : A(boost::forward(a)) + : Allocator(boost::forward(a)) , m_start() , m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this , m_capacity() { if(initial_size){ - m_start = this->allocation_command(allocate_new, initial_size, initial_size, m_capacity, m_start).first; + pointer reuse = 0; + m_start = this->allocation_command(allocate_new, initial_size, m_capacity = initial_size, reuse); } } //Constructor, does not throw vector_alloc_holder(uninitialized_size_t, size_type initial_size) - : A() + : Allocator() , m_start() , m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this , m_capacity() { if(initial_size){ - m_start = this->allocation_command - (allocate_new, initial_size, initial_size, m_capacity, m_start).first; + pointer reuse = 0; + m_start = this->allocation_command(allocate_new, initial_size, m_capacity = initial_size, reuse); } } vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_CONTAINER_NOEXCEPT - : A(BOOST_MOVE_BASE(A, holder)) + : Allocator(BOOST_MOVE_BASE(Allocator, holder)) , m_start(holder.m_start) , m_size(holder.m_size) , m_capacity(holder.m_capacity) @@ -319,20 +322,6 @@ struct vector_alloc_holder holder.m_size = holder.m_capacity = 0; } - void first_allocation(size_type cap) - { - if(cap){ - m_start = this->allocation_command - (allocate_new, cap, cap, m_capacity, m_start).first; - #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS - ++this->num_alloc; - #endif - } - } - - void first_allocation_same_allocator_type(size_type cap) - { this->first_allocation(cap); } - ~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT { if(this->m_capacity){ @@ -340,14 +329,28 @@ struct vector_alloc_holder } } - std::pair - allocation_command(boost::container::allocation_type command, - size_type limit_size, - size_type preferred_size, - size_type &received_size, const pointer &reuse = pointer()) + pointer allocation_command(boost::container::allocation_type command, + size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) { - return allocator_version_traits::allocation_command - (this->alloc(), command, limit_size, preferred_size, received_size, reuse); + typedef typename container_detail::version::type alloc_version; + return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse); + } + + bool try_expand_fwd(size_type at_least) + { + //There is not enough memory, try to expand the old one + const size_type new_cap = this->capacity() + at_least; + size_type real_cap = new_cap; + pointer reuse = this->start(); + bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse); + //Check for forward expansion + if(success){ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->capacity(real_cap); + } + return success; } size_type next_capacity(size_type additional_objects) const @@ -378,28 +381,61 @@ struct vector_alloc_holder x.m_size = x.m_capacity = 0; } - A &alloc() BOOST_CONTAINER_NOEXCEPT + Allocator &alloc() BOOST_CONTAINER_NOEXCEPT { return *this; } - const A &alloc() const BOOST_CONTAINER_NOEXCEPT + const Allocator &alloc() const BOOST_CONTAINER_NOEXCEPT { return *this; } const pointer &start() const BOOST_CONTAINER_NOEXCEPT { return m_start; } const size_type &capacity() const BOOST_CONTAINER_NOEXCEPT { return m_capacity; } void start(const pointer &p) BOOST_CONTAINER_NOEXCEPT { m_start = p; } void capacity(const size_type &c) BOOST_CONTAINER_NOEXCEPT { m_capacity = c; } + + private: + void priv_first_allocation(size_type cap) + { + if(cap){ + pointer reuse = 0; + m_start = this->allocation_command(allocate_new, cap, cap, reuse); + m_capacity = cap; + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + } + } + + pointer priv_allocation_command(version_1, boost::container::allocation_type command, + size_type , + size_type &prefer_in_recvd_out_size, + pointer &reuse) + { + (void)command; + BOOST_ASSERT( (command & allocate_new)); + BOOST_ASSERT(!(command & nothrow_allocation)); + reuse = pointer(); + return this->alloc().allocate(prefer_in_recvd_out_size); + } + + pointer priv_allocation_command(version_2, boost::container::allocation_type command, + size_type limit_size, + size_type &prefer_in_recvd_out_size, + pointer &reuse) + { + return this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); + } }; //!This struct deallocates and allocated memory -template -struct vector_alloc_holder > - : public A +template +struct vector_alloc_holder + : public Allocator { private: BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) public: - typedef boost::container::allocator_traits allocator_traits_type; + typedef boost::container::allocator_traits allocator_traits_type; typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::value_type value_type; @@ -409,37 +445,37 @@ struct vector_alloc_holder > //Constructor, does not throw vector_alloc_holder() - BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value) - : A(), m_size() + BOOST_CONTAINER_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible::value) + : Allocator(), m_size() {} //Constructor, does not throw template explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT - : A(boost::forward(a)), m_size() + : Allocator(boost::forward(a)), m_size() {} //Constructor, does not throw template vector_alloc_holder(uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) - : A(boost::forward(a)) + : Allocator(boost::forward(a)) , m_size(initial_size) //Size is initialized here... { //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor - this->first_allocation(initial_size); + this->priv_first_allocation(initial_size); } //Constructor, does not throw vector_alloc_holder(uninitialized_size_t, size_type initial_size) - : A() + : Allocator() , m_size(initial_size) //Size is initialized here... { //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor - this->first_allocation(initial_size); + this->priv_first_allocation(initial_size); } vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) - : A(BOOST_MOVE_BASE(A, holder)) + : Allocator(BOOST_MOVE_BASE(Allocator, holder)) , m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this { ::boost::container::uninitialized_move_alloc_n @@ -448,26 +484,23 @@ struct vector_alloc_holder > template vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder BOOST_RV_REF_END holder) - : A() + : Allocator() , m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort { //Different allocator type so we must check we have enough storage const size_type n = holder.m_size; - this->first_allocation(n); + this->priv_first_allocation(n); ::boost::container::uninitialized_move_alloc_n (this->alloc(), container_detail::to_raw_pointer(holder.start()), n, container_detail::to_raw_pointer(this->start())); } - void first_allocation(size_type cap) + void priv_first_allocation(size_type cap) { - if(cap > A::internal_capacity){ + if(cap > Allocator::internal_capacity){ throw_bad_alloc(); } } - void first_allocation_same_allocator_type(size_type) BOOST_CONTAINER_NOEXCEPT - {} - //Destructor ~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT {} @@ -480,7 +513,7 @@ struct vector_alloc_holder > template void swap(vector_alloc_holder &x) { - if(this->m_size > OtherAllocator::internal_capacity || x.m_size > A::internal_capacity){ + if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){ throw_bad_alloc(); } this->priv_swap_members_impl(x); @@ -491,14 +524,17 @@ struct vector_alloc_holder > throw_bad_alloc(); } - A &alloc() BOOST_CONTAINER_NOEXCEPT + Allocator &alloc() BOOST_CONTAINER_NOEXCEPT { return *this; } - const A &alloc() const BOOST_CONTAINER_NOEXCEPT + const Allocator &alloc() const BOOST_CONTAINER_NOEXCEPT { return *this; } - pointer start() const BOOST_CONTAINER_NOEXCEPT { return A::internal_storage(); } - size_type capacity() const BOOST_CONTAINER_NOEXCEPT { return A::internal_capacity; } + bool try_expand_fwd(size_type at_least) + { return !at_least; } + + pointer start() const BOOST_CONTAINER_NOEXCEPT { return Allocator::internal_storage(); } + size_type capacity() const BOOST_CONTAINER_NOEXCEPT { return Allocator::internal_capacity; } size_type m_size; private: @@ -506,7 +542,7 @@ struct vector_alloc_holder > template void priv_swap_members_impl(vector_alloc_holder &x) { - const size_type MaxTmpStorage = sizeof(value_type)*A::internal_capacity; + const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity; value_type *const first_this = container_detail::to_raw_pointer(this->start()); value_type *const first_x = container_detail::to_raw_pointer(x.start()); @@ -530,21 +566,20 @@ struct vector_alloc_holder > //! elements in a vector may vary dynamically; memory management is automatic. //! //! \tparam T The type of object that is stored in the vector -//! \tparam A The allocator used for all internal memory management -template ) > +//! \tparam Allocator The allocator used for all internal memory management +template ) > class vector { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef typename container_detail::version::type alloc_version; + typedef typename container_detail::version::type alloc_version; boost::container::container_detail::vector_alloc_holder - m_holder; - typedef allocator_traits allocator_traits_type; + m_holder; + typedef allocator_traits allocator_traits_type; template friend class vector; - typedef typename ::boost::container::allocator_traits - ::pointer pointer_impl; + typedef typename allocator_traits_type::pointer pointer_impl; typedef container_detail::vec_iterator iterator_impl; typedef container_detail::vec_iterator const_iterator_impl; @@ -557,33 +592,28 @@ class vector ////////////////////////////////////////////// typedef T value_type; - typedef typename ::boost::container::allocator_traits::pointer pointer; - typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits::reference reference; - typedef typename ::boost::container::allocator_traits::const_reference const_reference; - typedef typename ::boost::container::allocator_traits::size_type size_type; - typedef typename ::boost::container::allocator_traits::difference_type difference_type; - typedef A allocator_type; - typedef A stored_allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef Allocator stored_allocator_type; #if defined BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER - typedef BOOST_CONTAINER_IMPDEF(pointer) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator; + typedef BOOST_MOVE_IMPDEF(pointer) iterator; + typedef BOOST_MOVE_IMPDEF(const_pointer) const_iterator; #else - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_MOVE_IMPDEF(iterator_impl) iterator; + typedef BOOST_MOVE_IMPDEF(const_iterator_impl) const_iterator; #endif - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_MOVE_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(vector) - typedef container_detail::vector_value_traits value_traits; - - typedef container_detail::integral_constant allocator_v0; - typedef container_detail::integral_constant allocator_v1; - typedef container_detail::integral_constant allocator_v2; - + typedef container_detail::vector_value_traits value_traits; typedef constant_iterator cvalue_iterator; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -600,7 +630,7 @@ class vector //! //! Complexity: Constant. vector() - BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value) + BOOST_CONTAINER_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible::value) : m_holder() {} @@ -609,7 +639,7 @@ class vector //! Throws: Nothing //! //! Complexity: Constant. - explicit vector(const A& a) BOOST_CONTAINER_NOEXCEPT + explicit vector(const Allocator& a) BOOST_CONTAINER_NOEXCEPT : m_holder(a) {} @@ -728,7 +758,7 @@ class vector , x.size(), container_detail::to_raw_pointer(this->m_holder.start())); } -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Constructs a vector that will use a copy of allocator a //! and inserts a copy of the range [il.begin(), il.last()) in the vector //! @@ -741,8 +771,7 @@ class vector { insert(cend(), il.begin(), il.end()); } -#endif - + #endif //! Effects: Move constructor. Moves x's resources to *this. //! @@ -799,17 +828,16 @@ class vector //! //! Complexity: Constant if a == x.get_allocator(), linear otherwise. vector(BOOST_RV_REF(vector) x, const allocator_type &a) - : m_holder(container_detail::uninitialized_size, a, x.size()) + : m_holder(container_detail::uninitialized_size, a, x.m_holder.alloc() == a ? 0 : x.size()) { - #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS - this->num_alloc += x.size() != 0; - #endif if(x.m_holder.alloc() == a){ this->m_holder.move_from_empty(x.m_holder); } else{ const size_type n = x.size(); - this->m_holder.first_allocation_same_allocator_type(n); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif ::boost::container::uninitialized_move_alloc_n_source ( this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start()) , n, container_detail::to_raw_pointer(this->m_holder.start())); @@ -845,7 +873,7 @@ class vector return *this; } -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Make *this container contains elements from il. //! //! Complexity: Linear to the range [il.begin(), il.end()). @@ -854,7 +882,7 @@ class vector assign(il.begin(), il.end()); return *this; } -#endif + #endif //! Effects: Move assignment. All x's values are transferred to *this. //! @@ -928,10 +956,10 @@ class vector //! Complexity: Linear to n. template void assign(InIt first, InIt last - BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I typename container_detail::enable_if_c - < !container_detail::is_convertible::value && + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c + < !container_detail::is_convertible::value && ( container_detail::is_input_iterator::value || - container_detail::is_same::value ) + container_detail::is_same::value ) >::type * = 0) ) { //Overwrite all elements we can from [first, last) @@ -953,7 +981,7 @@ class vector } } -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Assigns the the range [il.begin(), il.end()) to *this. //! //! Throws: If memory allocation throws or @@ -963,7 +991,7 @@ class vector { assign(il.begin(), il.end()); } -#endif + #endif //! Effects: Assigns the the range [first, last) to *this. //! @@ -973,10 +1001,10 @@ class vector //! Complexity: Linear to n. template void assign(FwdIt first, FwdIt last - BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I typename container_detail::enable_if_c - < !container_detail::is_convertible::value && + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c + < !container_detail::is_convertible::value && ( !container_detail::is_input_iterator::value && - !container_detail::is_same::value ) + !container_detail::is_same::value ) >::type * = 0) ) { @@ -986,9 +1014,9 @@ class vector const size_type old_capacity = this->capacity(); if(input_sz > old_capacity){ //If input range is too big, we need to reallocate size_type real_cap = 0; - std::pair ret = - this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, input_sz, real_cap, this->m_holder.start()); - if(!ret.second){ //New allocation, just emplace new values + pointer reuse(this->m_holder.start()); + pointer const ret(this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, real_cap = input_sz, reuse)); + if(!reuse){ //New allocation, just emplace new values #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_alloc; #endif @@ -997,7 +1025,7 @@ class vector this->priv_destroy_all(); this->m_holder.alloc().deallocate(old_p, old_capacity); } - this->m_holder.start(ret.first); + this->m_holder.start(ret); this->m_holder.capacity(real_cap); this->m_holder.m_size = 0; this->priv_uninitialized_construct_at_end(first, last); @@ -1250,7 +1278,7 @@ class vector void reserve(size_type new_cap) { if (this->capacity() < new_cap){ - this->priv_reserve(new_cap, alloc_version()); + this->priv_reserve_no_capacity(new_cap, alloc_version()); } } @@ -1476,7 +1504,7 @@ class vector ++this->m_holder.m_size; } else{ - typedef container_detail::insert_emplace_proxy type; + typedef container_detail::insert_emplace_proxy type; this->priv_forward_range_insert_no_capacity (this->back_ptr(), 1, type(::boost::forward(args)...), alloc_version()); } @@ -1485,8 +1513,7 @@ class vector //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the end of the vector. //! - //! Throws: If memory allocation throws or the in-place constructor throws or - //! T's copy/move constructor throws. + //! Throws: If the in-place constructor throws. //! //! Complexity: Constant time. //! @@ -1494,7 +1521,7 @@ class vector template bool stable_emplace_back(BOOST_FWD_REF(Args)...args) { - const bool is_room_enough = this->room_enough(); + const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u)); if (BOOST_LIKELY(is_room_enough)){ //There is more memory, just construct a new object at the end allocator_traits_type::construct(this->m_holder.alloc(), this->back_raw(), ::boost::forward(args)...); @@ -1517,236 +1544,52 @@ class vector iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args) { //Just call more general insert(pos, size, value) and return iterator - typedef container_detail::insert_emplace_proxy type; + typedef container_detail::insert_emplace_proxy type; return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1 - , type(::boost::forward(args)...), alloc_version()); + , type(::boost::forward(args)...)); } - #else + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - //0 arg - void emplace_back() - { - if (BOOST_LIKELY(this->room_enough())){ - allocator_traits_type::construct (this->m_holder.alloc(), this->back_raw()); - ++this->m_holder.m_size; - } - else{ - typedef container_detail::insert_emplace_proxy_arg0 type; - this->priv_forward_range_insert_no_capacity - ( this->back_ptr(), 1, type(), alloc_version()); - } - } + #define BOOST_CONTAINER_VECTOR_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + void emplace_back(BOOST_MOVE_UREF##N)\ + {\ + if (BOOST_LIKELY(this->room_enough())){\ + allocator_traits_type::construct (this->m_holder.alloc()\ + , this->back_raw() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + ++this->m_holder.m_size;\ + }\ + else{\ + typedef container_detail::insert_emplace_proxy_arg##N type;\ + this->priv_forward_range_insert_no_capacity\ + ( this->back_ptr(), 1, type(BOOST_MOVE_FWD##N), alloc_version());\ + }\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + bool stable_emplace_back(BOOST_MOVE_UREF##N)\ + {\ + const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));\ + if (BOOST_LIKELY(is_room_enough)){\ + allocator_traits_type::construct (this->m_holder.alloc()\ + , this->back_raw() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + ++this->m_holder.m_size;\ + }\ + return is_room_enough;\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + typedef container_detail::insert_emplace_proxy_arg##N type;\ + return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), 1, type(BOOST_MOVE_FWD##N));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE) + #undef BOOST_CONTAINER_VECTOR_EMPLACE_CODE - bool stable_emplace_back() - { - const bool is_room_enough = this->room_enough(); - if (BOOST_LIKELY(is_room_enough)){ - allocator_traits_type::construct (this->m_holder.alloc(), this->back_raw()); - ++this->m_holder.m_size; - } - return is_room_enough; - } - - iterator emplace(const_iterator pos) - { - typedef container_detail::insert_emplace_proxy_arg0 type; - return this->priv_forward_range_insert - ( vector_iterator_get_ptr(pos), 1 - , type(), alloc_version()); - } - - //1 arg - template - void emplace_back(BOOST_FWD_REF(P0) p0) - { - if (BOOST_LIKELY(this->room_enough())){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0)); - ++this->m_holder.m_size; - } - else{ - typedef container_detail::insert_emplace_proxy_arg1 type; - this->priv_forward_range_insert_no_capacity - ( this->back_ptr(), 1 - , type(::boost::forward(p0)), alloc_version()); - } - } - - template - bool stable_emplace_back(BOOST_FWD_REF(P0) p0) - { - const bool is_room_enough = this->room_enough(); - if (BOOST_LIKELY(is_room_enough)){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0)); - ++this->m_holder.m_size; - } - return is_room_enough; - } - - template - iterator emplace(const_iterator pos, BOOST_FWD_REF(P0) p0) - { - typedef container_detail::insert_emplace_proxy_arg1 type; - return this->priv_forward_range_insert - ( vector_iterator_get_ptr(pos), 1 - , type(::boost::forward(p0)), alloc_version()); - } - - //2 arg - template - void emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1) - { - if (BOOST_LIKELY(this->room_enough())){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1)); - ++this->m_holder.m_size; - } - else{ - typedef container_detail::insert_emplace_proxy_arg2 type; - this->priv_forward_range_insert_no_capacity - ( this->back_ptr(), 1 - , type(::boost::forward(p0),::boost::forward(p1)), alloc_version()); - } - } - - template - bool stable_emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1) - { - const bool is_room_enough = this->room_enough(); - if (BOOST_LIKELY(is_room_enough)){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1)); - ++this->m_holder.m_size; - } - return is_room_enough; - } - - template - iterator emplace(const_iterator pos, BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1) - { - typedef container_detail::insert_emplace_proxy_arg2 type; - return this->priv_forward_range_insert - ( vector_iterator_get_ptr(pos), 1 - , type(::boost::forward(p0), ::boost::forward(p1)), alloc_version()); - } - - //3 arg - template - void emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2) - { - if (BOOST_LIKELY(this->room_enough())){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1), ::boost::forward(p2)); - ++this->m_holder.m_size; - } - else{ - typedef container_detail::insert_emplace_proxy_arg3 type; - this->priv_forward_range_insert_no_capacity - ( this->back_ptr(), 1 - , type(::boost::forward(p0),::boost::forward(p1),::boost::forward(p2)), alloc_version()); - } - } - - template - bool stable_emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2) - { - const bool is_room_enough = this->room_enough(); - if (BOOST_LIKELY(is_room_enough)){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1),::boost::forward(p2)); - ++this->m_holder.m_size; - } - return is_room_enough; - } - - template - iterator emplace(const_iterator pos, BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2) - { - typedef container_detail::insert_emplace_proxy_arg3 type; - return this->priv_forward_range_insert - ( vector_iterator_get_ptr(pos), 1 - , type(::boost::forward(p0), ::boost::forward(p1),::boost::forward(p2)), alloc_version()); - } - - //4 arg - template - void emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2, BOOST_FWD_REF(P3) p3) - { - if (BOOST_LIKELY(this->room_enough())){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1), ::boost::forward(p2), ::boost::forward(p3)); - ++this->m_holder.m_size; - } - else{ - typedef container_detail::insert_emplace_proxy_arg4 type; - this->priv_forward_range_insert_no_capacity - ( this->back_ptr(), 1 - , type(::boost::forward(p0),::boost::forward(p1),::boost::forward(p2),::boost::forward(p3)), alloc_version()); - } - } - - template - bool stable_emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2, BOOST_FWD_REF(P3) p3) - { - const bool is_room_enough = this->room_enough(); - if (BOOST_LIKELY(is_room_enough)){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1), ::boost::forward(p2), ::boost::forward(p3)); - ++this->m_holder.m_size; - } - return is_room_enough; - } - - template - iterator emplace(const_iterator pos, BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2, BOOST_FWD_REF(P3) p3) - { - typedef container_detail::insert_emplace_proxy_arg4 type; - return this->priv_forward_range_insert - ( vector_iterator_get_ptr(pos), 1 - , type(::boost::forward(p0), ::boost::forward(p1),::boost::forward(p2),::boost::forward(p3)), alloc_version()); - } - - //5 arg - template - void emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2, BOOST_FWD_REF(P3) p3, BOOST_FWD_REF(P4) p4) - { - if (BOOST_LIKELY(this->room_enough())){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1), ::boost::forward(p2), ::boost::forward(p3), ::boost::forward(p4)); - ++this->m_holder.m_size; - } - else{ - typedef container_detail::insert_emplace_proxy_arg5 type; - this->priv_forward_range_insert_no_capacity - ( this->back_ptr(), 1 - , type(::boost::forward(p0),::boost::forward(p1),::boost::forward(p2),::boost::forward(p3),::boost::forward(p4)), alloc_version()); - } - } - - template - bool stable_emplace_back(BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2, BOOST_FWD_REF(P3) p3, BOOST_FWD_REF(P4) p4) - { - const bool is_room_enough = this->room_enough(); - if (BOOST_LIKELY(is_room_enough)){ - allocator_traits_type::construct (this->m_holder.alloc() - , this->back_raw(), ::boost::forward(p0), ::boost::forward(p1), ::boost::forward(p2), ::boost::forward(p3)); - ++this->m_holder.m_size; - } - return is_room_enough; - } - - template - iterator emplace(const_iterator pos, BOOST_FWD_REF(P0) p0, BOOST_FWD_REF(P1) p1, BOOST_FWD_REF(P2) p2, BOOST_FWD_REF(P3) p3, BOOST_FWD_REF(P4) p4) - { - typedef container_detail::insert_emplace_proxy_arg5 type; - return this->priv_forward_range_insert - ( vector_iterator_get_ptr(pos), 1 - , type(::boost::forward(p0),::boost::forward(p1),::boost::forward(p2),::boost::forward(p3),::boost::forward(p4)), alloc_version()); - } - - #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #endif #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts a copy of x at the end of the vector. @@ -1804,8 +1647,8 @@ class vector //! Complexity: Linear to n. iterator insert(const_iterator p, size_type n, const T& x) { - container_detail::insert_n_copies_proxy proxy(x); - return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy, alloc_version()); + container_detail::insert_n_copies_proxy proxy(x); + return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy); } //! Requires: p must be a valid iterator of *this. @@ -1820,8 +1663,8 @@ class vector //! Complexity: Linear to boost::container::iterator_distance [first, last). template iterator insert(const_iterator pos, InIt first, InIt last - BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I typename container_detail::enable_if_c - < !container_detail::is_convertible::value + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c + < !container_detail::is_convertible::value && container_detail::is_input_iterator::value >::type * = 0) ) @@ -1844,8 +1687,8 @@ class vector >::type * = 0 ) { - container_detail::insert_range_proxy proxy(first); - return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy, alloc_version()); + container_detail::insert_range_proxy proxy(first); + return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy); } #endif @@ -1871,12 +1714,12 @@ class vector BOOST_ASSERT(container_detail::is_input_iterator::value || num == static_cast(boost::container::iterator_distance(first, last))); (void)last; - container_detail::insert_range_proxy proxy(first); - return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy, alloc_version()); + container_detail::insert_range_proxy proxy(first); + return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy); } #endif -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Requires: position must be a valid iterator of *this. //! //! Effects: Insert a copy of the [il.begin(), il.end()) range before position. @@ -1888,7 +1731,7 @@ class vector { return insert(position, il.begin(), il.end()); } -#endif + #endif //! Effects: Removes the last element from the vector. //! @@ -1912,7 +1755,7 @@ class vector const pointer p = vector_iterator_get_ptr(position); T *const pos_ptr = container_detail::to_raw_pointer(p); T *const beg_ptr = container_detail::to_raw_pointer(this->m_holder.start()); - T *const new_end_ptr = ::boost::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr); + T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr); //Move elements forward and destroy last this->priv_destroy_last(pos_ptr == new_end_ptr); return iterator(p); @@ -1930,7 +1773,7 @@ class vector T* const old_end_ptr = this->back_raw(); T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first)); T* const last_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(last)); - T* const ptr = container_detail::to_raw_pointer(boost::move(last_ptr, old_end_ptr, first_ptr)); + T* const ptr = container_detail::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr)); this->priv_destroy_last_n(old_end_ptr - ptr, last_ptr == old_end_ptr); } return iterator(vector_iterator_get_ptr(first)); @@ -1941,9 +1784,9 @@ class vector //! Throws: Nothing. //! //! Complexity: Constant. - void swap(vector& x) BOOST_CONTAINER_NOEXCEPT_IF((!container_detail::is_version::value)) + void swap(vector& x) BOOST_CONTAINER_NOEXCEPT_IF((!container_detail::is_version::value)) { - //Just swap internals in case of !allocator_v0. Otherwise, deep swap + //Just swap internals in case of !version_0. Otherwise, deep swap this->m_holder.swap(x.m_holder); //And now the allocator container_detail::bool_ flag; @@ -2039,24 +1882,8 @@ class vector //! Note: Non-standard extension. bool stable_reserve(size_type new_cap) { - const bool is_room_enough = this->capacity() < new_cap; - if(!is_room_enough && alloc_version::value < 2){ - return false; - } - else{ - //There is not enough memory, try to expand the old one - size_type real_cap = 0; - std::pair ret = this->m_holder.allocation_command - (expand_fwd, new_cap, new_cap, real_cap, this->m_holder.start()); - //Check for forward expansion - if(ret.second){ - #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS - ++this->num_expand_fwd; - #endif - this->m_holder.capacity(real_cap); - } - return ret.second; - } + const size_type cp = this->capacity(); + return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(new_cap - cp)); } //Absolutely experimental. This function might change, disappear or simply crash! @@ -2224,37 +2051,35 @@ class vector , container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size)); } - void priv_reserve(size_type, allocator_v0) + void priv_reserve_no_capacity(size_type, version_0) { throw_bad_alloc(); } - container_detail::insert_range_proxy, T*> priv_dummy_empty_proxy() + container_detail::insert_range_proxy, T*> priv_dummy_empty_proxy() { - return container_detail::insert_range_proxy, T*> + return container_detail::insert_range_proxy, T*> (::boost::make_move_iterator((T *)0)); } - void priv_reserve(size_type new_cap, allocator_v1) + void priv_reserve_no_capacity(size_type new_cap, version_1) { //There is not enough memory, allocate a new buffer pointer p = this->m_holder.allocate(new_cap); //We will reuse insert code, so create a dummy input iterator this->priv_forward_range_insert_new_allocation - ( container_detail::to_raw_pointer(p), new_cap - , this->back_raw() - , 0, this->priv_dummy_empty_proxy()); + ( container_detail::to_raw_pointer(p), new_cap, this->back_raw(), 0, this->priv_dummy_empty_proxy()); } - void priv_reserve(size_type new_cap, allocator_v2) + void priv_reserve_no_capacity(size_type new_cap, version_2) { //There is not enough memory, allocate a new //buffer or expand the old one. bool same_buffer_start; size_type real_cap = 0; - std::pair ret = this->m_holder.allocation_command - (allocate_new | expand_fwd | expand_bwd, new_cap, new_cap, real_cap, this->m_holder.start()); + pointer reuse = 0; + pointer const ret(this->m_holder.allocation_command(allocate_new | expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse)); //Check for forward expansion - same_buffer_start = ret.second && this->m_holder.start() == ret.first; + same_buffer_start = reuse && this->m_holder.start() == ret; if(same_buffer_start){ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_expand_fwd; @@ -2262,9 +2087,9 @@ class vector this->m_holder.capacity(real_cap); } else{ //If there is no forward expansion, move objects, we will reuse insertion code - T * const new_mem = container_detail::to_raw_pointer(ret.first); + T * const new_mem = container_detail::to_raw_pointer(ret); T * const ins_pos = this->back_raw(); - if(ret.second){ //Backwards (and possibly forward) expansion + if(reuse){ //Backwards (and possibly forward) expansion #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_expand_bwd; #endif @@ -2340,15 +2165,14 @@ class vector iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x) { return this->priv_forward_range_insert - ( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy - (::boost::forward(x)), alloc_version()); + ( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy(::boost::forward(x))); } - container_detail::insert_copy_proxy priv_single_insert_proxy(const T &x) - { return container_detail::insert_copy_proxy (x); } + container_detail::insert_copy_proxy priv_single_insert_proxy(const T &x) + { return container_detail::insert_copy_proxy (x); } - container_detail::insert_move_proxy priv_single_insert_proxy(BOOST_RV_REF(T) x) - { return container_detail::insert_move_proxy (x); } + container_detail::insert_move_proxy priv_single_insert_proxy(BOOST_RV_REF(T) x) + { return container_detail::insert_move_proxy (x); } template void priv_push_back(BOOST_FWD_REF(U) u) @@ -2368,14 +2192,14 @@ class vector } } - container_detail::insert_n_copies_proxy priv_resize_proxy(const T &x) - { return container_detail::insert_n_copies_proxy(x); } + container_detail::insert_n_copies_proxy priv_resize_proxy(const T &x) + { return container_detail::insert_n_copies_proxy(x); } - container_detail::insert_default_initialized_n_proxy priv_resize_proxy(default_init_t) - { return container_detail::insert_default_initialized_n_proxy(); } + container_detail::insert_default_initialized_n_proxy priv_resize_proxy(default_init_t) + { return container_detail::insert_default_initialized_n_proxy(); } - container_detail::insert_value_initialized_n_proxy priv_resize_proxy(value_init_t) - { return container_detail::insert_value_initialized_n_proxy(); } + container_detail::insert_value_initialized_n_proxy priv_resize_proxy(value_init_t) + { return container_detail::insert_value_initialized_n_proxy(); } template void priv_resize(size_type new_size, const U& u) @@ -2391,10 +2215,10 @@ class vector } } - void priv_shrink_to_fit(allocator_v0) BOOST_CONTAINER_NOEXCEPT + void priv_shrink_to_fit(version_0) BOOST_CONTAINER_NOEXCEPT {} - void priv_shrink_to_fit(allocator_v1) + void priv_shrink_to_fit(version_1) { const size_type cp = this->m_holder.capacity(); if(cp){ @@ -2420,7 +2244,7 @@ class vector } } - void priv_shrink_to_fit(allocator_v2) BOOST_CONTAINER_NOEXCEPT + void priv_shrink_to_fit(version_2) BOOST_CONTAINER_NOEXCEPT { const size_type cp = this->m_holder.capacity(); if(cp){ @@ -2431,10 +2255,10 @@ class vector this->m_holder.m_capacity = 0; } else{ - size_type received_size; + size_type received_size = sz; + pointer reuse(this->m_holder.start()); if(this->m_holder.allocation_command - ( shrink_in_place | nothrow_allocation - , cp, sz, received_size, this->m_holder.start()).first){ + (shrink_in_place | nothrow_allocation, cp, received_size, reuse)){ this->m_holder.capacity(received_size); #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_shrink; @@ -2446,7 +2270,7 @@ class vector template iterator priv_forward_range_insert_no_capacity - (const pointer &pos, const size_type, const InsertionProxy , allocator_v0) + (const pointer &pos, const size_type, const InsertionProxy , version_0) { throw_bad_alloc(); return iterator(pos); @@ -2454,7 +2278,7 @@ class vector template iterator priv_forward_range_insert_no_capacity - (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1) + (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_1) { //Check if we have enough memory or try to expand current memory const size_type n_pos = pos - this->m_holder.start(); @@ -2472,23 +2296,23 @@ class vector template iterator priv_forward_range_insert_no_capacity - (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2) + (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2) { //Check if we have enough memory or try to expand current memory T *const raw_pos = container_detail::to_raw_pointer(pos); const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start()); - size_type real_cap = 0; //There is not enough memory, allocate a new //buffer or expand the old one. - std::pair ret = (this->m_holder.allocation_command - (allocate_new | expand_fwd | expand_bwd, - this->m_holder.m_size + n, this->m_holder.next_capacity(n), real_cap, this->m_holder.start())); + size_type real_cap = this->m_holder.next_capacity(n); + pointer reuse(this->m_holder.start()); + pointer const ret (this->m_holder.allocation_command + (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse)); //Buffer reallocated - if(ret.second){ + if(reuse){ //Forward expansion, delay insertion - if(this->m_holder.start() == ret.first){ + if(this->m_holder.start() == ret){ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_expand_fwd; #endif @@ -2502,8 +2326,7 @@ class vector ++this->num_expand_bwd; #endif this->priv_forward_range_insert_expand_backwards - ( container_detail::to_raw_pointer(ret.first) - , real_cap, raw_pos, n, insert_range_proxy); + (container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); } } //New buffer @@ -2512,8 +2335,7 @@ class vector ++this->num_alloc; #endif this->priv_forward_range_insert_new_allocation - ( container_detail::to_raw_pointer(ret.first) - , real_cap, raw_pos, n, insert_range_proxy); + ( container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); } return iterator(this->m_holder.start() + n_pos); @@ -2521,42 +2343,7 @@ class vector template iterator priv_forward_range_insert - (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v0) - { - //Check if we have enough memory or try to expand current memory - const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size; - - if (n > remaining){ - //This will trigger an error - throw_bad_alloc(); - } - const size_type n_pos = pos - this->m_holder.start(); - T *const raw_pos = container_detail::to_raw_pointer(pos); - this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy); - return iterator(this->m_holder.start() + n_pos); - } - - template - iterator priv_forward_range_insert - (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1) - { - //Check if we have enough memory or try to expand current memory - const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size; - T *const raw_pos = container_detail::to_raw_pointer(pos); - - if (n <= remaining){ - const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start()); - this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy); - return iterator(this->m_holder.start() + n_pos); - } - else{ - return this->priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version()); - } - } - - template - iterator priv_forward_range_insert - (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2) + (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy) { BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size); //Check if we have enough memory or try to expand current memory @@ -2577,7 +2364,7 @@ class vector template iterator priv_forward_range_insert_at_end - (const size_type n, const InsertionProxy insert_range_proxy, allocator_v0) + (const size_type n, const InsertionProxy insert_range_proxy, version_0) { //Check if we have enough memory or try to expand current memory const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size; @@ -2590,18 +2377,11 @@ class vector return this->end(); } - template + template iterator priv_forward_range_insert_at_end - (const size_type n, const InsertionProxy insert_range_proxy, allocator_v1) + (const size_type n, const InsertionProxy insert_range_proxy, AllocVersion) { - return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy, allocator_v1()); - } - - template - iterator priv_forward_range_insert_at_end - (const size_type n, const InsertionProxy insert_range_proxy, allocator_v2) - { - return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy, allocator_v2()); + return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy); } //Absolutely experimental. This function might change, disappear or simply crash! @@ -2732,7 +2512,7 @@ class vector //Case A: if((last_pos + shift_count) <= limit_pos){ //All move assigned - boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count); + boost::container::move_backward(first_ptr, last_ptr, last_ptr + shift_count); } //Case B: else if((first_pos + shift_count) >= limit_pos){ @@ -2748,7 +2528,7 @@ class vector T* const boundary_ptr = limit_ptr - shift_count; ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), boundary_ptr, last_ptr, limit_ptr); //The rest is move assigned - boost::move_backward(first_ptr, boundary_ptr, limit_ptr); + boost::container::move_backward(first_ptr, boundary_ptr, limit_ptr); } return hole_size; } @@ -2782,7 +2562,7 @@ class vector (this->m_holder.alloc(), old_finish - n, old_finish, old_finish); this->m_holder.m_size += n; //Copy previous to last objects to the initialized end - boost::move_backward(pos, old_finish - n, old_finish); + boost::container::move_backward(pos, old_finish - n, old_finish); //Insert new objects in the pos insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n); } @@ -2933,7 +2713,7 @@ class vector old_values_destroyer.shrink_forward(new_size-s_before); this->m_holder.m_size = new_size; //Now move remaining last objects in the old buffer begin - ::boost::move(pos + raw_gap, old_finish, old_start); + ::boost::container::move(pos + raw_gap, old_finish, old_start); //Once moved, avoid calling the destructors if trivial after move if(value_traits::trivial_dctr_after_move){ old_values_destroyer.release(); @@ -3017,14 +2797,14 @@ class vector } this->m_holder.m_size = old_size + new_1st_range; //Now copy the second part of old_begin overwriting itself - T *const next = ::boost::move(old_start + s_before, pos, old_start); + T *const next = ::boost::container::move(old_start + s_before, pos, old_start); //Now copy the new_beg elements insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, new_1st_range); //If there is no after work and the last old part needs to be moved to front, do it if(!do_after && (n != s_before)){ //Now displace old_end elements - ::boost::move(pos, old_finish, next + new_1st_range); + ::boost::container::move(pos, old_finish, next + new_1st_range); } } else { @@ -3074,7 +2854,7 @@ class vector insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, rest_new); T* const move_start = old_start + rest_new; //Displace old_end - T* const move_end = ::boost::move(pos, old_finish, move_start); + T* const move_end = ::boost::container::move(pos, old_finish, move_start); //Destroy remaining moved elements from old_end except if they //have trivial destructor after being moved size_type n_destroy = s_before - n; @@ -3126,7 +2906,7 @@ class vector (this->m_holder.alloc(), finish_n, old_finish, old_finish); this->m_holder.m_size += n_after; //Displace the rest of old_end to the new position - boost::move_backward(pos, finish_n, old_finish); + boost::container::move_backward(pos, finish_n, old_finish); //Now overwrite with new_end //The new_end part is [first + (n - n_after), last) insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n_after); @@ -3192,30 +2972,18 @@ class vector namespace boost { -/* //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template -struct has_trivial_destructor_after_move > - : public ::boost::has_trivial_destructor_after_move -{}; -*/ +template +struct has_trivial_destructor_after_move > +{ + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; + } -//#define BOOST_CONTAINER_PUT_SWAP_OVERLOAD_IN_NAMESPACE_STD - -#ifdef BOOST_CONTAINER_PUT_SWAP_OVERLOAD_IN_NAMESPACE_STD - -namespace std { - -template -inline void swap(boost::container::vector& x, boost::container::vector& y) -{ x.swap(y); } - -} //namespace std { - -#endif - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #include diff --git a/proj/vc7ide/alloc_lib.vcproj b/proj/vc7ide/alloc_lib.vcproj index 497a4b8..eec4f59 100644 --- a/proj/vc7ide/alloc_lib.vcproj +++ b/proj/vc7ide/alloc_lib.vcproj @@ -107,76 +107,39 @@ Name="Header Files" Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> - - - - - - + RelativePath="..\..\src\dlmalloc_2_8_6.c"> + + + + + + + RelativePath="..\..\src\dlmalloc_ext_2_8_6.c"> + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/container.vcproj b/proj/vc7ide/container.vcproj index 3b5361f..80f03a5 100644 --- a/proj/vc7ide/container.vcproj +++ b/proj/vc7ide/container.vcproj @@ -125,6 +125,9 @@ + + @@ -170,12 +173,18 @@ + + + + @@ -206,6 +215,9 @@ + + @@ -221,15 +233,15 @@ + + - - @@ -239,6 +251,9 @@ + + @@ -257,18 +272,21 @@ - - + + + + @@ -352,7 +370,7 @@ RelativePath="..\..\test\forward_to_input_iterator.hpp"> + RelativePath="..\..\test\heap_version_1.hpp"> diff --git a/proj/vc7ide/list_test.vcproj b/proj/vc7ide/list_test.vcproj index 3ebaf1b..1aec531 100644 --- a/proj/vc7ide/list_test.vcproj +++ b/proj/vc7ide/list_test.vcproj @@ -21,7 +21,6 @@ Optimization="0" AdditionalIncludeDirectories="../../../.." PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" - GeneratePreprocessedFile="0" KeepComments="FALSE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" diff --git a/proj/vc7ide/scoped_allocator_adaptor.vcproj b/proj/vc7ide/scoped_allocator_adaptor.vcproj index 451d6dd..e3ad785 100644 --- a/proj/vc7ide/scoped_allocator_adaptor.vcproj +++ b/proj/vc7ide/scoped_allocator_adaptor.vcproj @@ -1,136 +1,134 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/throw_exception_test.vcproj b/proj/vc7ide/throw_exception_test.vcproj index 88d3de3..8522325 100644 --- a/proj/vc7ide/throw_exception_test.vcproj +++ b/proj/vc7ide/throw_exception_test.vcproj @@ -1,136 +1,136 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/vector_test.vcproj b/proj/vc7ide/vector_test.vcproj index 68e9a83..ffb61e5 100644 --- a/proj/vc7ide/vector_test.vcproj +++ b/proj/vc7ide/vector_test.vcproj @@ -21,6 +21,7 @@ Optimization="0" AdditionalIncludeDirectories="../../../.." PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + GeneratePreprocessedFile="0" MinimalRebuild="TRUE" ExceptionHandling="TRUE" BasicRuntimeChecks="3" diff --git a/test/alloc_full_test.cpp b/test/alloc_full_test.cpp index a283552..1ffc2a9 100644 --- a/test/alloc_full_test.cpp +++ b/test/alloc_full_test.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include //std::remove #include diff --git a/test/allocator_traits_test.cpp b/test/allocator_traits_test.cpp index 407a62b..7da3ee7 100644 --- a/test/allocator_traits_test.cpp +++ b/test/allocator_traits_test.cpp @@ -11,18 +11,22 @@ #include #include #include -#include -#include +#include #include #include #include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include template class SimpleAllocator { + public: bool allocate_called_; bool deallocate_called_; - public: + typedef T value_type; template @@ -73,6 +77,7 @@ class SimpleSmartPtr template class ComplexAllocator { + public: bool allocate_called_; bool deallocate_called_; bool allocate_hint_called_; @@ -81,7 +86,6 @@ class ComplexAllocator mutable bool select_on_container_copy_construction_called_; bool construct_called_; - public: typedef T value_type; typedef SimpleSmartPtr pointer; typedef SimpleSmartPtr const_pointer; @@ -93,9 +97,12 @@ class ComplexAllocator typedef SimpleSmartPtr const_void_pointer; typedef signed short difference_type; typedef unsigned short size_type; - typedef boost::true_type propagate_on_container_copy_assignment; - typedef boost::true_type propagate_on_container_move_assignment; - typedef boost::true_type propagate_on_container_swap; + typedef boost::container::container_detail:: + true_type propagate_on_container_copy_assignment; + typedef boost::container::container_detail:: + true_type propagate_on_container_move_assignment; + typedef boost::container::container_detail:: + true_type propagate_on_container_swap; ComplexAllocator() : allocate_called_(false) @@ -127,23 +134,27 @@ class ComplexAllocator size_type max_size() const { max_size_called_ = true; return size_type(size_type(0)-1); } - #define BOOST_PP_LOCAL_MACRO(n) \ - template \ - void construct(U *p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - construct_called_ = true; \ - ::new (p) U (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ + #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + #define BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL(N)\ + \ + template< class U BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ + void construct(U *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \ + { construct_called_ = true; ::new(p) U ( BOOST_MOVE_FWD##N ); }\ // - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL + #else + + template< class U, class ...Args> + void construct(U *p, BOOST_FWD_REF(Args) ...args) + { construct_called_ = true; ::new(p) U( ::boost::forward(args)...); } + + #endif template void construct(U *p, boost::container::default_init_t) - { - construct_called_ = true; - ::new (p) U; - } + { construct_called_ = true; ::new(p)U; } //getters bool allocate_called() const @@ -212,22 +223,23 @@ void test_void_allocator() int main() { + using namespace boost::container::container_detail; test_void_allocator(); //SimpleAllocator - BOOST_STATIC_ASSERT(( boost::is_same >::value_type, int>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::pointer, int*>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::const_pointer, const int*>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::void_pointer, void*>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::const_void_pointer, const void*>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::difference_type, std::ptrdiff_t>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::size_type, std::size_t>::value )); BOOST_STATIC_ASSERT(( boost::container::allocator_traits < SimpleAllocator >::propagate_on_container_copy_assignment::value == false )); @@ -235,27 +247,27 @@ int main() < SimpleAllocator >::propagate_on_container_move_assignment::value == false )); BOOST_STATIC_ASSERT(( boost::container::allocator_traits < SimpleAllocator >::propagate_on_container_swap::value == false )); - BOOST_STATIC_ASSERT(( boost::is_same >::rebind_traits::allocator_type , SimpleAllocator >::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::rebind_alloc::value_type , double >::value )); //ComplexAllocator - BOOST_STATIC_ASSERT(( boost::is_same >::value_type, int>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::pointer, SimpleSmartPtr >::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::const_pointer, SimpleSmartPtr >::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::void_pointer, SimpleSmartPtr >::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::const_void_pointer, SimpleSmartPtr >::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::difference_type, signed short>::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::size_type, unsigned short>::value )); BOOST_STATIC_ASSERT(( boost::container::allocator_traits < ComplexAllocator >::propagate_on_container_copy_assignment::value == true )); @@ -263,10 +275,10 @@ int main() < ComplexAllocator >::propagate_on_container_move_assignment::value == true )); BOOST_STATIC_ASSERT(( boost::container::allocator_traits < ComplexAllocator >::propagate_on_container_swap::value == true )); - BOOST_STATIC_ASSERT(( boost::is_same >::rebind_traits::allocator_type , ComplexAllocator >::value )); - BOOST_STATIC_ASSERT(( boost::is_same >::rebind_alloc::value_type , double >::value )); @@ -279,51 +291,43 @@ int main() //allocate CAllocTraits::allocate(c_alloc, 1); - if(!c_alloc.allocate_called()){ - return 1; - } + BOOST_TEST(c_alloc.allocate_called()); + SAllocTraits::allocate(s_alloc, 1); - if(!s_alloc.allocate_called()){ - return 1; - } + BOOST_TEST(s_alloc.allocate_called()); //deallocate CAllocTraits::deallocate(c_alloc, CAllocTraits::pointer(), 1); - if(!c_alloc.deallocate_called()){ - return 1; - } + BOOST_TEST(c_alloc.deallocate_called()); + SAllocTraits::deallocate(s_alloc, SAllocTraits::pointer(), 1); - if(!s_alloc.deallocate_called()){ - return 1; - } + BOOST_TEST(s_alloc.deallocate_called()); //allocate with hint CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer()); - if(!c_alloc.allocate_hint_called()){ - return 1; - } + BOOST_TEST(c_alloc.allocate_hint_called()); + + s_alloc.allocate_called_ = false; SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer()); + BOOST_TEST(s_alloc.allocate_called()); //destroy float dummy; CAllocTraits::destroy(c_alloc, &dummy); - if(!c_alloc.destroy_called()){ - return 1; - } + BOOST_TEST(c_alloc.destroy_called()); + SAllocTraits::destroy(s_alloc, &dummy); //max_size CAllocTraits::max_size(c_alloc); - if(!c_alloc.max_size_called()){ - return 1; - } + BOOST_TEST(c_alloc.max_size_called()); + SAllocTraits::max_size(s_alloc); //select_on_container_copy_construction CAllocTraits::select_on_container_copy_construction(c_alloc); - if(!c_alloc.select_on_container_copy_construction_called()){ - return 1; - } + BOOST_TEST(c_alloc.select_on_container_copy_construction_called()); + SAllocTraits::select_on_container_copy_construction(s_alloc); //construct @@ -332,81 +336,61 @@ int main() c.copymoveconstructed_ = true; c.copymoveconstructed_ = true; CAllocTraits::construct(c_alloc, &c); - if(!c_alloc.construct_called() || c.copymoveconstructed() || c.moved()){ - return 1; - } + BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved()); } { int i = 5; CAllocTraits::construct(c_alloc, &i, boost::container::default_init); - if(!c_alloc.construct_called() || i != 5){ - return 1; - } + BOOST_TEST(c_alloc.construct_called() && i == 5); } { copymovable c; copymovable c2; CAllocTraits::construct(c_alloc, &c, c2); - if(!c_alloc.construct_called() || !c.copymoveconstructed() || c.moved()){ - return 1; - } + BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && !c.moved()); } { copymovable c; copymovable c2; CAllocTraits::construct(c_alloc, &c, ::boost::move(c2)); - if(!c_alloc.construct_called() || !c.copymoveconstructed() || !c.moved()){ - return 1; - } + BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && c.moved()); } { copymovable c; c.copymoveconstructed_ = true; c.copymoveconstructed_ = true; SAllocTraits::construct(s_alloc, &c); - if(c.copymoveconstructed() || c.moved()){ - return 1; - } + BOOST_TEST(!c.copymoveconstructed() && !c.moved()); } { int i = 4; SAllocTraits::construct(s_alloc, &i, boost::container::default_init); - if(i != 4){ - return 1; - } + BOOST_TEST(i == 4); } { copymovable c; copymovable c2; SAllocTraits::construct(s_alloc, &c, c2); - if(!c.copymoveconstructed() || c.moved()){ - return 1; - } + BOOST_TEST(c.copymoveconstructed() && !c.moved()); } { copymovable c; copymovable c2; SAllocTraits::construct(s_alloc, &c, ::boost::move(c2)); - if(!c.copymoveconstructed() || !c.moved()){ - return 1; - } + BOOST_TEST(c.copymoveconstructed() && c.moved()); } { copymovable c; CAllocTraits::construct(c_alloc, &c, 0, 1, 2); - if(!c_alloc.construct_called() || c.copymoveconstructed() || c.moved()){ - return 1; - } + BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved()); } { copymovable c; copymovable c2; SAllocTraits::construct(s_alloc, &c, 0, 1, 2); - if(c.copymoveconstructed() || c.moved()){ - return 1; - } + BOOST_TEST(!c.copymoveconstructed() && !c.moved()); } - return 0; + return ::boost::report_errors(); } #include diff --git a/test/container_common_tests.hpp b/test/container_common_tests.hpp index 394a860..af57eb6 100644 --- a/test/container_common_tests.hpp +++ b/test/container_common_tests.hpp @@ -26,7 +26,7 @@ const Container &as_const(Container &c) template bool test_nth_index_of(Container &c) { - typename Container::iterator it; + typename Container::iterator it; typename Container::const_iterator cit; typename Container::size_type sz, csz; //index 0 @@ -43,7 +43,7 @@ bool test_nth_index_of(Container &c) return false; if(csz != 0) return false; - + //index size()/2 const typename Container::size_type sz_div_2 = c.size()/2; it = c.nth(sz_div_2); diff --git a/test/default_init_test.hpp b/test/default_init_test.hpp index 4af9d59..57303aa 100644 --- a/test/default_init_test.hpp +++ b/test/default_init_test.hpp @@ -12,27 +12,7 @@ #define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER #include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "print_container.hpp" -#include "check_equal_containers.hpp" -#include "movable_int.hpp" -#include -#include -#include "emplace_test.hpp" -#include "input_from_forward_iterator.hpp" -#include -#include -#include -#include -#include "insert_test.hpp" +#include namespace boost{ namespace container { diff --git a/test/deque_test.cpp b/test/deque_test.cpp index 4e0b30e..ff31e50 100644 --- a/test/deque_test.cpp +++ b/test/deque_test.cpp @@ -9,11 +9,9 @@ ////////////////////////////////////////////////////////////////////////////// #include -#include #include #include #include -#include #include #include diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp index 27b5202..c089289 100644 --- a/test/dummy_test_allocator.hpp +++ b/test/dummy_test_allocator.hpp @@ -17,18 +17,22 @@ #include #include - #include -#include -#include -#include -#include -#include -#include -#include + #include + +#include +#include +#include +#include +#include +#include + #include #include + +#include + #include #include #include @@ -136,12 +140,8 @@ class dummy_test_allocator //Experimental version 2 dummy_test_allocator functions - std::pair - allocation_command(boost::container::allocation_type, - size_type, - size_type, - size_type &, const pointer & = 0) - { return std::pair(pointer(), true); } + pointer allocation_command(boost::container::allocation_type, size_type, size_type &, pointer &p) + { p = pointer(); return pointer(); } //!Returns maximum the number of objects the previously allocated memory //!pointed by p can hold. diff --git a/test/emplace_test.hpp b/test/emplace_test.hpp index 62824c5..50fe656 100644 --- a/test/emplace_test.hpp +++ b/test/emplace_test.hpp @@ -16,8 +16,7 @@ #include #include #include -#include -#include +#include namespace boost{ namespace container { @@ -147,7 +146,7 @@ bool test_expected_container(const Container &ec, const std::pair EmplaceIntPair; -static boost::aligned_storage::type pair_storage; +static boost::container::container_detail::aligned_storage::type pair_storage; static EmplaceIntPair* initialize_emplace_int_pair() { diff --git a/test/expand_bwd_test_allocator.hpp b/test/expand_bwd_test_allocator.hpp index 3ae6ffb..2a2532e 100644 --- a/test/expand_bwd_test_allocator.hpp +++ b/test/expand_bwd_test_allocator.hpp @@ -17,14 +17,18 @@ #include #include - #include + #include + +#include #include -#include -#include #include + #include + +#include + #include #include #include @@ -117,35 +121,33 @@ class expand_bwd_test_allocator //Experimental version 2 expand_bwd_test_allocator functions - std::pair - allocation_command(boost::container::allocation_type command, - size_type limit_size, - size_type preferred_size, - size_type &received_size, const pointer &reuse = 0) + pointer allocation_command(boost::container::allocation_type command, + size_type limit_size,size_type &prefer_in_recvd_out_size,pointer &reuse) { - (void)preferred_size; (void)reuse; (void)command; + (void)reuse; (void)command; //This allocator only expands backwards! assert(m_allocations == 0 || (command & boost::container::expand_bwd)); - received_size = limit_size; + prefer_in_recvd_out_size = limit_size; if(m_allocations == 0){ if((m_offset + limit_size) > m_size){ assert(0); } ++m_allocations; - return std::pair(mp_buffer + m_offset, false); + reuse = 0; + return (mp_buffer + m_offset); } else if(m_allocations == 1){ if(limit_size > m_size){ assert(0); } ++m_allocations; - return std::pair(mp_buffer, true); + return mp_buffer; } else{ throw_bad_alloc(); - return std::pair(mp_buffer, true); + return mp_buffer; } } diff --git a/test/expand_bwd_test_template.hpp b/test/expand_bwd_test_template.hpp index ee73c28..1c193ac 100644 --- a/test/expand_bwd_test_template.hpp +++ b/test/expand_bwd_test_template.hpp @@ -18,7 +18,6 @@ #include "expand_bwd_test_allocator.hpp" #include //equal() #include "movable_int.hpp" -#include #include namespace boost { namespace container { namespace test { @@ -79,6 +78,9 @@ bool test_insert_with_expand_bwd() { 0, 100, 200 }; for(unsigned int pos = 0; pos < sizeof(Position)/sizeof(Position[0]); ++pos){ + if(!life_count::check(0)) + return false; + for(unsigned int iteration = 0; iteration < Iterations; ++iteration) { boost::movelib::unique_ptr memptr = @@ -122,6 +124,8 @@ bool test_insert_with_expand_bwd() return false; } } + if(!life_count::check(0)) + return false; } return true; diff --git a/test/flat_map_test.cpp b/test/flat_map_test.cpp index 1e11cd2..e55a9ef 100644 --- a/test/flat_map_test.cpp +++ b/test/flat_map_test.cpp @@ -183,7 +183,7 @@ public: flat_multimap::const_iterator cit_; flat_multimap::reverse_iterator rit_; flat_multimap::const_reverse_iterator crit_; - + friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b) { return a.id_ < b.id_; } }; @@ -199,17 +199,17 @@ void test_move() move_assign.swap(original); } -template +template class flat_map_propagate_test_wrapper : public boost::container::flat_map < T, T, std::less - , typename boost::container::allocator_traits::template + , typename boost::container::allocator_traits::template portable_rebind_alloc< std::pair >::type> { BOOST_COPYABLE_AND_MOVABLE(flat_map_propagate_test_wrapper) typedef boost::container::flat_map < T, T, std::less - , typename boost::container::allocator_traits::template + , typename boost::container::allocator_traits::template portable_rebind_alloc< std::pair >::type> Base; public: flat_map_propagate_test_wrapper() @@ -441,8 +441,8 @@ int main() //Allocator argument container { - flat_map map_((std::allocator >())); - flat_multimap multimap_((std::allocator >())); + flat_map map_((flat_map::allocator_type())); + flat_multimap multimap_((flat_multimap::allocator_type())); } //Now test move semantics { diff --git a/test/flat_set_test.cpp b/test/flat_set_test.cpp index 5949b8f..bd39ff8 100644 --- a/test/flat_set_test.cpp +++ b/test/flat_set_test.cpp @@ -184,7 +184,7 @@ class recursive_flat_set flat_set::const_iterator cit_; flat_set::reverse_iterator rit_; flat_set::const_reverse_iterator crit_; - + friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b) { return a.id_ < b.id_; } }; @@ -210,7 +210,7 @@ class recursive_flat_multiset flat_multiset::const_iterator cit_; flat_multiset::reverse_iterator rit_; flat_multiset::const_reverse_iterator crit_; - + friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b) { return a.id_ < b.id_; } }; @@ -227,12 +227,12 @@ void test_move() move_assign.swap(original); } -template +template class flat_set_propagate_test_wrapper - : public boost::container::flat_set, A> + : public boost::container::flat_set, Allocator> { BOOST_COPYABLE_AND_MOVABLE(flat_set_propagate_test_wrapper) - typedef boost::container::flat_set, A> Base; + typedef boost::container::flat_set, Allocator> Base; public: flat_set_propagate_test_wrapper() : Base() @@ -524,8 +524,8 @@ int main() //Allocator argument container { - flat_set set_((std::allocator())); - flat_multiset multiset_((std::allocator())); + flat_set set_((flat_set::allocator_type())); + flat_multiset multiset_((flat_multiset::allocator_type())); } //Now test move semantics { diff --git a/test/insert_vs_emplace_test.cpp b/test/insert_vs_emplace_test.cpp index c523dab..8e841db 100644 --- a/test/insert_vs_emplace_test.cpp +++ b/test/insert_vs_emplace_test.cpp @@ -64,7 +64,7 @@ public: X& operator=(BOOST_COPY_ASSIGN_REF(X) x) { - + i_ = x.i_; p_ = x.p_; // std::cout << "X& operator=(const X& x)\n"; @@ -82,7 +82,7 @@ public: X& operator=(BOOST_RV_REF(X) x) BOOST_CONTAINER_NOEXCEPT { - + i_ = x.i_; p_ = x.p_; // std::cout << "X& operator=(X&& x)\n"; diff --git a/test/list_test.cpp b/test/list_test.cpp index d3029f3..46cc22e 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -71,7 +71,7 @@ public: list::const_iterator cit_; list::reverse_iterator rit_; list::const_reverse_iterator crit_; - + recursive_list &operator=(const recursive_list &o) { list_ = o.list_; return *this; } }; @@ -207,3 +207,13 @@ int main () } #include + +/* +#include +//#include + +int main() +{ + return 0; +} +*/ diff --git a/test/list_test.hpp b/test/list_test.hpp index 606dc60..c4eca93 100644 --- a/test/list_test.hpp +++ b/test/list_test.hpp @@ -20,11 +20,8 @@ #include #include -#include #include -#include #include //std::greater -#include namespace boost{ namespace container { diff --git a/test/map_test.cpp b/test/map_test.cpp index 4ff5721..a98016f 100644 --- a/test/map_test.cpp +++ b/test/map_test.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include "print_container.hpp" @@ -201,7 +200,7 @@ class recursive_map map::const_iterator cit_; map::reverse_iterator rit_; map::const_reverse_iterator crit_; - + friend bool operator< (const recursive_map &a, const recursive_map &b) { return a.id_ < b.id_; } }; @@ -218,7 +217,7 @@ class recursive_multimap multimap::const_iterator cit_; multimap::reverse_iterator rit_; multimap::const_reverse_iterator crit_; - + friend bool operator< (const recursive_multimap &a, const recursive_multimap &b) { return a.id_ < b.id_; } }; @@ -236,11 +235,11 @@ void test_move() move_assign.swap(original); } -template +template class map_propagate_test_wrapper : public boost::container::map < T, T, std::less - , typename boost::container::allocator_traits::template + , typename boost::container::allocator_traits::template portable_rebind_alloc< std::pair >::type //tree_assoc_defaults > @@ -248,7 +247,7 @@ class map_propagate_test_wrapper BOOST_COPYABLE_AND_MOVABLE(map_propagate_test_wrapper) typedef boost::container::map < T, T, std::less - , typename boost::container::allocator_traits::template + , typename boost::container::allocator_traits::template portable_rebind_alloc< std::pair >::type > Base; public: @@ -399,8 +398,8 @@ int main () } //Allocator argument container { - map map_((std::allocator >())); - multimap multimap_((std::allocator >())); + map map_((map::allocator_type())); + multimap multimap_((multimap::allocator_type())); } //Now test move semantics { diff --git a/test/map_test.hpp b/test/map_test.hpp index 502b00a..2dbd558 100644 --- a/test/map_test.hpp +++ b/test/map_test.hpp @@ -14,22 +14,22 @@ #include #include "check_equal_containers.hpp" #include "print_container.hpp" -#include #include #include #include #include -#include //std::pair +#include //pair #include #include -#include -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test { -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} -#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, )) -#include BOOST_PP_ITERATE() +#include + +namespace boost { namespace container { namespace test { + +BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(has_member_rebalance, rebalance) + +}}} template bool operator ==(std::pair &p1, std::pair &p2) @@ -534,13 +534,13 @@ int map_test() return 1; map_test_rebalanceable(boostmap - , container_detail::bool_::value>()); + , container_detail::bool_::value>()); if(!CheckEqualContainers(boostmap, stdmap)){ std::cout << "Error in boostmap.rebalance()" << std::endl; return 1; } map_test_rebalanceable(boostmultimap - , container_detail::bool_::value>()); + , container_detail::bool_::value>()); if(!CheckEqualContainers(boostmultimap, stdmultimap)){ std::cout << "Error in boostmultimap.rebalance()" << std::endl; return 1; diff --git a/test/null_iterators_test.cpp b/test/null_iterators_test.cpp index 59d1d89..faf60be 100644 --- a/test/null_iterators_test.cpp +++ b/test/null_iterators_test.cpp @@ -22,14 +22,13 @@ #include #include -#include #include #include #include using namespace boost::container; -typedef boost::aligned_storage::type buffer_t; +typedef boost::container::container_detail::aligned_storage::type buffer_t; static buffer_t buffer_0x00; static buffer_t buffer_0xFF; diff --git a/test/print_container.hpp b/test/print_container.hpp index afc07f6..2e49ec6 100644 --- a/test/print_container.hpp +++ b/test/print_container.hpp @@ -12,33 +12,12 @@ #define BOOST_PRINTCONTAINER_HPP #include -#include #include -#include namespace boost{ namespace container { namespace test{ -struct PrintValues -{ - typedef int argument_type; - typedef void result_type; - - void operator() (int value) const - { - std::cout << value << " "; - } -}; - -template -void PrintContents(const Container &cont, const char *contName) -{ - std::cout<< "Printing contents of " << contName << std::endl; - std::for_each(cont.begin(), cont.end(), PrintValues()); - std::cout<< std::endl << std::endl; -} - //Function to dump data template diff --git a/test/scoped_allocator_adaptor_test.cpp b/test/scoped_allocator_adaptor_test.cpp index d86359b..88a329c 100644 --- a/test/scoped_allocator_adaptor_test.cpp +++ b/test/scoped_allocator_adaptor_test.cpp @@ -9,7 +9,6 @@ ////////////////////////////////////////////////////////////////////////////// #include #include -#include #include #include #include @@ -237,21 +236,22 @@ namespace container { template struct constructible_with_allocator_prefix < ::mark_on_scoped_allocation > - : ::boost::true_type -{}; +{ + static const bool value = true; +}; template struct constructible_with_allocator_suffix < ::mark_on_scoped_allocation > - : ::boost::true_type -{}; +{ + static const bool value = true; +}; } //namespace container { } //namespace boost { #include -#include #include #include #include diff --git a/test/scoped_allocator_usage_test.cpp b/test/scoped_allocator_usage_test.cpp index 111d12a..aec537e 100644 --- a/test/scoped_allocator_usage_test.cpp +++ b/test/scoped_allocator_usage_test.cpp @@ -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 #include @@ -136,26 +145,26 @@ struct is_unique_assoc static const bool value = false; }; -template -struct is_unique_assoc< map > +template +struct is_unique_assoc< map > { static const bool value = true; }; -template -struct is_unique_assoc< flat_map > +template +struct is_unique_assoc< flat_map > { static const bool value = true; }; -template -struct is_unique_assoc< set > +template +struct is_unique_assoc< set > { static const bool value = true; }; -template -struct is_unique_assoc< flat_set > +template +struct is_unique_assoc< flat_set > { static const bool value = true; }; @@ -171,26 +180,26 @@ struct is_map static const bool value = false; }; -template -struct is_map< map > +template +struct is_map< map > { static const bool value = true; }; -template -struct is_map< flat_map > +template +struct is_map< flat_map > { static const bool value = true; }; -template -struct is_map< multimap > +template +struct is_map< multimap > { static const bool value = true; }; -template -struct is_map< flat_multimap > +template +struct is_map< flat_multimap > { static const bool value = true; }; @@ -201,26 +210,26 @@ struct is_set static const bool value = false; }; -template -struct is_set< set > +template +struct is_set< set > { static const bool value = true; }; -template -struct is_set< flat_set > +template +struct is_set< flat_set > { static const bool value = true; }; -template -struct is_set< multiset > +template +struct is_set< multiset > { static const bool value = true; }; -template -struct is_set< flat_multiset > +template +struct is_set< flat_multiset > { static const bool value = true; }; diff --git a/test/set_test.cpp b/test/set_test.cpp index 4c0be9c..656305b 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -176,7 +176,7 @@ public: set::const_iterator cit_; set::reverse_iterator rit_; set::const_reverse_iterator crit_; - + friend bool operator< (const recursive_set &a, const recursive_set &b) { return a.id_ < b.id_; } }; @@ -194,7 +194,7 @@ class recursive_multiset multiset::const_iterator cit_; multiset::reverse_iterator rit_; multiset::const_reverse_iterator crit_; - + friend bool operator< (const recursive_multiset &a, const recursive_multiset &b) { return a.id_ < b.id_; } }; @@ -212,14 +212,14 @@ void test_move() move_assign.swap(original); } -template +template class set_propagate_test_wrapper - : public boost::container::set, A + : public boost::container::set, Allocator //tree_assoc_defaults > { BOOST_COPYABLE_AND_MOVABLE(set_propagate_test_wrapper) - typedef boost::container::set, A > Base; + typedef boost::container::set, Allocator > Base; public: set_propagate_test_wrapper() : Base() @@ -363,8 +363,8 @@ int main () } //Allocator argument container { - set set_((std::allocator())); - multiset multiset_((std::allocator())); + set set_((set::allocator_type())); + multiset multiset_((multiset::allocator_type())); } //Now test move semantics { diff --git a/test/set_test.hpp b/test/set_test.hpp index 74fd8b8..409de62 100644 --- a/test/set_test.hpp +++ b/test/set_test.hpp @@ -13,22 +13,17 @@ #include #include "check_equal_containers.hpp" -#include -#include -#include #include "print_container.hpp" #include #include #include -#include -#include #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace test { #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} -#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, )) -#include BOOST_PP_ITERATE() - +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0 +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0 +#include namespace boost{ namespace container { diff --git a/test/slist_test.cpp b/test/slist_test.cpp index 6e7cda6..f5420c5 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -59,7 +59,7 @@ public: slist slist_; slist::iterator it_; slist::const_iterator cit_; - + recursive_slist &operator=(const recursive_slist &o) { slist_ = o.slist_; return *this; } }; diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp index eeb3c7f..ecc6c55 100644 --- a/test/stable_vector_test.cpp +++ b/test/stable_vector_test.cpp @@ -9,11 +9,7 @@ ////////////////////////////////////////////////////////////////////////////// #include -#include #include -#include -#include -#include #include #include @@ -70,7 +66,7 @@ class recursive_vector stable_vector::const_iterator cit_; stable_vector::reverse_iterator rit_; stable_vector::const_reverse_iterator crit_; - + recursive_vector &operator=(const recursive_vector &o) { vector_ = o.vector_; return *this; } }; diff --git a/test/static_vector_test.hpp b/test/static_vector_test.hpp index 1686955..ab931b2 100644 --- a/test/static_vector_test.hpp +++ b/test/static_vector_test.hpp @@ -78,6 +78,9 @@ private: namespace boost { +template +struct has_nothrow_move; + template <> struct has_nothrow_move { diff --git a/test/string_test.cpp b/test/string_test.cpp index d43f9f7..7d63e8d 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -432,12 +432,12 @@ bool test_expand_bwd() return test::test_all_expand_bwd(); } -template +template class string_propagate_test_wrapper - : public basic_string, A> + : public basic_string, Allocator> { BOOST_COPYABLE_AND_MOVABLE(string_propagate_test_wrapper) - typedef basic_string, A> Base; + typedef basic_string, Allocator> Base; public: string_propagate_test_wrapper() : Base() diff --git a/test/vector_test.cpp b/test/vector_test.cpp index 0ec3eb1..e39d58d 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -7,10 +7,8 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #include #include -#include #include #include @@ -252,3 +250,14 @@ int main() return 0; } + +/* + +#include +//#include +int main() +{ + boost::container::vector a; + return 0; +} +*/ diff --git a/test/vector_test.hpp b/test/vector_test.hpp index 197caae..b2b55a7 100644 --- a/test/vector_test.hpp +++ b/test/vector_test.hpp @@ -13,10 +13,8 @@ #include -#include #include #include -#include #include #include