Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:10

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/container for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
0012 #define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
0013 
0014 #if defined (_MSC_VER)
0015 #  pragma once
0016 #endif
0017 
0018 #include <boost/container/detail/config_begin.hpp>
0019 #include <boost/container/detail/workaround.hpp>
0020 
0021 #include <boost/container/allocator_traits.hpp>
0022 #include <boost/container/uses_allocator.hpp>
0023 
0024 #include <boost/container/detail/addressof.hpp>
0025 #include <boost/container/detail/mpl.hpp>
0026 #include <boost/container/detail/is_pair.hpp>
0027 #include <boost/container/detail/type_traits.hpp>
0028 
0029 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0030 #include <boost/move/detail/fwd_macros.hpp>
0031 #else
0032 #include <boost/container/detail/variadic_templates_tools.hpp>
0033 #endif
0034 #include <boost/move/utility_core.hpp>
0035 
0036 namespace boost { namespace container {
0037 
0038 namespace dtl {
0039 
0040 
0041 // Check if we can detect is_convertible using advanced SFINAE expressions
0042 #if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0043 
0044    //! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list
0045    //! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html
0046    //! Thanks Mathias!
0047 
0048    //With variadic templates, we need a single class to implement the trait
0049    template<class T, class ...Args>
0050    struct is_constructible
0051    {
0052       typedef char yes_type;
0053       struct no_type
0054       { char padding[2]; };
0055 
0056       template<std::size_t N>
0057       struct dummy;
0058 
0059       template<class X>
0060       static decltype(X(boost::move_detail::declval<Args>()...), true_type()) test(int);
0061 
0062       template<class X>
0063       static no_type test(...);
0064 
0065       static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
0066    };
0067 
0068    template <class T, class InnerAlloc, class ...Args>
0069    struct is_constructible_with_allocator_prefix
0070       : is_constructible<T, allocator_arg_t, InnerAlloc, Args...>
0071    {};
0072 
0073 #else    // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0074 
0075    //Without advanced SFINAE expressions, we can't use is_constructible
0076    //so backup to constructible_with_allocator_xxx
0077 
0078    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0079 
0080    template <class T, class InnerAlloc, class ...Args>
0081    struct is_constructible_with_allocator_prefix
0082       : constructible_with_allocator_prefix<T>
0083    {};
0084 
0085    template <class T, class InnerAlloc, class ...Args>
0086    struct is_constructible_with_allocator_suffix
0087       : constructible_with_allocator_suffix<T>
0088    {};
0089 
0090    #else    // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0091 
0092    template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
0093    struct is_constructible_with_allocator_prefix
0094       : constructible_with_allocator_prefix<T>
0095    {};
0096 
0097    template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
0098    struct is_constructible_with_allocator_suffix
0099       : constructible_with_allocator_suffix<T>
0100    {};
0101 
0102    #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0103 
0104 #endif   // #if !defined(BOOST_NO_SFINAE_EXPR)
0105 
0106 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0107 
0108 template < typename ConstructAlloc
0109          , typename ArgAlloc
0110          , typename T
0111          , class ...Args
0112          >
0113 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
0114    < void
0115    , dtl::is_not_pair<T>
0116    , dtl::not_< uses_allocator<T, typename remove_cvref<ArgAlloc>::type > >
0117    >::type dispatch_uses_allocator
0118    ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
0119 {
0120    (void)arg_alloc;
0121    allocator_traits<ConstructAlloc>::construct(construct_alloc, p, ::boost::forward<Args>(args)...);
0122 }
0123 
0124 // allocator_arg_t
0125 template < typename ConstructAlloc
0126          , typename ArgAlloc
0127          , typename T
0128          , class ...Args
0129          >
0130 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
0131    < void
0132    , dtl::is_not_pair<T>
0133    , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
0134    , is_constructible_with_allocator_prefix<T, ArgAlloc, Args...>
0135    >::type dispatch_uses_allocator
0136    ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args) ...args)
0137 {
0138    allocator_traits<ConstructAlloc>::construct
0139       ( construct_alloc, p, allocator_arg
0140       , ::boost::forward<ArgAlloc>(arg_alloc), ::boost::forward<Args>(args)...);
0141 }
0142 
0143 // allocator suffix
0144 template < typename ConstructAlloc
0145          , typename ArgAlloc
0146          , typename T
0147          , class ...Args
0148          >
0149 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
0150    < void
0151    , dtl::is_not_pair<T>
0152    , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
0153    , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc, Args...> >
0154    >::type dispatch_uses_allocator
0155    ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
0156 {
0157    allocator_traits<ConstructAlloc>::construct
0158       (construct_alloc, p, ::boost::forward<Args>(args)..., ::boost::forward<ArgAlloc>(arg_alloc));
0159 }
0160 
0161 #else    //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0162 
0163 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
0164    template <typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
0165    BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
0166       < void\
0167       , dtl::is_not_pair<T>\
0168       , dtl::not_<uses_allocator<T, typename remove_cvref<ArgAlloc>::type> >\
0169       >::type\
0170       dispatch_uses_allocator\
0171       (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0172    {\
0173       (void)arg_alloc;\
0174       allocator_traits<ConstructAlloc>::construct(construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
0175    }\
0176 //
0177 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
0178 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
0179 
0180 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
0181    template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
0182    BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
0183       < void\
0184       , dtl::is_not_pair<T>\
0185       , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
0186       , is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>\
0187       >::type\
0188       dispatch_uses_allocator\
0189       (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0190    {\
0191       allocator_traits<ConstructAlloc>::construct\
0192          (construct_alloc, p, allocator_arg, ::boost::forward<ArgAlloc>(arg_alloc) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
0193    }\
0194 //
0195 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
0196 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
0197 
0198 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
0199    template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
0200    BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
0201       < void\
0202       , dtl::is_not_pair<T>\
0203       , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
0204       , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N> >\
0205       >::type\
0206       dispatch_uses_allocator\
0207       (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0208    {\
0209       allocator_traits<ConstructAlloc>::construct\
0210          (construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, ::boost::forward<ArgAlloc>(arg_alloc));\
0211    }\
0212 //
0213 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
0214 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
0215 
0216 #endif   //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0217 
0218 template < typename ConstructAlloc
0219          , typename ArgAlloc
0220          , typename Pair
0221          > inline 
0222 BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void >::type)
0223    dispatch_uses_allocator
0224    ( ConstructAlloc & construct_alloc
0225    , BOOST_FWD_REF(ArgAlloc) arg_alloc
0226    , Pair* p)
0227 {
0228    dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first));
0229    BOOST_CONTAINER_TRY{
0230       dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second));
0231    }
0232    BOOST_CONTAINER_CATCH(...) {
0233       allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
0234       BOOST_CONTAINER_RETHROW
0235    }
0236    BOOST_CONTAINER_CATCH_END
0237 }
0238 
0239 
0240 template < typename ConstructAlloc
0241          , typename ArgAlloc
0242          , class Pair, class U, class V>
0243 BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void>::type)
0244    dispatch_uses_allocator
0245    ( ConstructAlloc & construct_alloc
0246    , BOOST_FWD_REF(ArgAlloc) arg_alloc
0247    , Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
0248 {
0249    dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<U>(x));
0250    BOOST_CONTAINER_TRY{
0251       dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<V>(y));
0252    }
0253    BOOST_CONTAINER_CATCH(...){
0254       allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
0255       BOOST_CONTAINER_RETHROW
0256    }
0257    BOOST_CONTAINER_CATCH_END
0258 }
0259 
0260 template < typename ConstructAlloc
0261          , typename ArgAlloc
0262          , class Pair, class Pair2>
0263 BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void >::type)
0264    dispatch_uses_allocator
0265    (ConstructAlloc & construct_alloc
0266    , BOOST_FWD_REF(ArgAlloc) arg_alloc
0267    , Pair* p, Pair2& x)
0268 {  dispatch_uses_allocator(construct_alloc, arg_alloc, p, x.first, x.second);  }
0269 
0270 template < typename ConstructAlloc
0271          , typename ArgAlloc
0272          , class Pair, class Pair2>
0273 typename dtl::enable_if_and
0274    < void
0275    , dtl::is_pair<Pair>
0276    , dtl::not_<boost::move_detail::is_reference<Pair2> > >::type //This is needed for MSVC10 and ambiguous overloads
0277    dispatch_uses_allocator
0278    (ConstructAlloc & construct_alloc
0279       , BOOST_FWD_REF(ArgAlloc) arg_alloc
0280       , Pair* p, BOOST_RV_REF_BEG Pair2 BOOST_RV_REF_END x)
0281 {  dispatch_uses_allocator(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second));  }
0282 
0283 
0284 //piecewise construction from boost::tuple
0285 #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
0286 template< typename ConstructAlloc, typename ArgAlloc, class Pair \
0287         , template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
0288          BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
0289 typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
0290    dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
0291       , BoostTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
0292       , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
0293 {\
0294    (void)p; (void)q;\
0295    dispatch_uses_allocator\
0296       (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_TMPL_GET##N);\
0297    BOOST_CONTAINER_TRY{\
0298       dispatch_uses_allocator\
0299          (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_TMPL_GETQ##M);\
0300    }\
0301    BOOST_CONTAINER_CATCH(...) {\
0302       allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
0303       BOOST_CONTAINER_RETHROW\
0304    }\
0305    BOOST_CONTAINER_CATCH_END\
0306 }\
0307 //
0308 BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
0309 #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
0310 
0311 //piecewise construction from Std Tuple
0312 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0313 
0314    template< typename ConstructAlloc, typename ArgAlloc, class Pair
0315            , template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
0316    void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair
0317                                     , Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
0318    {
0319       (void)t1; (void)t2;
0320       dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(pair->first), ::boost::forward<Args1>(get<Indexes1>(t1))...);
0321       BOOST_CONTAINER_TRY{
0322          dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(pair->second), ::boost::forward<Args2>(get<Indexes2>(t2))...);
0323       }
0324       BOOST_CONTAINER_CATCH(...){
0325          allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));
0326          BOOST_CONTAINER_RETHROW
0327       }
0328       BOOST_CONTAINER_CATCH_END
0329    }
0330 
0331    template< typename ConstructAlloc, typename ArgAlloc, class Pair
0332            , template<class ...> class Tuple, class... Args1, class... Args2>
0333    typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
0334       dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t
0335                              , Tuple<Args1...> t1, Tuple<Args2...> t2)
0336    {
0337       (dispatch_uses_allocator_index)( construct_alloc, arg_alloc, pair, t1, t2
0338                                      , typename build_number_seq<sizeof...(Args1)>::type()
0339                                      , typename build_number_seq<sizeof...(Args2)>::type());
0340    }
0341 
0342 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
0343 
0344    //MSVC 2010 tuple implementation
0345    #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
0346    template< typename ConstructAlloc, typename ArgAlloc, class Pair\
0347            , template<class, class, class, class, class, class, class, class, class, class> class StdTuple\
0348             BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
0349    typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
0350       dispatch_uses_allocator(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
0351                            , StdTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
0352                            , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
0353    {\
0354       (void)p; (void)q;\
0355       dispatch_uses_allocator\
0356          (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
0357       BOOST_CONTAINER_TRY{\
0358          dispatch_uses_allocator\
0359             (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
0360       }\
0361       BOOST_CONTAINER_CATCH(...) {\
0362          allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
0363          BOOST_CONTAINER_RETHROW\
0364       }\
0365       BOOST_CONTAINER_CATCH_END\
0366    }\
0367    //
0368    BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
0369    #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
0370 
0371 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
0372    #if _VARIADIC_MAX >= 9
0373    #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
0374    #else
0375    #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
0376    #endif
0377 
0378    //MSVC 2012 tuple implementation
0379    #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
0380    template< typename ConstructAlloc, typename ArgAlloc, class Pair\
0381             , template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
0382             BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
0383    typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
0384       dispatch_uses_allocator\
0385          ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
0386          , StdTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
0387          , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
0388    {\
0389       (void)p; (void)q;\
0390       dispatch_uses_allocator\
0391          (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
0392       BOOST_CONTAINER_TRY{\
0393          dispatch_uses_allocator\
0394             (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
0395       }\
0396       BOOST_CONTAINER_CATCH(...) {\
0397          allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
0398          BOOST_CONTAINER_RETHROW\
0399       }\
0400       BOOST_CONTAINER_CATCH_END\
0401    }\
0402    //
0403    BOOST_MOVE_ITER2D_0TOMAX(BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
0404    #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
0405    #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
0406 
0407 #endif   //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0408 
0409 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0410 
0411 template < typename ConstructAlloc
0412          , typename ArgAlloc
0413          , class Pair, class KeyType, class ... Args>
0414 typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
0415    dispatch_uses_allocator
0416    (ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args)
0417 {
0418    dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));
0419    BOOST_CONTAINER_TRY{
0420       dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<Args>(args)...);
0421    }
0422    BOOST_CONTAINER_CATCH(...) {
0423       allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
0424       BOOST_CONTAINER_RETHROW
0425    }
0426    BOOST_CONTAINER_CATCH_END
0427 }
0428 
0429 #else
0430 
0431 #define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE(N) \
0432    template <typename ConstructAlloc, typename ArgAlloc, class Pair, class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
0433    inline typename dtl::enable_if\
0434       < dtl::is_pair<Pair> BOOST_MOVE_I void >::type\
0435       dispatch_uses_allocator\
0436       (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, \
0437        BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0438    {\
0439       dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));\
0440       BOOST_CONTAINER_TRY{\
0441          dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
0442       }\
0443       BOOST_CONTAINER_CATCH(...) {\
0444          allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));\
0445          BOOST_CONTAINER_RETHROW\
0446       }\
0447       BOOST_CONTAINER_CATCH_END\
0448    }\
0449 //
0450 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE)
0451 #undef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE
0452 
0453 #endif   //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0454 
0455 }  //namespace dtl
0456 
0457 }} // namespace boost { namespace container {
0458 
0459 #include <boost/container/detail/config_end.hpp>
0460 
0461 #endif //  BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP