annotate DEPENDENCIES/generic/include/boost/geometry/index/detail/varray_detail.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 c530137014c0
children
rev   line source
Chris@16 1 // Boost.Geometry
Chris@16 2 //
Chris@16 3 // varray details
Chris@16 4 //
Chris@101 5 // Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
Chris@16 6 // Copyright (c) 2011-2013 Andrew Hundt.
Chris@16 7 //
Chris@16 8 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 10 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 11
Chris@16 12 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
Chris@16 13 #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
Chris@16 14
Chris@16 15 #include <cstddef>
Chris@16 16 #include <cstring>
Chris@16 17 #include <memory>
Chris@16 18 #include <limits>
Chris@16 19
Chris@16 20 #include <boost/mpl/if.hpp>
Chris@16 21 #include <boost/mpl/and.hpp>
Chris@16 22 #include <boost/mpl/or.hpp>
Chris@16 23 #include <boost/mpl/int.hpp>
Chris@16 24
Chris@16 25 #include <boost/type_traits/is_same.hpp>
Chris@16 26 #include <boost/type_traits/remove_const.hpp>
Chris@16 27 #include <boost/type_traits/remove_reference.hpp>
Chris@16 28 #include <boost/type_traits/has_trivial_assign.hpp>
Chris@16 29 #include <boost/type_traits/has_trivial_copy.hpp>
Chris@16 30 #include <boost/type_traits/has_trivial_constructor.hpp>
Chris@16 31 #include <boost/type_traits/has_trivial_destructor.hpp>
Chris@16 32 #include <boost/type_traits/has_trivial_move_constructor.hpp>
Chris@16 33 #include <boost/type_traits/has_trivial_move_assign.hpp>
Chris@16 34 //#include <boost/type_traits/has_nothrow_constructor.hpp>
Chris@16 35 //#include <boost/type_traits/has_nothrow_copy.hpp>
Chris@16 36 //#include <boost/type_traits/has_nothrow_assign.hpp>
Chris@16 37 //#include <boost/type_traits/has_nothrow_destructor.hpp>
Chris@16 38
Chris@16 39 #include <boost/detail/no_exceptions_support.hpp>
Chris@16 40 #include <boost/config.hpp>
Chris@16 41 #include <boost/move/move.hpp>
Chris@101 42 #include <boost/core/addressof.hpp>
Chris@16 43 #include <boost/iterator/iterator_traits.hpp>
Chris@16 44
Chris@101 45 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@101 46 #include <boost/move/detail/fwd_macros.hpp>
Chris@101 47 #endif
Chris@101 48
Chris@16 49 // TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
Chris@16 50
Chris@16 51 #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
Chris@16 52 #include <vector>
Chris@16 53 #include <boost/container/vector.hpp>
Chris@16 54 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
Chris@16 55
Chris@16 56 namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail {
Chris@16 57
Chris@16 58 template <typename I>
Chris@16 59 struct are_elements_contiguous : boost::is_pointer<I>
Chris@16 60 {};
Chris@16 61
Chris@16 62 // EXPERIMENTAL - not finished
Chris@16 63 // Conditional setup - mark vector iterators defined in known implementations
Chris@16 64 // as iterators pointing to contiguous ranges
Chris@16 65
Chris@16 66 #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
Chris@16 67
Chris@16 68 template <typename Pointer>
Chris@16 69 struct are_elements_contiguous<
Chris@16 70 boost::container::container_detail::vector_const_iterator<Pointer>
Chris@16 71 > : boost::true_type
Chris@16 72 {};
Chris@16 73
Chris@16 74 template <typename Pointer>
Chris@16 75 struct are_elements_contiguous<
Chris@16 76 boost::container::container_detail::vector_iterator<Pointer>
Chris@16 77 > : boost::true_type
Chris@16 78 {};
Chris@16 79
Chris@16 80 #if defined(BOOST_DINKUMWARE_STDLIB)
Chris@16 81
Chris@16 82 template <typename T>
Chris@16 83 struct are_elements_contiguous<
Chris@16 84 std::_Vector_const_iterator<T>
Chris@16 85 > : boost::true_type
Chris@16 86 {};
Chris@16 87
Chris@16 88 template <typename T>
Chris@16 89 struct are_elements_contiguous<
Chris@16 90 std::_Vector_iterator<T>
Chris@16 91 > : boost::true_type
Chris@16 92 {};
Chris@16 93
Chris@16 94 #elif defined(BOOST_GNU_STDLIB)
Chris@16 95
Chris@16 96 template <typename P, typename T, typename A>
Chris@16 97 struct are_elements_contiguous<
Chris@16 98 __gnu_cxx::__normal_iterator<P, std::vector<T, A> >
Chris@16 99 > : boost::true_type
Chris@16 100 {};
Chris@16 101
Chris@16 102 #elif defined(_LIBCPP_VERSION)
Chris@16 103
Chris@16 104 // TODO - test it first
Chris@16 105 //template <typename P>
Chris@16 106 //struct are_elements_contiguous<
Chris@16 107 // __wrap_iter<P>
Chris@16 108 //> : boost::true_type
Chris@16 109 //{};
Chris@16 110
Chris@16 111 #else // OTHER_STDLIB
Chris@16 112
Chris@16 113 // TODO - add other iterators implementations
Chris@16 114
Chris@16 115 #endif // STDLIB
Chris@16 116
Chris@16 117 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
Chris@16 118
Chris@16 119 // True if iterator values are the same and both iterators points to the ranges of contiguous elements
Chris@16 120
Chris@16 121 template <typename I, typename O>
Chris@16 122 struct are_corresponding :
Chris@16 123 ::boost::mpl::and_<
Chris@16 124 ::boost::is_same<
Chris@16 125 ::boost::remove_const<
Chris@16 126 typename ::boost::iterator_value<I>::type
Chris@16 127 >,
Chris@16 128 ::boost::remove_const<
Chris@16 129 typename ::boost::iterator_value<O>::type
Chris@16 130 >
Chris@16 131 >,
Chris@16 132 are_elements_contiguous<I>,
Chris@16 133 are_elements_contiguous<O>
Chris@16 134 >
Chris@16 135 {};
Chris@16 136
Chris@16 137 template <typename I, typename V>
Chris@16 138 struct is_corresponding_value :
Chris@16 139 ::boost::is_same<
Chris@16 140 ::boost::remove_const<
Chris@16 141 typename ::boost::iterator_value<I>::type
Chris@16 142 >,
Chris@16 143 ::boost::remove_const<V>
Chris@16 144 >
Chris@16 145 {};
Chris@16 146
Chris@16 147 // destroy(I, I)
Chris@16 148
Chris@16 149 template <typename I>
Chris@16 150 void destroy_dispatch(I /*first*/, I /*last*/,
Chris@16 151 boost::true_type const& /*has_trivial_destructor*/)
Chris@16 152 {}
Chris@16 153
Chris@16 154 template <typename I>
Chris@16 155 void destroy_dispatch(I first, I last,
Chris@16 156 boost::false_type const& /*has_trivial_destructor*/)
Chris@16 157 {
Chris@16 158 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 159 for ( ; first != last ; ++first )
Chris@16 160 first->~value_type();
Chris@16 161 }
Chris@16 162
Chris@16 163 template <typename I>
Chris@16 164 void destroy(I first, I last)
Chris@16 165 {
Chris@16 166 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 167 destroy_dispatch(first, last, has_trivial_destructor<value_type>());
Chris@16 168 }
Chris@16 169
Chris@16 170 // destroy(I)
Chris@16 171
Chris@16 172 template <typename I>
Chris@16 173 void destroy_dispatch(I /*pos*/,
Chris@16 174 boost::true_type const& /*has_trivial_destructor*/)
Chris@16 175 {}
Chris@16 176
Chris@16 177 template <typename I>
Chris@16 178 void destroy_dispatch(I pos,
Chris@16 179 boost::false_type const& /*has_trivial_destructor*/)
Chris@16 180 {
Chris@16 181 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 182 pos->~value_type();
Chris@16 183 }
Chris@16 184
Chris@16 185 template <typename I>
Chris@16 186 void destroy(I pos)
Chris@16 187 {
Chris@16 188 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 189 destroy_dispatch(pos, has_trivial_destructor<value_type>());
Chris@16 190 }
Chris@16 191
Chris@16 192 // copy(I, I, O)
Chris@16 193
Chris@16 194 template <typename I, typename O>
Chris@16 195 inline O copy_dispatch(I first, I last, O dst,
Chris@16 196 boost::mpl::bool_<true> const& /*use_memmove*/)
Chris@16 197 {
Chris@16 198 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 199 typename boost::iterator_difference<I>::type d = std::distance(first, last);
Chris@16 200
Chris@16 201 ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
Chris@16 202 return dst + d;
Chris@16 203 }
Chris@16 204
Chris@16 205 template <typename I, typename O>
Chris@16 206 inline O copy_dispatch(I first, I last, O dst,
Chris@16 207 boost::mpl::bool_<false> const& /*use_memmove*/)
Chris@16 208 {
Chris@16 209 return std::copy(first, last, dst); // may throw
Chris@16 210 }
Chris@16 211
Chris@16 212 template <typename I, typename O>
Chris@16 213 inline O copy(I first, I last, O dst)
Chris@16 214 {
Chris@16 215 typedef typename
Chris@16 216 ::boost::mpl::and_<
Chris@16 217 are_corresponding<I, O>,
Chris@16 218 ::boost::has_trivial_assign<
Chris@16 219 typename ::boost::iterator_value<O>::type
Chris@16 220 >
Chris@16 221 >::type
Chris@16 222 use_memmove;
Chris@16 223
Chris@16 224 return copy_dispatch(first, last, dst, use_memmove()); // may throw
Chris@16 225 }
Chris@16 226
Chris@16 227 // uninitialized_copy(I, I, O)
Chris@16 228
Chris@16 229 template <typename I, typename O>
Chris@16 230 inline
Chris@16 231 O uninitialized_copy_dispatch(I first, I last, O dst,
Chris@16 232 boost::mpl::bool_<true> const& /*use_memcpy*/)
Chris@16 233 {
Chris@16 234 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 235 typename boost::iterator_difference<I>::type d = std::distance(first, last);
Chris@16 236
Chris@16 237 ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
Chris@16 238 return dst + d;
Chris@16 239 }
Chris@16 240
Chris@16 241 template <typename I, typename F>
Chris@16 242 inline
Chris@16 243 F uninitialized_copy_dispatch(I first, I last, F dst,
Chris@16 244 boost::mpl::bool_<false> const& /*use_memcpy*/)
Chris@16 245 {
Chris@16 246 return std::uninitialized_copy(first, last, dst); // may throw
Chris@16 247 }
Chris@16 248
Chris@16 249 template <typename I, typename F>
Chris@16 250 inline
Chris@16 251 F uninitialized_copy(I first, I last, F dst)
Chris@16 252 {
Chris@16 253 typedef typename
Chris@16 254 ::boost::mpl::and_<
Chris@16 255 are_corresponding<I, F>,
Chris@16 256 ::boost::has_trivial_copy<
Chris@16 257 typename ::boost::iterator_value<F>::type
Chris@16 258 >
Chris@16 259 >::type
Chris@16 260 use_memcpy;
Chris@16 261
Chris@16 262 return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
Chris@16 263 }
Chris@16 264
Chris@16 265 // uninitialized_move(I, I, O)
Chris@16 266
Chris@16 267 template <typename I, typename O>
Chris@16 268 inline
Chris@16 269 O uninitialized_move_dispatch(I first, I last, O dst,
Chris@16 270 boost::mpl::bool_<true> const& /*use_memcpy*/)
Chris@16 271 {
Chris@16 272 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 273 typename boost::iterator_difference<I>::type d = std::distance(first, last);
Chris@16 274
Chris@16 275 ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
Chris@16 276 return dst + d;
Chris@16 277 }
Chris@16 278
Chris@16 279 template <typename I, typename O>
Chris@16 280 inline
Chris@16 281 O uninitialized_move_dispatch(I first, I last, O dst,
Chris@16 282 boost::mpl::bool_<false> const& /*use_memcpy*/)
Chris@16 283 {
Chris@16 284 //return boost::uninitialized_move(first, last, dst); // may throw
Chris@16 285
Chris@16 286 O o = dst;
Chris@16 287
Chris@16 288 BOOST_TRY
Chris@16 289 {
Chris@16 290 typedef typename std::iterator_traits<O>::value_type value_type;
Chris@16 291 for (; first != last; ++first, ++o )
Chris@16 292 new (boost::addressof(*o)) value_type(boost::move(*first));
Chris@16 293 }
Chris@16 294 BOOST_CATCH(...)
Chris@16 295 {
Chris@16 296 destroy(dst, o);
Chris@16 297 BOOST_RETHROW;
Chris@16 298 }
Chris@16 299 BOOST_CATCH_END
Chris@16 300
Chris@16 301 return dst;
Chris@16 302 }
Chris@16 303
Chris@16 304 template <typename I, typename O>
Chris@16 305 inline
Chris@16 306 O uninitialized_move(I first, I last, O dst)
Chris@16 307 {
Chris@16 308 typedef typename
Chris@16 309 ::boost::mpl::and_<
Chris@16 310 are_corresponding<I, O>,
Chris@16 311 ::boost::has_trivial_copy<
Chris@16 312 typename ::boost::iterator_value<O>::type
Chris@16 313 >
Chris@16 314 >::type
Chris@16 315 use_memcpy;
Chris@16 316
Chris@16 317 return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw
Chris@16 318 }
Chris@16 319
Chris@16 320 // TODO - move uses memmove - implement 2nd version using memcpy?
Chris@16 321
Chris@16 322 // move(I, I, O)
Chris@16 323
Chris@16 324 template <typename I, typename O>
Chris@16 325 inline
Chris@16 326 O move_dispatch(I first, I last, O dst,
Chris@16 327 boost::mpl::bool_<true> const& /*use_memmove*/)
Chris@16 328 {
Chris@16 329 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 330 typename boost::iterator_difference<I>::type d = std::distance(first, last);
Chris@16 331
Chris@16 332 ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
Chris@16 333 return dst + d;
Chris@16 334 }
Chris@16 335
Chris@16 336 template <typename I, typename O>
Chris@16 337 inline
Chris@16 338 O move_dispatch(I first, I last, O dst,
Chris@16 339 boost::mpl::bool_<false> const& /*use_memmove*/)
Chris@16 340 {
Chris@16 341 return boost::move(first, last, dst); // may throw
Chris@16 342 }
Chris@16 343
Chris@16 344 template <typename I, typename O>
Chris@16 345 inline
Chris@16 346 O move(I first, I last, O dst)
Chris@16 347 {
Chris@16 348 typedef typename
Chris@16 349 ::boost::mpl::and_<
Chris@16 350 are_corresponding<I, O>,
Chris@16 351 ::boost::has_trivial_assign<
Chris@16 352 typename ::boost::iterator_value<O>::type
Chris@16 353 >
Chris@16 354 >::type
Chris@16 355 use_memmove;
Chris@16 356
Chris@16 357 return move_dispatch(first, last, dst, use_memmove()); // may throw
Chris@16 358 }
Chris@16 359
Chris@16 360 // move_backward(BDI, BDI, BDO)
Chris@16 361
Chris@16 362 template <typename BDI, typename BDO>
Chris@16 363 inline
Chris@16 364 BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
Chris@16 365 boost::mpl::bool_<true> const& /*use_memmove*/)
Chris@16 366 {
Chris@16 367 typedef typename boost::iterator_value<BDI>::type value_type;
Chris@16 368 typename boost::iterator_difference<BDI>::type d = std::distance(first, last);
Chris@16 369
Chris@16 370 BDO foo(dst - d);
Chris@16 371 ::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d);
Chris@16 372 return foo;
Chris@16 373 }
Chris@16 374
Chris@16 375 template <typename BDI, typename BDO>
Chris@16 376 inline
Chris@16 377 BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
Chris@16 378 boost::mpl::bool_<false> const& /*use_memmove*/)
Chris@16 379 {
Chris@16 380 return boost::move_backward(first, last, dst); // may throw
Chris@16 381 }
Chris@16 382
Chris@16 383 template <typename BDI, typename BDO>
Chris@16 384 inline
Chris@16 385 BDO move_backward(BDI first, BDI last, BDO dst)
Chris@16 386 {
Chris@16 387 typedef typename
Chris@16 388 ::boost::mpl::and_<
Chris@16 389 are_corresponding<BDI, BDO>,
Chris@16 390 ::boost::has_trivial_assign<
Chris@16 391 typename ::boost::iterator_value<BDO>::type
Chris@16 392 >
Chris@16 393 >::type
Chris@16 394 use_memmove;
Chris@16 395
Chris@16 396 return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
Chris@16 397 }
Chris@16 398
Chris@16 399 template <typename T>
Chris@16 400 struct has_nothrow_move : public
Chris@16 401 ::boost::mpl::or_<
Chris@16 402 boost::mpl::bool_<
Chris@16 403 ::boost::has_nothrow_move<
Chris@16 404 typename ::boost::remove_const<T>::type
Chris@16 405 >::value
Chris@16 406 >,
Chris@16 407 boost::mpl::bool_<
Chris@16 408 ::boost::has_nothrow_move<T>::value
Chris@16 409 >
Chris@16 410 >
Chris@16 411 {};
Chris@16 412
Chris@16 413 // uninitialized_move_if_noexcept(I, I, O)
Chris@16 414
Chris@16 415 template <typename I, typename O>
Chris@16 416 inline
Chris@16 417 O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
Chris@16 418 { return varray_detail::uninitialized_move(first, last, dst); }
Chris@16 419
Chris@16 420 template <typename I, typename O>
Chris@16 421 inline
Chris@16 422 O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
Chris@16 423 { return varray_detail::uninitialized_copy(first, last, dst); }
Chris@16 424
Chris@16 425 template <typename I, typename O>
Chris@16 426 inline
Chris@16 427 O uninitialized_move_if_noexcept(I first, I last, O dst)
Chris@16 428 {
Chris@16 429 typedef typename has_nothrow_move<
Chris@16 430 typename ::boost::iterator_value<O>::type
Chris@16 431 >::type use_move;
Chris@16 432
Chris@16 433 return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
Chris@16 434 }
Chris@16 435
Chris@16 436 // move_if_noexcept(I, I, O)
Chris@16 437
Chris@16 438 template <typename I, typename O>
Chris@16 439 inline
Chris@16 440 O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
Chris@16 441 { return move(first, last, dst); }
Chris@16 442
Chris@16 443 template <typename I, typename O>
Chris@16 444 inline
Chris@16 445 O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
Chris@16 446 { return copy(first, last, dst); }
Chris@16 447
Chris@16 448 template <typename I, typename O>
Chris@16 449 inline
Chris@16 450 O move_if_noexcept(I first, I last, O dst)
Chris@16 451 {
Chris@16 452 typedef typename has_nothrow_move<
Chris@16 453 typename ::boost::iterator_value<O>::type
Chris@16 454 >::type use_move;
Chris@16 455
Chris@16 456 return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
Chris@16 457 }
Chris@16 458
Chris@16 459 // uninitialized_fill(I, I)
Chris@16 460
Chris@16 461 template <typename I>
Chris@16 462 inline
Chris@16 463 void uninitialized_fill_dispatch(I /*first*/, I /*last*/,
Chris@16 464 boost::true_type const& /*has_trivial_constructor*/,
Chris@16 465 boost::true_type const& /*disable_trivial_init*/)
Chris@16 466 {}
Chris@16 467
Chris@16 468 template <typename I>
Chris@16 469 inline
Chris@16 470 void uninitialized_fill_dispatch(I first, I last,
Chris@16 471 boost::true_type const& /*has_trivial_constructor*/,
Chris@16 472 boost::false_type const& /*disable_trivial_init*/)
Chris@16 473 {
Chris@16 474 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 475 for ( ; first != last ; ++first )
Chris@16 476 new (boost::addressof(*first)) value_type();
Chris@16 477 }
Chris@16 478
Chris@16 479 template <typename I, typename DisableTrivialInit>
Chris@16 480 inline
Chris@16 481 void uninitialized_fill_dispatch(I first, I last,
Chris@16 482 boost::false_type const& /*has_trivial_constructor*/,
Chris@16 483 DisableTrivialInit const& /*not_used*/)
Chris@16 484 {
Chris@16 485 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 486 I it = first;
Chris@16 487
Chris@16 488 BOOST_TRY
Chris@16 489 {
Chris@16 490 for ( ; it != last ; ++it )
Chris@16 491 new (boost::addressof(*it)) value_type(); // may throw
Chris@16 492 }
Chris@16 493 BOOST_CATCH(...)
Chris@16 494 {
Chris@16 495 destroy(first, it);
Chris@16 496 BOOST_RETHROW;
Chris@16 497 }
Chris@16 498 BOOST_CATCH_END
Chris@16 499 }
Chris@16 500
Chris@16 501 template <typename I, typename DisableTrivialInit>
Chris@16 502 inline
Chris@16 503 void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
Chris@16 504 {
Chris@16 505 typedef typename boost::iterator_value<I>::type value_type;
Chris@16 506 uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
Chris@16 507 }
Chris@16 508
Chris@16 509 // construct(I)
Chris@16 510
Chris@16 511 template <typename I>
Chris@16 512 inline
Chris@16 513 void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I /*pos*/)
Chris@16 514 {}
Chris@16 515
Chris@16 516 template <typename I>
Chris@16 517 inline
Chris@16 518 void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos)
Chris@16 519 {
Chris@16 520 typedef typename ::boost::iterator_value<I>::type value_type;
Chris@16 521 new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw
Chris@16 522 }
Chris@16 523
Chris@16 524 template <typename DisableTrivialInit, typename I>
Chris@16 525 inline
Chris@16 526 void construct(DisableTrivialInit const&, I pos)
Chris@16 527 {
Chris@16 528 typedef typename ::boost::iterator_value<I>::type value_type;
Chris@16 529 typedef typename ::boost::mpl::and_<
Chris@16 530 boost::has_trivial_constructor<value_type>,
Chris@16 531 DisableTrivialInit
Chris@16 532 >::type dont_init;
Chris@16 533
Chris@16 534 construct_dispatch(dont_init(), pos); // may throw
Chris@16 535 }
Chris@16 536
Chris@16 537 // construct(I, V)
Chris@16 538
Chris@16 539 template <typename I, typename V>
Chris@16 540 inline
Chris@16 541 void construct_copy_dispatch(I pos, V const& v,
Chris@16 542 boost::mpl::bool_<true> const& /*use_memcpy*/)
Chris@16 543 {
Chris@16 544 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
Chris@16 545 }
Chris@16 546
Chris@16 547 template <typename I, typename P>
Chris@16 548 inline
Chris@16 549 void construct_copy_dispatch(I pos, P const& p,
Chris@16 550 boost::mpl::bool_<false> const& /*use_memcpy*/)
Chris@16 551 {
Chris@16 552 typedef typename boost::iterator_value<I>::type V;
Chris@16 553 new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw
Chris@16 554 }
Chris@16 555
Chris@16 556 template <typename DisableTrivialInit, typename I, typename P>
Chris@16 557 inline
Chris@16 558 void construct(DisableTrivialInit const&,
Chris@16 559 I pos, P const& p)
Chris@16 560 {
Chris@16 561 typedef typename
Chris@16 562 ::boost::mpl::and_<
Chris@16 563 is_corresponding_value<I, P>,
Chris@16 564 ::boost::has_trivial_copy<P>
Chris@16 565 >::type
Chris@16 566 use_memcpy;
Chris@16 567
Chris@16 568 construct_copy_dispatch(pos, p, use_memcpy()); // may throw
Chris@16 569 }
Chris@16 570
Chris@16 571 // Needed by push_back(V &&)
Chris@16 572
Chris@16 573 template <typename I, typename V>
Chris@16 574 inline
Chris@16 575 void construct_move_dispatch(I pos, V const& v,
Chris@16 576 boost::mpl::bool_<true> const& /*use_memcpy*/)
Chris@16 577 {
Chris@16 578 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
Chris@16 579 }
Chris@16 580
Chris@16 581 template <typename I, typename P>
Chris@16 582 inline
Chris@16 583 void construct_move_dispatch(I pos, BOOST_RV_REF(P) p,
Chris@16 584 boost::mpl::bool_<false> const& /*use_memcpy*/)
Chris@16 585 {
Chris@16 586 typedef typename boost::iterator_value<I>::type V;
Chris@16 587 new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw
Chris@16 588 }
Chris@16 589
Chris@16 590 template <typename DisableTrivialInit, typename I, typename P>
Chris@16 591 inline
Chris@16 592 void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
Chris@16 593 {
Chris@16 594 typedef typename
Chris@16 595 ::boost::mpl::and_<
Chris@16 596 is_corresponding_value<I, P>,
Chris@16 597 ::boost::has_trivial_move_constructor<P>
Chris@16 598 >::type
Chris@16 599 use_memcpy;
Chris@16 600
Chris@16 601 construct_move_dispatch(pos, ::boost::move(p), use_memcpy()); // may throw
Chris@16 602 }
Chris@16 603
Chris@16 604 // Needed by emplace_back() and emplace()
Chris@16 605
Chris@16 606 #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
Chris@101 607 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@16 608
Chris@16 609 template <typename DisableTrivialInit, typename I, class ...Args>
Chris@16 610 inline
Chris@16 611 void construct(DisableTrivialInit const&,
Chris@16 612 I pos,
Chris@16 613 BOOST_FWD_REF(Args) ...args)
Chris@16 614 {
Chris@16 615 typedef typename boost::iterator_value<I>::type V;
Chris@16 616 new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
Chris@16 617 }
Chris@16 618
Chris@101 619 #else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
Chris@16 620
Chris@101 621 // BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 const& p0
Chris@101 622 // !BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 && p0
Chris@16 623 // which means that version with one parameter may take V const& v
Chris@16 624
Chris@101 625 #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT(N) \
Chris@101 626 template <typename DisableTrivialInit, typename I, typename P BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
Chris@16 627 inline \
Chris@16 628 void construct(DisableTrivialInit const&, \
Chris@16 629 I pos, \
Chris@101 630 BOOST_FWD_REF(P) p \
Chris@101 631 BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
Chris@16 632 { \
Chris@16 633 typedef typename boost::iterator_value<I>::type V; \
Chris@16 634 new \
Chris@16 635 (static_cast<void*>(boost::addressof(*pos))) \
Chris@101 636 V(boost::forward<P>(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/ \
Chris@16 637 } \
Chris@16 638
Chris@101 639 BOOST_MOVE_ITERATE_1TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT)
Chris@101 640 #undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT
Chris@101 641
Chris@101 642 #endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
Chris@16 643 #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
Chris@16 644
Chris@16 645 // assign(I, V)
Chris@16 646
Chris@16 647 template <typename I, typename V>
Chris@16 648 inline
Chris@16 649 void assign_copy_dispatch(I pos, V const& v,
Chris@16 650 boost::mpl::bool_<true> const& /*use_memcpy*/)
Chris@16 651 {
Chris@16 652 // TODO - use memmove here?
Chris@16 653 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
Chris@16 654 }
Chris@16 655
Chris@16 656 template <typename I, typename V>
Chris@16 657 inline
Chris@16 658 void assign_copy_dispatch(I pos, V const& v,
Chris@16 659 boost::mpl::bool_<false> const& /*use_memcpy*/)
Chris@16 660 {
Chris@16 661 *pos = v; // may throw
Chris@16 662 }
Chris@16 663
Chris@16 664 template <typename I, typename V>
Chris@16 665 inline
Chris@16 666 void assign(I pos, V const& v)
Chris@16 667 {
Chris@16 668 typedef typename
Chris@16 669 ::boost::mpl::and_<
Chris@16 670 is_corresponding_value<I, V>,
Chris@16 671 ::boost::has_trivial_assign<V>
Chris@16 672 >::type
Chris@16 673 use_memcpy;
Chris@16 674
Chris@16 675 assign_copy_dispatch(pos, v, use_memcpy()); // may throw
Chris@16 676 }
Chris@16 677
Chris@16 678 template <typename I, typename V>
Chris@16 679 inline
Chris@16 680 void assign_move_dispatch(I pos, V const& v,
Chris@16 681 boost::mpl::bool_<true> const& /*use_memcpy*/)
Chris@16 682 {
Chris@16 683 // TODO - use memmove here?
Chris@16 684 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
Chris@16 685 }
Chris@16 686
Chris@16 687 template <typename I, typename V>
Chris@16 688 inline
Chris@16 689 void assign_move_dispatch(I pos, BOOST_RV_REF(V) v,
Chris@16 690 boost::mpl::bool_<false> const& /*use_memcpy*/)
Chris@16 691 {
Chris@16 692 *pos = boost::move(v); // may throw
Chris@16 693 }
Chris@16 694
Chris@16 695 template <typename I, typename V>
Chris@16 696 inline
Chris@16 697 void assign(I pos, BOOST_RV_REF(V) v)
Chris@16 698 {
Chris@16 699 typedef typename
Chris@16 700 ::boost::mpl::and_<
Chris@16 701 is_corresponding_value<I, V>,
Chris@16 702 ::boost::has_trivial_move_assign<V>
Chris@16 703 >::type
Chris@16 704 use_memcpy;
Chris@16 705
Chris@16 706 assign_move_dispatch(pos, ::boost::move(v), use_memcpy());
Chris@16 707 }
Chris@16 708
Chris@16 709 // uninitialized_copy_s
Chris@16 710
Chris@16 711 template <typename I, typename F>
Chris@16 712 inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count)
Chris@16 713 {
Chris@16 714 std::size_t count = 0;
Chris@16 715 F it = dest;
Chris@16 716
Chris@16 717 BOOST_TRY
Chris@16 718 {
Chris@16 719 for ( ; first != last ; ++it, ++first, ++count )
Chris@16 720 {
Chris@16 721 if ( max_count <= count )
Chris@16 722 return (std::numeric_limits<std::size_t>::max)();
Chris@16 723
Chris@16 724 // dummy 0 as DisableTrivialInit
Chris@16 725 construct(0, it, *first); // may throw
Chris@16 726 }
Chris@16 727 }
Chris@16 728 BOOST_CATCH(...)
Chris@16 729 {
Chris@16 730 destroy(dest, it);
Chris@16 731 BOOST_RETHROW;
Chris@16 732 }
Chris@16 733 BOOST_CATCH_END
Chris@16 734
Chris@16 735 return count;
Chris@16 736 }
Chris@16 737
Chris@16 738 // scoped_destructor
Chris@16 739
Chris@16 740 template<class T>
Chris@16 741 class scoped_destructor
Chris@16 742 {
Chris@16 743 public:
Chris@16 744 scoped_destructor(T * ptr) : m_ptr(ptr) {}
Chris@16 745
Chris@16 746 ~scoped_destructor()
Chris@16 747 {
Chris@16 748 if(m_ptr)
Chris@16 749 destroy(m_ptr);
Chris@16 750 }
Chris@16 751
Chris@16 752 void release() { m_ptr = 0; }
Chris@16 753
Chris@16 754 private:
Chris@16 755 T * m_ptr;
Chris@16 756 };
Chris@16 757
Chris@16 758 }}}}} // namespace boost::geometry::index::detail::varray_detail
Chris@16 759
Chris@16 760 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP