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