annotate DEPENDENCIES/generic/include/boost/container/detail/copy_move_algo.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 //////////////////////////////////////////////////////////////////////////////
Chris@102 2 //
Chris@102 3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
Chris@102 4 // Software License, Version 1.0. (See accompanying file
Chris@102 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@102 6 //
Chris@102 7 // See http://www.boost.org/libs/container for documentation.
Chris@102 8 //
Chris@102 9 //////////////////////////////////////////////////////////////////////////////
Chris@102 10 #ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
Chris@102 11 #define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
Chris@102 12
Chris@102 13 #ifndef BOOST_CONFIG_HPP
Chris@102 14 # include <boost/config.hpp>
Chris@102 15 #endif
Chris@102 16
Chris@102 17 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@102 18 # pragma once
Chris@102 19 #endif
Chris@102 20
Chris@102 21 // container
Chris@102 22 #include <boost/container/allocator_traits.hpp>
Chris@102 23 // container/detail
Chris@102 24 #include <boost/container/detail/iterator.hpp>
Chris@102 25 #include <boost/container/detail/iterator_to_raw_pointer.hpp>
Chris@102 26 #include <boost/container/detail/mpl.hpp>
Chris@102 27 #include <boost/container/detail/type_traits.hpp>
Chris@102 28 // move
Chris@102 29 #include <boost/move/adl_move_swap.hpp>
Chris@102 30 #include <boost/move/iterator.hpp>
Chris@102 31 #include <boost/move/utility_core.hpp>
Chris@102 32 // other
Chris@102 33 #include <boost/core/no_exceptions_support.hpp>
Chris@102 34 // std
Chris@102 35 #include <cstring> //for emmove/memcpy
Chris@102 36
Chris@102 37 namespace boost {
Chris@102 38 namespace container {
Chris@102 39 namespace container_detail {
Chris@102 40
Chris@102 41 template<class I>
Chris@102 42 struct are_elements_contiguous
Chris@102 43 {
Chris@102 44 static const bool value = false;
Chris@102 45 };
Chris@102 46
Chris@102 47 /////////////////////////
Chris@102 48 // raw pointers
Chris@102 49 /////////////////////////
Chris@102 50
Chris@102 51 template<class T>
Chris@102 52 struct are_elements_contiguous<T*>
Chris@102 53 {
Chris@102 54 static const bool value = true;
Chris@102 55 };
Chris@102 56
Chris@102 57 /////////////////////////
Chris@102 58 // move iterators
Chris@102 59 /////////////////////////
Chris@102 60
Chris@102 61 template<class It>
Chris@102 62 struct are_elements_contiguous< ::boost::move_iterator<It> >
Chris@102 63 : are_elements_contiguous<It>
Chris@102 64 {};
Chris@102 65
Chris@102 66 /////////////////////////
Chris@102 67 // predeclarations
Chris@102 68 /////////////////////////
Chris@102 69
Chris@102 70 #ifndef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
Chris@102 71
Chris@102 72 template<class Pointer>
Chris@102 73 class vector_iterator;
Chris@102 74
Chris@102 75 template<class Pointer>
Chris@102 76 class vector_const_iterator;
Chris@102 77
Chris@102 78 #endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
Chris@102 79
Chris@102 80 } //namespace container_detail {
Chris@102 81 } //namespace container {
Chris@102 82
Chris@102 83 namespace interprocess {
Chris@102 84
Chris@102 85 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
Chris@102 86 class offset_ptr;
Chris@102 87
Chris@102 88 } //namespace interprocess {
Chris@102 89
Chris@102 90 namespace container {
Chris@102 91
Chris@102 92 namespace container_detail {
Chris@102 93
Chris@102 94 /////////////////////////
Chris@102 95 //vector_[const_]iterator
Chris@102 96 /////////////////////////
Chris@102 97
Chris@102 98 #ifndef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
Chris@102 99
Chris@102 100 template<class Pointer>
Chris@102 101 struct are_elements_contiguous<boost::container::container_detail::vector_iterator<Pointer> >
Chris@102 102 {
Chris@102 103 static const bool value = true;
Chris@102 104 };
Chris@102 105
Chris@102 106 template<class Pointer>
Chris@102 107 struct are_elements_contiguous<boost::container::container_detail::vector_const_iterator<Pointer> >
Chris@102 108 {
Chris@102 109 static const bool value = true;
Chris@102 110 };
Chris@102 111
Chris@102 112 #endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
Chris@102 113
Chris@102 114 /////////////////////////
Chris@102 115 // offset_ptr
Chris@102 116 /////////////////////////
Chris@102 117
Chris@102 118 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
Chris@102 119 struct are_elements_contiguous< ::boost::interprocess::offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> >
Chris@102 120 {
Chris@102 121 static const bool value = true;
Chris@102 122 };
Chris@102 123
Chris@102 124 template <typename I, typename O>
Chris@102 125 struct are_contiguous_and_same
Chris@102 126 {
Chris@102 127 static const bool is_same_io =
Chris@102 128 is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
Chris@102 129 , typename ::boost::container::iterator_traits<O>::value_type
Chris@102 130 >::value;
Chris@102 131 static const bool value = is_same_io &&
Chris@102 132 are_elements_contiguous<I>::value &&
Chris@102 133 are_elements_contiguous<O>::value;
Chris@102 134 };
Chris@102 135
Chris@102 136 template <typename I, typename O>
Chris@102 137 struct is_memtransfer_copy_assignable
Chris@102 138 {
Chris@102 139 static const bool value = are_contiguous_and_same<I, O>::value &&
Chris@102 140 container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >::value;
Chris@102 141 };
Chris@102 142
Chris@102 143 template <typename I, typename O>
Chris@102 144 struct is_memtransfer_copy_constructible
Chris@102 145 {
Chris@102 146 static const bool value = are_contiguous_and_same<I, O>::value &&
Chris@102 147 container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >::value;
Chris@102 148 };
Chris@102 149
Chris@102 150 template <typename I, typename O, typename R>
Chris@102 151 struct enable_if_memtransfer_copy_constructible
Chris@102 152 : enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
Chris@102 153 {};
Chris@102 154
Chris@102 155 template <typename I, typename O, typename R>
Chris@102 156 struct disable_if_memtransfer_copy_constructible
Chris@102 157 : enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
Chris@102 158 {};
Chris@102 159
Chris@102 160 template <typename I, typename O, typename R>
Chris@102 161 struct enable_if_memtransfer_copy_assignable
Chris@102 162 : enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
Chris@102 163 {};
Chris@102 164
Chris@102 165 template <typename I, typename O, typename R>
Chris@102 166 struct disable_if_memtransfer_copy_assignable
Chris@102 167 : enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
Chris@102 168 {};
Chris@102 169
Chris@102 170 template
Chris@102 171 <typename I, // I models InputIterator
Chris@102 172 typename F> // F models ForwardIterator
Chris@102 173 inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 174 {
Chris@102 175 typedef typename boost::container::iterator_traits<I>::value_type value_type;
Chris@102 176 typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
Chris@102 177 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
Chris@102 178 boost::container::iterator_advance(r, n);
Chris@102 179 return r;
Chris@102 180 }
Chris@102 181
Chris@102 182 template
Chris@102 183 <typename I, // I models InputIterator
Chris@102 184 typename F> // F models ForwardIterator
Chris@102 185 F memmove_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 186 {
Chris@102 187 typedef typename boost::container::iterator_traits<I>::value_type value_type;
Chris@102 188 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
Chris@102 189 boost::container::iterator_advance(r, n);
Chris@102 190 return r;
Chris@102 191 }
Chris@102 192
Chris@102 193 template
Chris@102 194 <typename I, // I models InputIterator
Chris@102 195 typename F> // F models ForwardIterator
Chris@102 196 I memmove_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 197 {
Chris@102 198 typedef typename boost::container::iterator_traits<I>::value_type value_type;
Chris@102 199 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
Chris@102 200 boost::container::iterator_advance(f, n);
Chris@102 201 return f;
Chris@102 202 }
Chris@102 203
Chris@102 204 template
Chris@102 205 <typename I, // I models InputIterator
Chris@102 206 typename F> // F models ForwardIterator
Chris@102 207 I memmove_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 208 {
Chris@102 209 typedef typename boost::container::iterator_traits<I>::value_type value_type;
Chris@102 210 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
Chris@102 211 boost::container::iterator_advance(f, n);
Chris@102 212 boost::container::iterator_advance(r, n);
Chris@102 213 return f;
Chris@102 214 }
Chris@102 215
Chris@102 216 template <typename O>
Chris@102 217 struct is_memzero_initializable
Chris@102 218 {
Chris@102 219 typedef typename ::boost::container::iterator_traits<O>::value_type value_type;
Chris@102 220 static const bool value = are_elements_contiguous<O>::value &&
Chris@102 221 ( container_detail::is_integral<value_type>::value || container_detail::is_enum<value_type>::value
Chris@102 222 #if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
Chris@102 223 || container_detail::is_pointer<value_type>::value
Chris@102 224 #endif
Chris@102 225 #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO)
Chris@102 226 || container_detail::is_floating_point<value_type>::value
Chris@102 227 #endif
Chris@102 228 #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
Chris@102 229 || container_detail::is_pod<value_type>::value
Chris@102 230 #endif
Chris@102 231 );
Chris@102 232 };
Chris@102 233
Chris@102 234 template <typename O, typename R>
Chris@102 235 struct enable_if_memzero_initializable
Chris@102 236 : enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
Chris@102 237 {};
Chris@102 238
Chris@102 239 template <typename O, typename R>
Chris@102 240 struct disable_if_memzero_initializable
Chris@102 241 : enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
Chris@102 242 {};
Chris@102 243
Chris@102 244 template <typename I, typename R>
Chris@102 245 struct enable_if_trivially_destructible
Chris@102 246 : enable_if_c < false/*container_detail::is_trivially_destructible
Chris@102 247 <typename boost::container::iterator_traits<I>::value_type>::value*/
Chris@102 248 , R>
Chris@102 249 {};
Chris@102 250
Chris@102 251 template <typename I, typename R>
Chris@102 252 struct disable_if_trivially_destructible
Chris@102 253 : enable_if_c <true/*!container_detail::is_trivially_destructible
Chris@102 254 <typename boost::container::iterator_traits<I>::value_type>::value*/
Chris@102 255 , R>
Chris@102 256 {};
Chris@102 257
Chris@102 258 } //namespace container_detail {
Chris@102 259
Chris@102 260 //////////////////////////////////////////////////////////////////////////////
Chris@102 261 //
Chris@102 262 // uninitialized_move_alloc
Chris@102 263 //
Chris@102 264 //////////////////////////////////////////////////////////////////////////////
Chris@102 265
Chris@102 266
Chris@102 267 //! <b>Effects</b>:
Chris@102 268 //! \code
Chris@102 269 //! for (; f != l; ++r, ++f)
Chris@102 270 //! allocator_traits::construct(a, &*r, boost::move(*f));
Chris@102 271 //! \endcode
Chris@102 272 //!
Chris@102 273 //! <b>Returns</b>: r
Chris@102 274 template
Chris@102 275 <typename Allocator,
Chris@102 276 typename I, // I models InputIterator
Chris@102 277 typename F> // F models ForwardIterator
Chris@102 278 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 279 uninitialized_move_alloc(Allocator &a, I f, I l, F r)
Chris@102 280 {
Chris@102 281 F back = r;
Chris@102 282 BOOST_TRY{
Chris@102 283 while (f != l) {
Chris@102 284 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
Chris@102 285 ++f; ++r;
Chris@102 286 }
Chris@102 287 }
Chris@102 288 BOOST_CATCH(...){
Chris@102 289 for (; back != r; ++back){
Chris@102 290 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 291 }
Chris@102 292 BOOST_RETHROW;
Chris@102 293 }
Chris@102 294 BOOST_CATCH_END
Chris@102 295 return r;
Chris@102 296 }
Chris@102 297
Chris@102 298 template
Chris@102 299 <typename Allocator,
Chris@102 300 typename I, // I models InputIterator
Chris@102 301 typename F> // F models ForwardIterator
Chris@102 302 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 303 uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 304 { return container_detail::memmove(f, l, r); }
Chris@102 305
Chris@102 306 //////////////////////////////////////////////////////////////////////////////
Chris@102 307 //
Chris@102 308 // uninitialized_move_alloc_n
Chris@102 309 //
Chris@102 310 //////////////////////////////////////////////////////////////////////////////
Chris@102 311
Chris@102 312 //! <b>Effects</b>:
Chris@102 313 //! \code
Chris@102 314 //! for (; n--; ++r, ++f)
Chris@102 315 //! allocator_traits::construct(a, &*r, boost::move(*f));
Chris@102 316 //! \endcode
Chris@102 317 //!
Chris@102 318 //! <b>Returns</b>: r
Chris@102 319 template
Chris@102 320 <typename Allocator,
Chris@102 321 typename I, // I models InputIterator
Chris@102 322 typename F> // F models ForwardIterator
Chris@102 323 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 324 uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 325 {
Chris@102 326 F back = r;
Chris@102 327 BOOST_TRY{
Chris@102 328 while (n--) {
Chris@102 329 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
Chris@102 330 ++f; ++r;
Chris@102 331 }
Chris@102 332 }
Chris@102 333 BOOST_CATCH(...){
Chris@102 334 for (; back != r; ++back){
Chris@102 335 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 336 }
Chris@102 337 BOOST_RETHROW;
Chris@102 338 }
Chris@102 339 BOOST_CATCH_END
Chris@102 340 return r;
Chris@102 341 }
Chris@102 342
Chris@102 343 template
Chris@102 344 <typename Allocator,
Chris@102 345 typename I, // I models InputIterator
Chris@102 346 typename F> // F models ForwardIterator
Chris@102 347 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 348 uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 349 { return container_detail::memmove_n(f, n, r); }
Chris@102 350
Chris@102 351 //////////////////////////////////////////////////////////////////////////////
Chris@102 352 //
Chris@102 353 // uninitialized_move_alloc_n_source
Chris@102 354 //
Chris@102 355 //////////////////////////////////////////////////////////////////////////////
Chris@102 356
Chris@102 357 //! <b>Effects</b>:
Chris@102 358 //! \code
Chris@102 359 //! for (; n--; ++r, ++f)
Chris@102 360 //! allocator_traits::construct(a, &*r, boost::move(*f));
Chris@102 361 //! \endcode
Chris@102 362 //!
Chris@102 363 //! <b>Returns</b>: f (after incremented)
Chris@102 364 template
Chris@102 365 <typename Allocator,
Chris@102 366 typename I, // I models InputIterator
Chris@102 367 typename F> // F models ForwardIterator
Chris@102 368 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
Chris@102 369 uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 370 {
Chris@102 371 F back = r;
Chris@102 372 BOOST_TRY{
Chris@102 373 while (n--) {
Chris@102 374 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
Chris@102 375 ++f; ++r;
Chris@102 376 }
Chris@102 377 }
Chris@102 378 BOOST_CATCH(...){
Chris@102 379 for (; back != r; ++back){
Chris@102 380 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 381 }
Chris@102 382 BOOST_RETHROW;
Chris@102 383 }
Chris@102 384 BOOST_CATCH_END
Chris@102 385 return f;
Chris@102 386 }
Chris@102 387
Chris@102 388 template
Chris@102 389 <typename Allocator,
Chris@102 390 typename I, // I models InputIterator
Chris@102 391 typename F> // F models ForwardIterator
Chris@102 392 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
Chris@102 393 uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 394 { return container_detail::memmove_n_source(f, n, r); }
Chris@102 395
Chris@102 396 //////////////////////////////////////////////////////////////////////////////
Chris@102 397 //
Chris@102 398 // uninitialized_copy_alloc
Chris@102 399 //
Chris@102 400 //////////////////////////////////////////////////////////////////////////////
Chris@102 401
Chris@102 402 //! <b>Effects</b>:
Chris@102 403 //! \code
Chris@102 404 //! for (; f != l; ++r, ++f)
Chris@102 405 //! allocator_traits::construct(a, &*r, *f);
Chris@102 406 //! \endcode
Chris@102 407 //!
Chris@102 408 //! <b>Returns</b>: r
Chris@102 409 template
Chris@102 410 <typename Allocator,
Chris@102 411 typename I, // I models InputIterator
Chris@102 412 typename F> // F models ForwardIterator
Chris@102 413 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 414 uninitialized_copy_alloc(Allocator &a, I f, I l, F r)
Chris@102 415 {
Chris@102 416 F back = r;
Chris@102 417 BOOST_TRY{
Chris@102 418 while (f != l) {
Chris@102 419 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
Chris@102 420 ++f; ++r;
Chris@102 421 }
Chris@102 422 }
Chris@102 423 BOOST_CATCH(...){
Chris@102 424 for (; back != r; ++back){
Chris@102 425 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 426 }
Chris@102 427 BOOST_RETHROW;
Chris@102 428 }
Chris@102 429 BOOST_CATCH_END
Chris@102 430 return r;
Chris@102 431 }
Chris@102 432
Chris@102 433 template
Chris@102 434 <typename Allocator,
Chris@102 435 typename I, // I models InputIterator
Chris@102 436 typename F> // F models ForwardIterator
Chris@102 437 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 438 uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 439 { return container_detail::memmove(f, l, r); }
Chris@102 440
Chris@102 441 //////////////////////////////////////////////////////////////////////////////
Chris@102 442 //
Chris@102 443 // uninitialized_copy_alloc_n
Chris@102 444 //
Chris@102 445 //////////////////////////////////////////////////////////////////////////////
Chris@102 446
Chris@102 447 //! <b>Effects</b>:
Chris@102 448 //! \code
Chris@102 449 //! for (; n--; ++r, ++f)
Chris@102 450 //! allocator_traits::construct(a, &*r, *f);
Chris@102 451 //! \endcode
Chris@102 452 //!
Chris@102 453 //! <b>Returns</b>: r
Chris@102 454 template
Chris@102 455 <typename Allocator,
Chris@102 456 typename I, // I models InputIterator
Chris@102 457 typename F> // F models ForwardIterator
Chris@102 458 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 459 uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 460 {
Chris@102 461 F back = r;
Chris@102 462 BOOST_TRY{
Chris@102 463 while (n--) {
Chris@102 464 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
Chris@102 465 ++f; ++r;
Chris@102 466 }
Chris@102 467 }
Chris@102 468 BOOST_CATCH(...){
Chris@102 469 for (; back != r; ++back){
Chris@102 470 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 471 }
Chris@102 472 BOOST_RETHROW;
Chris@102 473 }
Chris@102 474 BOOST_CATCH_END
Chris@102 475 return r;
Chris@102 476 }
Chris@102 477
Chris@102 478 template
Chris@102 479 <typename Allocator,
Chris@102 480 typename I, // I models InputIterator
Chris@102 481 typename F> // F models ForwardIterator
Chris@102 482 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
Chris@102 483 uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 484 { return container_detail::memmove_n(f, n, r); }
Chris@102 485
Chris@102 486 //////////////////////////////////////////////////////////////////////////////
Chris@102 487 //
Chris@102 488 // uninitialized_copy_alloc_n_source
Chris@102 489 //
Chris@102 490 //////////////////////////////////////////////////////////////////////////////
Chris@102 491
Chris@102 492 //! <b>Effects</b>:
Chris@102 493 //! \code
Chris@102 494 //! for (; n--; ++r, ++f)
Chris@102 495 //! allocator_traits::construct(a, &*r, *f);
Chris@102 496 //! \endcode
Chris@102 497 //!
Chris@102 498 //! <b>Returns</b>: f (after incremented)
Chris@102 499 template
Chris@102 500 <typename Allocator,
Chris@102 501 typename I, // I models InputIterator
Chris@102 502 typename F> // F models ForwardIterator
Chris@102 503 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
Chris@102 504 uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 505 {
Chris@102 506 F back = r;
Chris@102 507 BOOST_TRY{
Chris@102 508 while (n--) {
Chris@102 509 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
Chris@102 510 ++f; ++r;
Chris@102 511 }
Chris@102 512 }
Chris@102 513 BOOST_CATCH(...){
Chris@102 514 for (; back != r; ++back){
Chris@102 515 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 516 }
Chris@102 517 BOOST_RETHROW;
Chris@102 518 }
Chris@102 519 BOOST_CATCH_END
Chris@102 520 return f;
Chris@102 521 }
Chris@102 522
Chris@102 523 template
Chris@102 524 <typename Allocator,
Chris@102 525 typename I, // I models InputIterator
Chris@102 526 typename F> // F models ForwardIterator
Chris@102 527 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
Chris@102 528 uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 529 { return container_detail::memmove_n_source(f, n, r); }
Chris@102 530
Chris@102 531 //////////////////////////////////////////////////////////////////////////////
Chris@102 532 //
Chris@102 533 // uninitialized_value_init_alloc_n
Chris@102 534 //
Chris@102 535 //////////////////////////////////////////////////////////////////////////////
Chris@102 536
Chris@102 537 //! <b>Effects</b>:
Chris@102 538 //! \code
Chris@102 539 //! for (; n--; ++r, ++f)
Chris@102 540 //! allocator_traits::construct(a, &*r);
Chris@102 541 //! \endcode
Chris@102 542 //!
Chris@102 543 //! <b>Returns</b>: r
Chris@102 544 template
Chris@102 545 <typename Allocator,
Chris@102 546 typename F> // F models ForwardIterator
Chris@102 547 inline typename container_detail::disable_if_memzero_initializable<F, F>::type
Chris@102 548 uninitialized_value_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
Chris@102 549 {
Chris@102 550 F back = r;
Chris@102 551 BOOST_TRY{
Chris@102 552 while (n--) {
Chris@102 553 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r));
Chris@102 554 ++r;
Chris@102 555 }
Chris@102 556 }
Chris@102 557 BOOST_CATCH(...){
Chris@102 558 for (; back != r; ++back){
Chris@102 559 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 560 }
Chris@102 561 BOOST_RETHROW;
Chris@102 562 }
Chris@102 563 BOOST_CATCH_END
Chris@102 564 return r;
Chris@102 565 }
Chris@102 566
Chris@102 567 template
Chris@102 568 <typename Allocator,
Chris@102 569 typename F> // F models ForwardIterator
Chris@102 570 inline typename container_detail::enable_if_memzero_initializable<F, F>::type
Chris@102 571 uninitialized_value_init_alloc_n(Allocator &, typename allocator_traits<Allocator>::difference_type n, F r)
Chris@102 572 {
Chris@102 573 typedef typename boost::container::iterator_traits<F>::value_type value_type;
Chris@102 574 std::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
Chris@102 575 boost::container::iterator_advance(r, n);
Chris@102 576 return r;
Chris@102 577 }
Chris@102 578
Chris@102 579 //////////////////////////////////////////////////////////////////////////////
Chris@102 580 //
Chris@102 581 // uninitialized_default_init_alloc_n
Chris@102 582 //
Chris@102 583 //////////////////////////////////////////////////////////////////////////////
Chris@102 584
Chris@102 585 //! <b>Effects</b>:
Chris@102 586 //! \code
Chris@102 587 //! for (; n--; ++r, ++f)
Chris@102 588 //! allocator_traits::construct(a, &*r);
Chris@102 589 //! \endcode
Chris@102 590 //!
Chris@102 591 //! <b>Returns</b>: r
Chris@102 592 template
Chris@102 593 <typename Allocator,
Chris@102 594 typename F> // F models ForwardIterator
Chris@102 595 inline F uninitialized_default_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
Chris@102 596 {
Chris@102 597 F back = r;
Chris@102 598 BOOST_TRY{
Chris@102 599 while (n--) {
Chris@102 600 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
Chris@102 601 ++r;
Chris@102 602 }
Chris@102 603 }
Chris@102 604 BOOST_CATCH(...){
Chris@102 605 for (; back != r; ++back){
Chris@102 606 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 607 }
Chris@102 608 BOOST_RETHROW;
Chris@102 609 }
Chris@102 610 BOOST_CATCH_END
Chris@102 611 return r;
Chris@102 612 }
Chris@102 613
Chris@102 614 //////////////////////////////////////////////////////////////////////////////
Chris@102 615 //
Chris@102 616 // uninitialized_fill_alloc
Chris@102 617 //
Chris@102 618 //////////////////////////////////////////////////////////////////////////////
Chris@102 619
Chris@102 620 //! <b>Effects</b>:
Chris@102 621 //! \code
Chris@102 622 //! for (; f != l; ++r, ++f)
Chris@102 623 //! allocator_traits::construct(a, &*r, *f);
Chris@102 624 //! \endcode
Chris@102 625 //!
Chris@102 626 //! <b>Returns</b>: r
Chris@102 627 template
Chris@102 628 <typename Allocator,
Chris@102 629 typename F, // F models ForwardIterator
Chris@102 630 typename T>
Chris@102 631 inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t)
Chris@102 632 {
Chris@102 633 F back = f;
Chris@102 634 BOOST_TRY{
Chris@102 635 while (f != l) {
Chris@102 636 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
Chris@102 637 ++f;
Chris@102 638 }
Chris@102 639 }
Chris@102 640 BOOST_CATCH(...){
Chris@102 641 for (; back != l; ++back){
Chris@102 642 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 643 }
Chris@102 644 BOOST_RETHROW;
Chris@102 645 }
Chris@102 646 BOOST_CATCH_END
Chris@102 647 }
Chris@102 648
Chris@102 649
Chris@102 650 //////////////////////////////////////////////////////////////////////////////
Chris@102 651 //
Chris@102 652 // uninitialized_fill_alloc_n
Chris@102 653 //
Chris@102 654 //////////////////////////////////////////////////////////////////////////////
Chris@102 655
Chris@102 656 //! <b>Effects</b>:
Chris@102 657 //! \code
Chris@102 658 //! for (; n--; ++r, ++f)
Chris@102 659 //! allocator_traits::construct(a, &*r, v);
Chris@102 660 //! \endcode
Chris@102 661 //!
Chris@102 662 //! <b>Returns</b>: r
Chris@102 663 template
Chris@102 664 <typename Allocator,
Chris@102 665 typename T,
Chris@102 666 typename F> // F models ForwardIterator
Chris@102 667 inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename allocator_traits<Allocator>::difference_type n, F r)
Chris@102 668 {
Chris@102 669 F back = r;
Chris@102 670 BOOST_TRY{
Chris@102 671 while (n--) {
Chris@102 672 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
Chris@102 673 ++r;
Chris@102 674 }
Chris@102 675 }
Chris@102 676 BOOST_CATCH(...){
Chris@102 677 for (; back != r; ++back){
Chris@102 678 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
Chris@102 679 }
Chris@102 680 BOOST_RETHROW;
Chris@102 681 }
Chris@102 682 BOOST_CATCH_END
Chris@102 683 return r;
Chris@102 684 }
Chris@102 685
Chris@102 686 //////////////////////////////////////////////////////////////////////////////
Chris@102 687 //
Chris@102 688 // copy
Chris@102 689 //
Chris@102 690 //////////////////////////////////////////////////////////////////////////////
Chris@102 691
Chris@102 692 template
Chris@102 693 <typename I, // I models InputIterator
Chris@102 694 typename F> // F models ForwardIterator
Chris@102 695 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 696 copy(I f, I l, F r)
Chris@102 697 {
Chris@102 698 while (f != l) {
Chris@102 699 *r = *f;
Chris@102 700 ++f; ++r;
Chris@102 701 }
Chris@102 702 return r;
Chris@102 703 }
Chris@102 704
Chris@102 705 template
Chris@102 706 <typename I, // I models InputIterator
Chris@102 707 typename F> // F models ForwardIterator
Chris@102 708 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 709 copy(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 710 { return container_detail::memmove(f, l, r); }
Chris@102 711
Chris@102 712 //////////////////////////////////////////////////////////////////////////////
Chris@102 713 //
Chris@102 714 // copy_n
Chris@102 715 //
Chris@102 716 //////////////////////////////////////////////////////////////////////////////
Chris@102 717
Chris@102 718 template
Chris@102 719 <typename I, // I models InputIterator
Chris@102 720 typename F> // F models ForwardIterator
Chris@102 721 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 722 copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 723 {
Chris@102 724 while (n--) {
Chris@102 725 *r = *f;
Chris@102 726 ++f; ++r;
Chris@102 727 }
Chris@102 728 return r;
Chris@102 729 }
Chris@102 730
Chris@102 731 template
Chris@102 732 <typename I, // I models InputIterator
Chris@102 733 typename F> // F models ForwardIterator
Chris@102 734 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 735 copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 736 { return container_detail::memmove_n(f, n, r); }
Chris@102 737
Chris@102 738 //////////////////////////////////////////////////////////////////////////////
Chris@102 739 //
Chris@102 740 // copy_n_source
Chris@102 741 //
Chris@102 742 //////////////////////////////////////////////////////////////////////////////
Chris@102 743
Chris@102 744 template
Chris@102 745 <typename I, // I models InputIterator
Chris@102 746 typename F> // F models ForwardIterator
Chris@102 747 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 748 copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 749 {
Chris@102 750 while (n--) {
Chris@102 751 *r = *f;
Chris@102 752 ++f; ++r;
Chris@102 753 }
Chris@102 754 return f;
Chris@102 755 }
Chris@102 756
Chris@102 757 template
Chris@102 758 <typename I, // I models InputIterator
Chris@102 759 typename F> // F models ForwardIterator
Chris@102 760 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 761 copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 762 { return container_detail::memmove_n_source(f, n, r); }
Chris@102 763
Chris@102 764 //////////////////////////////////////////////////////////////////////////////
Chris@102 765 //
Chris@102 766 // copy_n_source_dest
Chris@102 767 //
Chris@102 768 //////////////////////////////////////////////////////////////////////////////
Chris@102 769
Chris@102 770 template
Chris@102 771 <typename I, // I models InputIterator
Chris@102 772 typename F> // F models ForwardIterator
Chris@102 773 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 774 copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
Chris@102 775 {
Chris@102 776 while (n--) {
Chris@102 777 *r = *f;
Chris@102 778 ++f; ++r;
Chris@102 779 }
Chris@102 780 return f;
Chris@102 781 }
Chris@102 782
Chris@102 783 template
Chris@102 784 <typename I, // I models InputIterator
Chris@102 785 typename F> // F models ForwardIterator
Chris@102 786 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 787 copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 788 { return container_detail::memmove_n_source_dest(f, n, r); }
Chris@102 789
Chris@102 790 //////////////////////////////////////////////////////////////////////////////
Chris@102 791 //
Chris@102 792 // move
Chris@102 793 //
Chris@102 794 //////////////////////////////////////////////////////////////////////////////
Chris@102 795
Chris@102 796 template
Chris@102 797 <typename I, // I models InputIterator
Chris@102 798 typename F> // F models ForwardIterator
Chris@102 799 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 800 move(I f, I l, F r)
Chris@102 801 {
Chris@102 802 while (f != l) {
Chris@102 803 *r = ::boost::move(*f);
Chris@102 804 ++f; ++r;
Chris@102 805 }
Chris@102 806 return r;
Chris@102 807 }
Chris@102 808
Chris@102 809 template
Chris@102 810 <typename I, // I models InputIterator
Chris@102 811 typename F> // F models ForwardIterator
Chris@102 812 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 813 move(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 814 { return container_detail::memmove(f, l, r); }
Chris@102 815
Chris@102 816 //////////////////////////////////////////////////////////////////////////////
Chris@102 817 //
Chris@102 818 // move_n
Chris@102 819 //
Chris@102 820 //////////////////////////////////////////////////////////////////////////////
Chris@102 821
Chris@102 822 template
Chris@102 823 <typename I, // I models InputIterator
Chris@102 824 typename F> // F models ForwardIterator
Chris@102 825 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 826 move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 827 {
Chris@102 828 while (n--) {
Chris@102 829 *r = ::boost::move(*f);
Chris@102 830 ++f; ++r;
Chris@102 831 }
Chris@102 832 return r;
Chris@102 833 }
Chris@102 834
Chris@102 835 template
Chris@102 836 <typename I, // I models InputIterator
Chris@102 837 typename F> // F models ForwardIterator
Chris@102 838 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 839 move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 840 { return container_detail::memmove_n(f, n, r); }
Chris@102 841
Chris@102 842
Chris@102 843 //////////////////////////////////////////////////////////////////////////////
Chris@102 844 //
Chris@102 845 // move_backward
Chris@102 846 //
Chris@102 847 //////////////////////////////////////////////////////////////////////////////
Chris@102 848
Chris@102 849 template
Chris@102 850 <typename I, // I models BidirectionalIterator
Chris@102 851 typename F> // F models ForwardIterator
Chris@102 852 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 853 move_backward(I f, I l, F r)
Chris@102 854 {
Chris@102 855 while (f != l) {
Chris@102 856 --l; --r;
Chris@102 857 *r = ::boost::move(*l);
Chris@102 858 }
Chris@102 859 return r;
Chris@102 860 }
Chris@102 861
Chris@102 862 template
Chris@102 863 <typename I, // I models InputIterator
Chris@102 864 typename F> // F models ForwardIterator
Chris@102 865 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
Chris@102 866 move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 867 {
Chris@102 868 typedef typename boost::container::iterator_traits<I>::value_type value_type;
Chris@102 869 const typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
Chris@102 870 r -= n;
Chris@102 871 std::memmove((container_detail::iterator_to_raw_pointer)(r), (container_detail::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
Chris@102 872 return r;
Chris@102 873 }
Chris@102 874
Chris@102 875 //////////////////////////////////////////////////////////////////////////////
Chris@102 876 //
Chris@102 877 // move_n_source_dest
Chris@102 878 //
Chris@102 879 //////////////////////////////////////////////////////////////////////////////
Chris@102 880
Chris@102 881 template
Chris@102 882 <typename I // I models InputIterator
Chris@102 883 ,typename F> // F models ForwardIterator
Chris@102 884 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 885 move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
Chris@102 886 {
Chris@102 887 while (n--) {
Chris@102 888 *r = ::boost::move(*f);
Chris@102 889 ++f; ++r;
Chris@102 890 }
Chris@102 891 return f;
Chris@102 892 }
Chris@102 893
Chris@102 894 template
Chris@102 895 <typename I // I models InputIterator
Chris@102 896 ,typename F> // F models ForwardIterator
Chris@102 897 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 898 move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 899 { return container_detail::memmove_n_source_dest(f, n, r); }
Chris@102 900
Chris@102 901 //////////////////////////////////////////////////////////////////////////////
Chris@102 902 //
Chris@102 903 // move_n_source
Chris@102 904 //
Chris@102 905 //////////////////////////////////////////////////////////////////////////////
Chris@102 906
Chris@102 907 template
Chris@102 908 <typename I // I models InputIterator
Chris@102 909 ,typename F> // F models ForwardIterator
Chris@102 910 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 911 move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
Chris@102 912 {
Chris@102 913 while (n--) {
Chris@102 914 *r = ::boost::move(*f);
Chris@102 915 ++f; ++r;
Chris@102 916 }
Chris@102 917 return f;
Chris@102 918 }
Chris@102 919
Chris@102 920 template
Chris@102 921 <typename I // I models InputIterator
Chris@102 922 ,typename F> // F models ForwardIterator
Chris@102 923 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
Chris@102 924 move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 925 { return container_detail::memmove_n_source(f, n, r); }
Chris@102 926
Chris@102 927 //////////////////////////////////////////////////////////////////////////////
Chris@102 928 //
Chris@102 929 // destroy_alloc_n
Chris@102 930 //
Chris@102 931 //////////////////////////////////////////////////////////////////////////////
Chris@102 932
Chris@102 933 template
Chris@102 934 <typename Allocator
Chris@102 935 ,typename I // I models InputIterator
Chris@102 936 ,typename U> // U models unsigned integral constant
Chris@102 937 inline typename container_detail::disable_if_trivially_destructible<I, void>::type
Chris@102 938 destroy_alloc_n(Allocator &a, I f, U n)
Chris@102 939 {
Chris@102 940 while(n--){
Chris@102 941 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(f));
Chris@102 942 ++f;
Chris@102 943 }
Chris@102 944 }
Chris@102 945
Chris@102 946 template
Chris@102 947 <typename Allocator
Chris@102 948 ,typename I // I models InputIterator
Chris@102 949 ,typename U> // U models unsigned integral constant
Chris@102 950 inline typename container_detail::enable_if_trivially_destructible<I, void>::type
Chris@102 951 destroy_alloc_n(Allocator &, I, U)
Chris@102 952 {}
Chris@102 953
Chris@102 954 //////////////////////////////////////////////////////////////////////////////
Chris@102 955 //
Chris@102 956 // deep_swap_alloc_n
Chris@102 957 //
Chris@102 958 //////////////////////////////////////////////////////////////////////////////
Chris@102 959
Chris@102 960 template
Chris@102 961 <std::size_t MaxTmpBytes
Chris@102 962 ,typename Allocator
Chris@102 963 ,typename F // F models ForwardIterator
Chris@102 964 ,typename G // G models ForwardIterator
Chris@102 965 >
Chris@102 966 inline typename container_detail::disable_if_memtransfer_copy_assignable<F, G, void>::type
Chris@102 967 deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
Chris@102 968 , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
Chris@102 969 {
Chris@102 970 typename allocator_traits<Allocator>::size_type n = 0;
Chris@102 971 for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){
Chris@102 972 boost::adl_move_swap(*short_range_f, *large_range_f);
Chris@102 973 }
Chris@102 974 boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
Chris@102 975 boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
Chris@102 976 }
Chris@102 977
Chris@102 978 static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes
Chris@102 979
Chris@102 980 template
Chris@102 981 <std::size_t MaxTmpBytes
Chris@102 982 ,typename Allocator
Chris@102 983 ,typename F // F models ForwardIterator
Chris@102 984 ,typename G // G models ForwardIterator
Chris@102 985 >
Chris@102 986 inline typename container_detail::enable_if_c
Chris@102 987 < container_detail::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
Chris@102 988 , void>::type
Chris@102 989 deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
Chris@102 990 , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
Chris@102 991 {
Chris@102 992 typedef typename allocator_traits<Allocator>::value_type value_type;
Chris@102 993 typedef typename container_detail::aligned_storage
Chris@102 994 <MaxTmpBytes, container_detail::alignment_of<value_type>::value>::type storage_type;
Chris@102 995 storage_type storage;
Chris@102 996
Chris@102 997 const std::size_t n_i_bytes = sizeof(value_type)*n_i;
Chris@102 998 void *const large_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(large_range_f));
Chris@102 999 void *const short_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f));
Chris@102 1000 void *const stora_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(storage));
Chris@102 1001 std::memcpy(stora_ptr, large_ptr, n_i_bytes);
Chris@102 1002 std::memcpy(large_ptr, short_ptr, n_i_bytes);
Chris@102 1003 std::memcpy(short_ptr, stora_ptr, n_i_bytes);
Chris@102 1004 boost::container::iterator_advance(large_range_f, n_i);
Chris@102 1005 boost::container::iterator_advance(short_range_f, n_i);
Chris@102 1006 boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
Chris@102 1007 boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
Chris@102 1008 }
Chris@102 1009
Chris@102 1010 template
Chris@102 1011 <std::size_t MaxTmpBytes
Chris@102 1012 ,typename Allocator
Chris@102 1013 ,typename F // F models ForwardIterator
Chris@102 1014 ,typename G // G models ForwardIterator
Chris@102 1015 >
Chris@102 1016 inline typename container_detail::enable_if_c
Chris@102 1017 < container_detail::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
Chris@102 1018 , void>::type
Chris@102 1019 deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
Chris@102 1020 , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
Chris@102 1021 {
Chris@102 1022 typedef typename allocator_traits<Allocator>::value_type value_type;
Chris@102 1023 typedef typename container_detail::aligned_storage
Chris@102 1024 <DeepSwapAllocNMaxStorage, container_detail::alignment_of<value_type>::value>::type storage_type;
Chris@102 1025 storage_type storage;
Chris@102 1026 const std::size_t sizeof_storage = sizeof(storage);
Chris@102 1027
Chris@102 1028 std::size_t n_i_bytes = sizeof(value_type)*n_i;
Chris@102 1029 char *large_ptr = static_cast<char*>(static_cast<void*>(container_detail::iterator_to_raw_pointer(large_range_f)));
Chris@102 1030 char *short_ptr = static_cast<char*>(static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f)));
Chris@102 1031 char *stora_ptr = static_cast<char*>(static_cast<void*>(&storage));
Chris@102 1032
Chris@102 1033 std::size_t szt_times = n_i_bytes/sizeof_storage;
Chris@102 1034 const std::size_t szt_rem = n_i_bytes%sizeof_storage;
Chris@102 1035
Chris@102 1036 //Loop unrolling using Duff's device, as it seems it helps on some architectures
Chris@102 1037 const std::size_t Unroll = 4;
Chris@102 1038 std::size_t n = (szt_times + (Unroll-1))/Unroll;
Chris@102 1039 const std::size_t branch_number = (!szt_times)*Unroll + (szt_times % Unroll);
Chris@102 1040 switch(branch_number){
Chris@102 1041 case 4:
Chris@102 1042 break;
Chris@102 1043 case 0: do{
Chris@102 1044 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
Chris@102 1045 std::memcpy(large_ptr, short_ptr, sizeof_storage);
Chris@102 1046 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
Chris@102 1047 large_ptr += sizeof_storage;
Chris@102 1048 short_ptr += sizeof_storage;
Chris@102 1049 BOOST_CONTAINER_FALLTHOUGH
Chris@102 1050 case 3:
Chris@102 1051 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
Chris@102 1052 std::memcpy(large_ptr, short_ptr, sizeof_storage);
Chris@102 1053 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
Chris@102 1054 large_ptr += sizeof_storage;
Chris@102 1055 short_ptr += sizeof_storage;
Chris@102 1056 BOOST_CONTAINER_FALLTHOUGH
Chris@102 1057 case 2:
Chris@102 1058 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
Chris@102 1059 std::memcpy(large_ptr, short_ptr, sizeof_storage);
Chris@102 1060 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
Chris@102 1061 large_ptr += sizeof_storage;
Chris@102 1062 short_ptr += sizeof_storage;
Chris@102 1063 BOOST_CONTAINER_FALLTHOUGH
Chris@102 1064 case 1:
Chris@102 1065 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
Chris@102 1066 std::memcpy(large_ptr, short_ptr, sizeof_storage);
Chris@102 1067 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
Chris@102 1068 large_ptr += sizeof_storage;
Chris@102 1069 short_ptr += sizeof_storage;
Chris@102 1070 } while(--n);
Chris@102 1071 }
Chris@102 1072 std::memcpy(stora_ptr, large_ptr, szt_rem);
Chris@102 1073 std::memcpy(large_ptr, short_ptr, szt_rem);
Chris@102 1074 std::memcpy(short_ptr, stora_ptr, szt_rem);
Chris@102 1075 boost::container::iterator_advance(large_range_f, n_i);
Chris@102 1076 boost::container::iterator_advance(short_range_f, n_i);
Chris@102 1077 boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
Chris@102 1078 boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
Chris@102 1079 }
Chris@102 1080
Chris@102 1081
Chris@102 1082 //////////////////////////////////////////////////////////////////////////////
Chris@102 1083 //
Chris@102 1084 // copy_assign_range_alloc_n
Chris@102 1085 //
Chris@102 1086 //////////////////////////////////////////////////////////////////////////////
Chris@102 1087
Chris@102 1088 template
Chris@102 1089 <typename Allocator
Chris@102 1090 ,typename I // F models InputIterator
Chris@102 1091 ,typename O // G models OutputIterator
Chris@102 1092 >
Chris@102 1093 void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
Chris@102 1094 , O out_start, typename allocator_traits<Allocator>::size_type n_o )
Chris@102 1095 {
Chris@102 1096 if (n_o < n_i){
Chris@102 1097 inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw
Chris@102 1098 boost::container::uninitialized_copy_alloc_n(a, inp_start, n_i - n_o, out_start);// may throw
Chris@102 1099 }
Chris@102 1100 else{
Chris@102 1101 out_start = boost::container::copy_n(inp_start, n_i, out_start); // may throw
Chris@102 1102 boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
Chris@102 1103 }
Chris@102 1104 }
Chris@102 1105
Chris@102 1106 //////////////////////////////////////////////////////////////////////////////
Chris@102 1107 //
Chris@102 1108 // move_assign_range_alloc_n
Chris@102 1109 //
Chris@102 1110 //////////////////////////////////////////////////////////////////////////////
Chris@102 1111
Chris@102 1112 template
Chris@102 1113 <typename Allocator
Chris@102 1114 ,typename I // F models InputIterator
Chris@102 1115 ,typename O // G models OutputIterator
Chris@102 1116 >
Chris@102 1117 void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
Chris@102 1118 , O out_start, typename allocator_traits<Allocator>::size_type n_o )
Chris@102 1119 {
Chris@102 1120 if (n_o < n_i){
Chris@102 1121 inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw
Chris@102 1122 boost::container::uninitialized_move_alloc_n(a, inp_start, n_i - n_o, out_start); // may throw
Chris@102 1123 }
Chris@102 1124 else{
Chris@102 1125 out_start = boost::container::move_n(inp_start, n_i, out_start); // may throw
Chris@102 1126 boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
Chris@102 1127 }
Chris@102 1128 }
Chris@102 1129
Chris@102 1130 } //namespace container {
Chris@102 1131 } //namespace boost {
Chris@102 1132
Chris@102 1133 #endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP