Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-14 08:27:27

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2008-2013. 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_ADVANCED_INSERT_INT_HPP
0012 #define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024 
0025 // container
0026 #include <boost/container/allocator_traits.hpp>
0027 // container/detail
0028 #include <boost/container/detail/copy_move_algo.hpp>
0029 #include <boost/container/detail/destroyers.hpp>
0030 #include <boost/container/detail/mpl.hpp>
0031 #include <boost/container/detail/type_traits.hpp>
0032 #include <boost/container/detail/iterator.hpp>
0033 #include <boost/container/detail/iterators.hpp>
0034 #include <boost/move/detail/iterator_to_raw_pointer.hpp>
0035 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0036 #include <boost/move/detail/fwd_macros.hpp>
0037 #endif
0038 // move
0039 
0040 #include <boost/move/utility_core.hpp>
0041 #include <boost/move/detail/force_ptr.hpp>
0042 #include <boost/move/detail/launder.hpp>
0043 // other
0044 #include <boost/assert.hpp>
0045 
0046 namespace boost { namespace container { namespace dtl {
0047 
0048 template<class Allocator, class FwdIt>
0049 struct move_insert_range_proxy
0050 {
0051    typedef typename allocator_traits<Allocator>::value_type value_type;
0052 
0053    inline explicit move_insert_range_proxy(FwdIt first)
0054       :  first_(first)
0055    {}
0056 
0057    template<class Iterator>
0058    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n)
0059    {
0060       this->first_ = ::boost::container::uninitialized_move_alloc_n_source
0061          (a, this->first_, n, p);
0062    }
0063 
0064    template<class Iterator>
0065    inline void copy_n_and_update(Allocator &, Iterator p, std::size_t n)
0066    {
0067       this->first_ = ::boost::container::move_n_source(this->first_, n, p);
0068    }
0069 
0070    FwdIt first_;
0071 };
0072 
0073 
0074 template<class Allocator, class FwdIt>
0075 struct insert_range_proxy
0076 {
0077    typedef typename allocator_traits<Allocator>::value_type value_type;
0078 
0079    inline explicit insert_range_proxy(FwdIt first)
0080       :  first_(first)
0081    {}
0082 
0083    template<class Iterator>
0084    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n)
0085    {
0086       this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
0087    }
0088 
0089    template<class Iterator>
0090    inline void copy_n_and_update(Allocator &, Iterator p, std::size_t n)
0091    {
0092       this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
0093    }
0094 
0095    FwdIt first_;
0096 };
0097 
0098 
0099 template<class Allocator>
0100 struct insert_n_copies_proxy
0101 {
0102    typedef typename allocator_traits<Allocator>::value_type value_type;
0103 
0104    inline explicit insert_n_copies_proxy(const value_type &v)
0105       :  v_(v)
0106    {}
0107 
0108    template<class Iterator>
0109    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const
0110    {  boost::container::uninitialized_fill_alloc_n(a, v_, n, p);  }
0111 
0112    template<class Iterator>
0113    inline void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const
0114    {
0115       while (n){
0116          --n;
0117          *p = v_;
0118          ++p;
0119       }
0120    }
0121 
0122    const value_type &v_;
0123 };
0124 
0125 template<class Allocator>
0126 struct insert_value_initialized_n_proxy
0127 {
0128    typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
0129    typedef typename allocator_traits<Allocator>::value_type value_type;
0130    typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
0131 
0132    template<class Iterator>
0133    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const
0134    {  boost::container::uninitialized_value_init_alloc_n(a, n, p);  }
0135 
0136    template<class Iterator>
0137    void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const
0138    {
0139       while (n){
0140          --n;
0141          storage_t v;
0142          alloc_traits::construct(a, (value_type*)&v);
0143          value_type *vp = move_detail::launder_cast<value_type *>(&v);
0144          value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
0145          *p = ::boost::move(*vp);
0146          ++p;
0147       }
0148    }
0149 };
0150 
0151 template<class Allocator>
0152 struct insert_default_initialized_n_proxy
0153 {
0154    typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
0155    typedef typename allocator_traits<Allocator>::value_type value_type;
0156    typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
0157 
0158    template<class Iterator>
0159    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const
0160    {  boost::container::uninitialized_default_init_alloc_n(a, n, p);  }
0161 
0162    template<class Iterator>
0163    void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const
0164    {
0165       if(!is_pod<value_type>::value){
0166          while (n){
0167             --n;
0168             typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
0169             alloc_traits::construct(a, (value_type*)&v, default_init);
0170             value_type *vp = move_detail::launder_cast<value_type *>(&v);
0171             value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
0172             *p = ::boost::move(*vp);
0173             ++p;
0174          }
0175       }
0176    }
0177 };
0178 
0179 template<class Allocator>
0180 struct insert_copy_proxy
0181 {
0182    typedef boost::container::allocator_traits<Allocator> alloc_traits;
0183    typedef typename alloc_traits::value_type value_type;
0184 
0185    BOOST_STATIC_CONSTEXPR bool single_value = true;
0186 
0187    inline explicit insert_copy_proxy(const value_type &v)
0188       :  v_(v)
0189    {}
0190 
0191    template<class Iterator>
0192    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const
0193    {
0194       BOOST_ASSERT(n == 1);  (void)n;
0195       alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_);
0196    }
0197 
0198    template<class Iterator>
0199    inline void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const
0200    {
0201       BOOST_ASSERT(n == 1);  (void)n;
0202       *p = v_;
0203    }
0204 
0205    const value_type &v_;
0206 };
0207 
0208 
0209 template<class Allocator>
0210 struct insert_move_proxy
0211 {
0212    typedef boost::container::allocator_traits<Allocator> alloc_traits;
0213    typedef typename alloc_traits::value_type value_type;
0214 
0215    BOOST_STATIC_CONSTEXPR bool single_value = true;
0216 
0217    inline explicit insert_move_proxy(value_type &v)
0218       :  v_(v)
0219    {}
0220 
0221    template<class Iterator>
0222    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const
0223    {
0224       BOOST_ASSERT(n == 1);  (void)n;
0225       alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) );
0226    }
0227 
0228    template<class Iterator>
0229    inline void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const
0230    {
0231       BOOST_ASSERT(n == 1);  (void)n;
0232       *p = ::boost::move(v_);
0233    }
0234 
0235    value_type &v_;
0236 };
0237 
0238 template<class It, class Allocator>
0239 inline insert_move_proxy<Allocator> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
0240 {
0241    return insert_move_proxy<Allocator>(v);
0242 }
0243 
0244 template<class It, class Allocator>
0245 inline insert_copy_proxy<Allocator> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
0246 {
0247    return insert_copy_proxy<Allocator>(v);
0248 }
0249 
0250 }}}   //namespace boost { namespace container { namespace dtl {
0251 
0252 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0253 
0254 #include <boost/container/detail/variadic_templates_tools.hpp>
0255 #include <boost/move/utility_core.hpp>
0256 
0257 namespace boost {
0258 namespace container {
0259 namespace dtl {
0260 
0261 template<class Allocator, class ...Args>
0262 struct insert_nonmovable_emplace_proxy
0263 {
0264    typedef boost::container::allocator_traits<Allocator>   alloc_traits;
0265    typedef typename alloc_traits::value_type       value_type;
0266    typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
0267 
0268    BOOST_STATIC_CONSTEXPR bool single_value = true;
0269 
0270    inline explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
0271       : args_(args...)
0272    {}
0273 
0274    template<class Iterator>
0275    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n)
0276    {  this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n);  }
0277 
0278    private:
0279    template<std::size_t ...IdxPack, class Iterator>
0280    inline void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n)
0281    {
0282       BOOST_ASSERT(n == 1); (void)n;
0283       alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
0284    }
0285 
0286    protected:
0287    tuple<Args&...> args_;
0288 };
0289 
0290 template<class Allocator, class ...Args>
0291 struct insert_emplace_proxy
0292    :  public insert_nonmovable_emplace_proxy<Allocator, Args...>
0293 {
0294    typedef insert_nonmovable_emplace_proxy<Allocator, Args...> base_t;
0295    typedef boost::container::allocator_traits<Allocator>   alloc_traits;
0296    typedef typename base_t::value_type             value_type;
0297    typedef typename base_t::index_tuple_t          index_tuple_t;
0298 
0299    BOOST_STATIC_CONSTEXPR bool single_value = true;
0300 
0301    inline explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
0302       : base_t(::boost::forward<Args>(args)...)
0303    {}
0304 
0305    template<class Iterator>
0306    inline void copy_n_and_update(Allocator &a, Iterator p, std::size_t n)
0307    {  this->priv_copy_some_and_update(a, index_tuple_t(), p, n);  }
0308 
0309    private:
0310 
0311    template<std::size_t ...IdxPack, class Iterator>
0312    inline void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n)
0313    {
0314       BOOST_ASSERT(n ==1); (void)n;
0315       typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
0316       alloc_traits::construct(a, (value_type*)&v, ::boost::forward<Args>(get<IdxPack>(this->args_))...);
0317       value_type *vp = move_detail::launder_cast<value_type *>(&v);
0318       BOOST_CONTAINER_TRY{
0319          *p = ::boost::move(*vp);
0320       }
0321       BOOST_CONTAINER_CATCH(...){
0322          alloc_traits::destroy(a, vp);
0323          BOOST_CONTAINER_RETHROW
0324       }
0325       BOOST_CONTAINER_CATCH_END
0326       alloc_traits::destroy(a, vp);
0327    }
0328 };
0329 
0330 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
0331 template<class Allocator>
0332 struct insert_emplace_proxy<Allocator, typename boost::container::allocator_traits<Allocator>::value_type>
0333    : public insert_move_proxy<Allocator>
0334 {
0335    BOOST_STATIC_CONSTEXPR bool single_value = true;
0336 
0337    inline explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
0338    : insert_move_proxy<Allocator>(v)
0339    {}
0340 };
0341 
0342 //We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
0343 //compiler error C2752 ("more than one partial specialization matches").
0344 //Any problem is solvable with an extra layer of indirection? ;-)
0345 template<class Allocator>
0346 struct insert_emplace_proxy<Allocator
0347    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
0348    >
0349    : public insert_copy_proxy<Allocator>
0350 {
0351 
0352    BOOST_STATIC_CONSTEXPR bool single_value = true;
0353 
0354    inline explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
0355    : insert_copy_proxy<Allocator>(v)
0356    {}
0357 };
0358 
0359 template<class Allocator>
0360 struct insert_emplace_proxy<Allocator, typename boost::container::allocator_traits<Allocator>::value_type &>
0361    : public insert_copy_proxy<Allocator>
0362 {
0363    BOOST_STATIC_CONSTEXPR bool single_value = true;
0364 
0365    inline explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
0366    : insert_copy_proxy<Allocator>(v)
0367    {}
0368 };
0369 
0370 template<class Allocator>
0371 struct insert_emplace_proxy<Allocator
0372    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
0373    >
0374    : public insert_copy_proxy<Allocator>
0375 {
0376    BOOST_STATIC_CONSTEXPR bool single_value = true;
0377 
0378    inline explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
0379    : insert_copy_proxy<Allocator>(v)
0380    {}
0381 };
0382 
0383 }}}   //namespace boost { namespace container { namespace dtl {
0384 
0385 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0386 
0387 #include <boost/container/detail/value_init.hpp>
0388 
0389 namespace boost {
0390 namespace container {
0391 namespace dtl {
0392 
0393 #define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
0394 template< class Allocator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
0395 struct insert_nonmovable_emplace_proxy##N\
0396 {\
0397    typedef boost::container::allocator_traits<Allocator> alloc_traits;\
0398    typedef typename alloc_traits::value_type value_type;\
0399    \
0400    BOOST_STATIC_CONSTEXPR bool single_value = true;\
0401    \
0402    inline explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
0403       BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
0404    \
0405    template<class Iterator>\
0406    inline void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\
0407    {\
0408       BOOST_ASSERT(n == 1); (void)n;\
0409       alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
0410    }\
0411    \
0412    template<class Iterator>\
0413    inline void copy_n_and_update(Allocator &, Iterator, std::size_t)\
0414    {  BOOST_ASSERT(false);   }\
0415    \
0416    protected:\
0417    BOOST_MOVE_MREF##N\
0418 };\
0419 \
0420 template< class Allocator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
0421 struct insert_emplace_proxy_arg##N\
0422    : insert_nonmovable_emplace_proxy##N< Allocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
0423 {\
0424    typedef insert_nonmovable_emplace_proxy##N\
0425       < Allocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
0426    typedef typename base_t::value_type value_type;\
0427    typedef boost::container::allocator_traits<Allocator> alloc_traits;\
0428    \
0429    BOOST_STATIC_CONSTEXPR bool single_value = true;\
0430    \
0431    inline explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
0432       : base_t(BOOST_MOVE_FWD##N){}\
0433    \
0434    template<class Iterator>\
0435    inline void copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\
0436    {\
0437       BOOST_ASSERT(n == 1); (void)n;\
0438       typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\
0439       alloc_traits::construct(a, (value_type*)&v BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
0440       value_type *vp = move_detail::launder_cast<value_type *>(&v);\
0441       BOOST_CONTAINER_TRY{\
0442          *p = ::boost::move(*vp);\
0443       }\
0444       BOOST_CONTAINER_CATCH(...){\
0445          alloc_traits::destroy(a, vp);\
0446          BOOST_CONTAINER_RETHROW\
0447       }\
0448       BOOST_CONTAINER_CATCH_END\
0449       alloc_traits::destroy(a, vp);\
0450    }\
0451 };\
0452 //
0453 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
0454 #undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
0455 
0456 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0457 
0458 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
0459 template<class Allocator>
0460 struct insert_emplace_proxy_arg1<Allocator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
0461    : public insert_move_proxy<Allocator>
0462 {
0463    BOOST_STATIC_CONSTEXPR bool single_value = true;
0464 
0465    inline explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
0466    : insert_move_proxy<Allocator>(v)
0467    {}
0468 };
0469 
0470 template<class Allocator>
0471 struct insert_emplace_proxy_arg1<Allocator, typename boost::container::allocator_traits<Allocator>::value_type>
0472    : public insert_copy_proxy<Allocator>
0473 {
0474    BOOST_STATIC_CONSTEXPR bool single_value = true;
0475 
0476    inline explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
0477    : insert_copy_proxy<Allocator>(v)
0478    {}
0479 };
0480 
0481 #else //e.g. MSVC10 & MSVC11
0482 
0483 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
0484 template<class Allocator>
0485 struct insert_emplace_proxy_arg1<Allocator, typename boost::container::allocator_traits<Allocator>::value_type>
0486    : public insert_move_proxy<Allocator>
0487 {
0488    BOOST_STATIC_CONSTEXPR bool single_value = true;
0489 
0490    inline explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
0491    : insert_move_proxy<Allocator>(v)
0492    {}
0493 };
0494 
0495 //We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
0496 //compiler error C2752 ("more than one partial specialization matches").
0497 //Any problem is solvable with an extra layer of indirection? ;-)
0498 template<class Allocator>
0499 struct insert_emplace_proxy_arg1<Allocator
0500    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
0501    >
0502    : public insert_copy_proxy<Allocator>
0503 {
0504    BOOST_STATIC_CONSTEXPR bool single_value = true;
0505 
0506    inline explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
0507    : insert_copy_proxy<Allocator>(v)
0508    {}
0509 };
0510 
0511 template<class Allocator>
0512 struct insert_emplace_proxy_arg1<Allocator, typename boost::container::allocator_traits<Allocator>::value_type &>
0513    : public insert_copy_proxy<Allocator>
0514 {
0515    BOOST_STATIC_CONSTEXPR bool single_value = true;
0516 
0517    inline explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
0518    : insert_copy_proxy<Allocator>(v)
0519    {}
0520 };
0521 
0522 template<class Allocator>
0523 struct insert_emplace_proxy_arg1<Allocator
0524    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
0525    >
0526    : public insert_copy_proxy<Allocator>
0527 {
0528   BOOST_STATIC_CONSTEXPR bool single_value = true;
0529 
0530    inline explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
0531    : insert_copy_proxy<Allocator>(v)
0532    {}
0533 };
0534 
0535 #endif
0536 
0537 }}}   //namespace boost { namespace container { namespace dtl {
0538 
0539 #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0540 
0541 #include <boost/container/detail/config_end.hpp>
0542 
0543 #endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP