X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=boost%2Fcontainer%2Fdetail%2Fadvanced_insert_int.hpp;h=a35279dcf7617be0ff0b892a38af18f1e6b09182;hb=08c1e93fa36a49f49325a07fe91ff92c964c2b6c;hp=a97af282e039c2f175f7d54a266b4ae9e6e839ba;hpb=bb4dd8289b351fae6b55e303f189127a394a1edd;p=platform%2Fupstream%2Fboost.git diff --git a/boost/container/detail/advanced_insert_int.hpp b/boost/container/detail/advanced_insert_int.hpp index a97af28..a35279d 100644 --- a/boost/container/detail/advanced_insert_int.hpp +++ b/boost/container/detail/advanced_insert_int.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost +// (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) // @@ -11,170 +11,198 @@ #ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP #define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif -#include "config_begin.hpp" +#include #include + #include #include #include -#include +#include +#include +#include +#include +#include #include //std::iterator_traits #include +#include namespace boost { namespace container { namespace container_detail { -//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl -template -struct advanced_insert_aux_int +template +struct move_insert_range_proxy { - typedef typename std::iterator_traits::difference_type difference_type; - virtual void copy_remaining_to(Iterator p) = 0; - virtual void uninitialized_copy_remaining_to(Iterator p) = 0; - virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0; - virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0; - virtual ~advanced_insert_aux_int() {} + 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) + { + 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) + { + this->first_ = ::boost::container::move_n_source(this->first_, n, p); + } + + FwdIt first_; }; -//This class template will adapt each FwIt types to advanced_insert_aux_int + template -struct advanced_insert_aux_proxy - : public advanced_insert_aux_int +struct insert_range_proxy { typedef typename allocator_traits::size_type size_type; typedef typename allocator_traits::value_type value_type; - typedef typename advanced_insert_aux_int::difference_type difference_type; - - advanced_insert_aux_proxy(A& a, FwdIt first, FwdIt last) - : a_(a), first_(first), last_(last) - {} - virtual ~advanced_insert_aux_proxy() + explicit insert_range_proxy(FwdIt first) + : first_(first) {} - virtual void copy_remaining_to(Iterator p) - { ::boost::copy_or_move(this->first_, this->last_, p); } - - virtual void uninitialized_copy_remaining_to(Iterator p) - { ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); } + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) + { + this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); + } - virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n) + void copy_n_and_update(A &, Iterator p, size_type n) { - FwdIt mid = this->first_; - std::advance(mid, division_count); - if(first_n){ - ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos); - this->first_ = mid; - } - else{ - ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos); - this->last_ = mid; - } + this->first_ = ::boost::container::copy_n_source(this->first_, n, p); } - virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n) + FwdIt first_; +}; + + +template +struct insert_n_copies_proxy +{ + 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 + { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } + + void copy_n_and_update(A &, Iterator p, size_type n) const { - FwdIt mid = this->first_; - std::advance(mid, division_count); - if(first_n){ - ::boost::copy_or_move(this->first_, mid, pos); - this->first_ = mid; - } - else{ - ::boost::copy_or_move(mid, this->last_, pos); - this->last_ = mid; + for (; 0 < n; --n, ++p){ + *p = v_; } } - A &a_; - FwdIt first_, last_; + + const value_type &v_; }; -//This class template will adapt default construction insertions to advanced_insert_aux_int template -struct default_construct_aux_proxy - : public advanced_insert_aux_int +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 typename advanced_insert_aux_int::difference_type difference_type; - default_construct_aux_proxy(A &a, size_type count) - : a_(a), count_(count) - {} + void uninitialized_copy_n_and_update(A &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 + { BOOST_ASSERT(false); } +}; - virtual ~default_construct_aux_proxy() +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; + + void uninitialized_copy_n_and_update(A &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 + { BOOST_ASSERT(false); } +}; + +template +struct insert_copy_proxy +{ + 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_copy_proxy(const value_type &v) + : v_(v) {} - virtual void copy_remaining_to(Iterator) - { //This should never be called with any count - BOOST_ASSERT(this->count_ == 0); + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, iterator_to_raw_pointer(p), v_); } - virtual void uninitialized_copy_remaining_to(Iterator p) - { this->priv_uninitialized_copy(p, this->count_); } - - virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n) + void copy_n_and_update(A &, Iterator p, size_type n) const { - size_type new_count; - if(first_n){ - new_count = division_count; - } - else{ - BOOST_ASSERT(difference_type(this->count_)>= division_count); - new_count = this->count_ - division_count; - } - this->priv_uninitialized_copy(pos, new_count); + BOOST_ASSERT(n == 1); (void)n; + *p =v_; } - virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n) + const value_type &v_; +}; + + +template +struct insert_move_proxy +{ + 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_move_proxy(value_type &v) + : v_(v) + {} + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const { - BOOST_ASSERT(this->count_ == 0); - size_type new_count; - if(first_n){ - new_count = division_count; - } - else{ - BOOST_ASSERT(difference_type(this->count_)>= division_count); - new_count = this->count_ - division_count; - } - //This function should never called with a count different to zero - BOOST_ASSERT(new_count == 0); - (void)new_count; + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) ); } - private: - void priv_uninitialized_copy(Iterator p, const size_type n) + void copy_n_and_update(A &, Iterator p, size_type n) const { - BOOST_ASSERT(n <= this->count_); - Iterator orig_p = p; - size_type i = 0; - try{ - for(; i < n; ++i, ++p){ - alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p)); - } - } - catch(...){ - while(i--){ - alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++)); - } - throw; - } - this->count_ -= n; + BOOST_ASSERT(n == 1); (void)n; + *p = ::boost::move(v_); } - A &a_; - size_type count_; + + value_type &v_; }; +template +insert_move_proxy get_insert_value_proxy(BOOST_RV_REF(typename std::iterator_traits::value_type) v) +{ + return insert_move_proxy(v); +} + +template +insert_copy_proxy get_insert_value_proxy(const typename std::iterator_traits::value_type &v) +{ + return insert_copy_proxy(v); +} + }}} //namespace boost { namespace container { namespace container_detail { #ifdef BOOST_CONTAINER_PERFECT_FORWARDING #include -#include -#include +#include #include //#include //For debugging purposes @@ -182,143 +210,117 @@ namespace boost { namespace container { namespace container_detail { - -//This class template will adapt emplace construction insertions of movable types -//to advanced_insert_aux_int template -struct advanced_insert_aux_non_movable_emplace - : public advanced_insert_aux_int +struct insert_non_movable_emplace_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 typename advanced_insert_aux_int::difference_type difference_type; - typedef typename build_number_seq::type index_tuple_t; + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; - explicit advanced_insert_aux_non_movable_emplace(A &a, Args&&... args) - : a_(a) - , args_(args...) - , used_(false) - {} + typedef typename build_number_seq::type index_tuple_t; - ~advanced_insert_aux_non_movable_emplace() + explicit insert_non_movable_emplace_proxy(Args&&... args) + : args_(args...) {} - virtual void copy_remaining_to(Iterator) - //This code can't be called since value_type is not movable or copyable - { BOOST_ASSERT(false); } - - virtual void uninitialized_copy_remaining_to(Iterator p) - { this->priv_uninitialized_copy_remaining_to(index_tuple_t(), p); } - - virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n) - { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); } - - virtual void copy_some_and_update(Iterator, difference_type, bool ) - //This code can't be called since value_type is not movable or copyable - { BOOST_ASSERT(false); } + void uninitialized_copy_n_and_update(A &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(const index_tuple&, Iterator p, difference_type division_count, bool first_n) + void priv_uninitialized_copy_some_and_update(A &a, const index_tuple&, Iterator p, size_type n) { - BOOST_ASSERT(division_count <=1); - if((first_n && division_count == 1) || (!first_n && division_count == 0)){ - if(!this->used_){ - alloc_traits::construct( this->a_ - , container_detail::to_raw_pointer(&*p) - , ::boost::container::container_detail:: - stored_ref::forward(get(this->args_))... - ); - this->used_ = true; - } - } - } - - template - void priv_uninitialized_copy_remaining_to(const index_tuple&, Iterator p) - { - if(!this->used_){ - alloc_traits::construct( this->a_ - , container_detail::to_raw_pointer(&*p) - , ::boost::container::container_detail:: - stored_ref::forward(get(this->args_))... - ); - this->used_ = true; - } + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward(get(this->args_))... ); } protected: - A &a_; tuple args_; - bool used_; }; -//This class template will adapt emplace construction insertions of movable types -//to advanced_insert_aux_int template -struct advanced_insert_aux_emplace - : public advanced_insert_aux_non_movable_emplace +struct insert_emplace_proxy + : public insert_non_movable_emplace_proxy { - typedef advanced_insert_aux_non_movable_emplace base_t; - typedef boost::container::allocator_traits alloc_traits; - typedef typename base_t::value_type value_type; - typedef typename base_t::difference_type difference_type; - typedef typename base_t::index_tuple_t index_tuple_t; - - explicit advanced_insert_aux_emplace(A &a, Args&&... args) - : base_t(a, ::boost::forward(args)...) + typedef insert_non_movable_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) + : base_t(::boost::forward(args)...) {} - ~advanced_insert_aux_emplace() - {} - - //Override only needed functions - virtual void copy_remaining_to(Iterator p) - { this->priv_copy_remaining_to(index_tuple_t(), p); } - - virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n) - { this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); } + void copy_n_and_update(A &a, Iterator p, size_type n) + { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } private: + template - void priv_copy_remaining_to(const index_tuple&, Iterator p) + void priv_copy_some_and_update(A &a, const index_tuple&, Iterator p, size_type n) { - if(!this->used_){ - aligned_storage::value> v; - value_type *vp = static_cast(static_cast(&v)); - alloc_traits::construct(this->a_, vp, - ::boost::container::container_detail::stored_ref::forward(get(this->args_))...); - scoped_destructor d(this->a_, vp); + BOOST_ASSERT(n ==1); (void)n; + aligned_storage::value> v; + value_type *vp = static_cast(static_cast(&v)); + alloc_traits::construct(a, vp, + ::boost::forward(get(this->args_))...); + BOOST_TRY{ *p = ::boost::move(*vp); - d.release(); - this->used_ = true; } - } - - template - void priv_copy_some_and_update(const index_tuple&, Iterator p, difference_type division_count, bool first_n) - { - BOOST_ASSERT(division_count <=1); - if((first_n && division_count == 1) || (!first_n && division_count == 0)){ - if(!this->used_){ - aligned_storage::value> v; - value_type *vp = static_cast(static_cast(&v)); - alloc_traits::construct(this->a_, vp, - ::boost::container::container_detail::stored_ref::forward(get(this->args_))...); - try { - *p = ::boost::move(*vp); - } catch (...) { - alloc_traits::destroy(this->a_, vp); - throw; - } - alloc_traits::destroy(this->a_, vp); - this->used_ = true; - } + BOOST_CATCH(...){ + alloc_traits::destroy(a, vp); + BOOST_RETHROW } + BOOST_CATCH_END + alloc_traits::destroy(a, vp); } }; +//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 +{ + 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 + > + : public insert_copy_proxy +{ + 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 +{ + 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 & + > + : public insert_copy_proxy +{ + 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 @@ -330,118 +332,142 @@ namespace boost { namespace container { namespace container_detail { -#define BOOST_PP_LOCAL_MACRO(n) \ -template \ -struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \ - : public advanced_insert_aux_int \ +#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 allocator_traits::size_type size_type; \ - typedef typename allocator_traits::value_type value_type; \ - typedef typename advanced_insert_aux_int::difference_type \ - difference_type; \ + typedef typename alloc_traits::size_type size_type; \ + typedef typename alloc_traits::value_type value_type; \ \ - BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \ - ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ - : a_(a) \ - , used_(false) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_INIT, _) \ - {} \ + 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, _) \ + {} \ \ - virtual void copy_remaining_to(Iterator) \ - { BOOST_ASSERT(false); } \ - \ - virtual void uninitialized_copy_remaining_to(Iterator p) \ + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) \ { \ - if(!this->used_){ \ - alloc_traits::construct \ - ( this->a_ \ - , container_detail::to_raw_pointer(&*p) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ - ); \ - this->used_ = true; \ - } \ + 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, _) \ + ); \ } \ \ - virtual void uninitialized_copy_some_and_update \ - (Iterator p, difference_type division_count, bool first_n) \ - { \ - BOOST_ASSERT(division_count <=1); \ - if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \ - if(!this->used_){ \ - alloc_traits::construct \ - ( this->a_ \ - , container_detail::to_raw_pointer(&*p) \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ - ); \ - this->used_ = true; \ - } \ - } \ - } \ - \ - virtual void copy_some_and_update(Iterator, difference_type, bool) \ + void copy_n_and_update(A &, Iterator, size_type) \ { BOOST_ASSERT(false); } \ \ - A &a_; \ - bool used_; \ - BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \ + protected: \ + BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \ }; \ \ -template \ -struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ - : BOOST_PP_CAT(BOOST_PP_CAT( \ - advanced_insert_aux_non_movable_emplace, n), arg) \ - < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > \ +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(BOOST_PP_CAT( \ - advanced_insert_aux_non_movable_emplace, n), arg) \ - base_t; \ + 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::difference_type difference_type; \ + typedef typename base_t::size_type size_type; \ typedef boost::container::allocator_traits alloc_traits; \ \ - BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ - ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ - : base_t(a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \ - {} \ + 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, _) ) \ + {} \ \ - virtual void copy_remaining_to(Iterator p) \ + void copy_n_and_update(A &a, Iterator p, size_type n) \ { \ - if(!this->used_){ \ - aligned_storage::value> v; \ - value_type *vp = static_cast(static_cast(&v)); \ - alloc_traits::construct(this->a_, vp \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \ - scoped_destructor d(this->a_, vp); \ - *p = ::boost::move(*vp); \ - d.release(); \ - this->used_ = true; \ + 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); \ } \ - } \ - \ - virtual void copy_some_and_update \ - (Iterator p, difference_type division_count, bool first_n) \ - { \ - BOOST_ASSERT(division_count <=1); \ - if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \ - if(!this->used_){ \ - aligned_storage::value> v; \ - value_type *vp = static_cast(static_cast(&v)); \ - alloc_traits::construct(this->a_, vp \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \ - scoped_destructor d(this->a_, vp); \ - *p = ::boost::move(*vp); \ - d.release(); \ - this->used_ = true; \ - } \ + 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() +#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 +{ + 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 +{ + 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 +{ + 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 + > + : public insert_copy_proxy +{ + 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 +{ + 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 & + > + : public insert_copy_proxy +{ + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +#endif + }}} //namespace boost { namespace container { namespace container_detail { #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING