File indexing completed on 2025-07-14 08:27:27
0001
0002
0003
0004
0005
0006
0007
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
0026 #include <boost/container/allocator_traits.hpp>
0027
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
0039
0040 #include <boost/move/utility_core.hpp>
0041 #include <boost/move/detail/force_ptr.hpp>
0042 #include <boost/move/detail/launder.hpp>
0043
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 }}}
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
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
0343
0344
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 }}}
0384
0385 #else
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
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
0482
0483
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
0496
0497
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 }}}
0538
0539 #endif
0540
0541 #include <boost/container/detail/config_end.hpp>
0542
0543 #endif