File indexing completed on 2025-01-18 09:35:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
0017 #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
0018
0019 #include <algorithm>
0020 #include <cstddef>
0021 #include <cstring>
0022 #include <limits>
0023 #include <memory>
0024 #include <type_traits>
0025
0026 #include <boost/config.hpp>
0027
0028 #include <boost/core/addressof.hpp>
0029 #include <boost/core/no_exceptions_support.hpp>
0030 #include <boost/iterator/iterator_traits.hpp>
0031
0032
0033
0034 #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
0035 #include <vector>
0036 #include <boost/container/vector.hpp>
0037 #endif
0038
0039 namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail
0040 {
0041
0042
0043 template <typename I>
0044 struct are_elements_contiguous : std::is_pointer<I>
0045 {};
0046
0047
0048
0049
0050
0051 #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
0052
0053 template <typename Pointer>
0054 struct are_elements_contiguous<
0055 boost::container::container_detail::vector_const_iterator<Pointer>
0056 > : std::true_type
0057 {};
0058
0059 template <typename Pointer>
0060 struct are_elements_contiguous<
0061 boost::container::container_detail::vector_iterator<Pointer>
0062 > : std::true_type
0063 {};
0064
0065 #if defined(BOOST_DINKUMWARE_STDLIB)
0066
0067 template <typename T>
0068 struct are_elements_contiguous<
0069 std::_Vector_const_iterator<T>
0070 > : std::true_type
0071 {};
0072
0073 template <typename T>
0074 struct are_elements_contiguous<
0075 std::_Vector_iterator<T>
0076 > : std::true_type
0077 {};
0078
0079 #elif defined(BOOST_GNU_STDLIB)
0080
0081 template <typename P, typename T, typename A>
0082 struct are_elements_contiguous<
0083 __gnu_cxx::__normal_iterator<P, std::vector<T, A> >
0084 > : std::true_type
0085 {};
0086
0087 #elif defined(_LIBCPP_VERSION)
0088
0089
0090
0091
0092
0093
0094
0095
0096 #else
0097
0098
0099
0100 #endif
0101
0102 #endif
0103
0104
0105 template <typename I, typename O>
0106 struct is_memop_safe_for_range
0107 : std::integral_constant
0108 <
0109 bool,
0110 std::is_same
0111 <
0112 std::remove_const_t
0113 <
0114 typename ::boost::iterator_value<I>::type
0115 >,
0116 std::remove_const_t
0117 <
0118 typename ::boost::iterator_value<O>::type
0119 >
0120 >::value
0121 &&
0122 are_elements_contiguous<I>::value
0123 &&
0124 are_elements_contiguous<O>::value
0125 &&
0126 std::is_trivially_copyable
0127 <
0128 typename ::boost::iterator_value<O>::type
0129 >::value
0130 >
0131 {};
0132
0133
0134 template <typename I, typename V>
0135 struct is_memop_safe_for_value
0136 : std::integral_constant
0137 <
0138 bool,
0139 std::is_same
0140 <
0141 std::remove_const_t
0142 <
0143 typename ::boost::iterator_value<I>::type
0144 >,
0145 std::remove_const_t<V>
0146 >::value
0147 &&
0148 std::is_trivially_copyable
0149 <
0150 V
0151 >::value
0152 >
0153 {};
0154
0155
0156
0157 template <typename I>
0158 void destroy_dispatch(I , I ,
0159 std::true_type )
0160 {}
0161
0162 template <typename I>
0163 void destroy_dispatch(I first, I last,
0164 std::false_type )
0165 {
0166 typedef typename boost::iterator_value<I>::type value_type;
0167 for ( ; first != last ; ++first )
0168 first->~value_type();
0169 }
0170
0171 template <typename I>
0172 void destroy(I first, I last)
0173 {
0174 typedef typename boost::iterator_value<I>::type value_type;
0175 destroy_dispatch(first, last, std::is_trivially_destructible<value_type>());
0176 }
0177
0178
0179
0180 template <typename I>
0181 void destroy_dispatch(I ,
0182 std::true_type )
0183 {}
0184
0185 template <typename I>
0186 void destroy_dispatch(I pos,
0187 std::false_type )
0188 {
0189 typedef typename boost::iterator_value<I>::type value_type;
0190 pos->~value_type();
0191 }
0192
0193 template <typename I>
0194 void destroy(I pos)
0195 {
0196 typedef typename boost::iterator_value<I>::type value_type;
0197 destroy_dispatch(pos, std::is_trivially_destructible<value_type>());
0198 }
0199
0200
0201
0202 template <typename I, typename O>
0203 inline O copy_dispatch(I first, I last, O dst,
0204 std::true_type )
0205 {
0206 typedef typename boost::iterator_value<I>::type value_type;
0207 typename boost::iterator_difference<I>::type d = std::distance(first, last);
0208
0209 ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
0210 return dst + d;
0211 }
0212
0213 template <typename I, typename O>
0214 inline O copy_dispatch(I first, I last, O dst,
0215 std::false_type )
0216 {
0217 return std::copy(first, last, dst);
0218 }
0219
0220 template <typename I, typename O>
0221 inline O copy(I first, I last, O dst)
0222 {
0223 return copy_dispatch(first, last, dst, is_memop_safe_for_range<I, O>());
0224 }
0225
0226
0227
0228 template <typename I, typename O>
0229 inline
0230 O uninitialized_copy_dispatch(I first, I last, O dst,
0231 std::true_type )
0232 {
0233 typedef typename boost::iterator_value<I>::type value_type;
0234 typename boost::iterator_difference<I>::type d = std::distance(first, last);
0235
0236 ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
0237 return dst + d;
0238 }
0239
0240 template <typename I, typename F>
0241 inline
0242 F uninitialized_copy_dispatch(I first, I last, F dst,
0243 std::false_type )
0244 {
0245 return std::uninitialized_copy(first, last, dst);
0246 }
0247
0248 template <typename I, typename F>
0249 inline
0250 F uninitialized_copy(I first, I last, F dst)
0251 {
0252 return uninitialized_copy_dispatch(first, last, dst, is_memop_safe_for_range<I, F>());
0253 }
0254
0255
0256
0257 template <typename I, typename O>
0258 inline
0259 O uninitialized_move_dispatch(I first, I last, O dst,
0260 std::true_type )
0261 {
0262 typedef typename boost::iterator_value<I>::type value_type;
0263 typename boost::iterator_difference<I>::type d = std::distance(first, last);
0264
0265 ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
0266 return dst + d;
0267 }
0268
0269 template <typename I, typename O>
0270 inline
0271 O uninitialized_move_dispatch(I first, I last, O dst,
0272 std::false_type )
0273 {
0274
0275
0276 O o = dst;
0277
0278 BOOST_TRY
0279 {
0280 typedef typename std::iterator_traits<O>::value_type value_type;
0281 for (; first != last; ++first, ++o )
0282 new (boost::addressof(*o)) value_type(std::move(*first));
0283 }
0284 BOOST_CATCH(...)
0285 {
0286 varray_detail::destroy(dst, o);
0287 BOOST_RETHROW;
0288 }
0289 BOOST_CATCH_END
0290
0291 return dst;
0292 }
0293
0294 template <typename I, typename O>
0295 inline
0296 O uninitialized_move(I first, I last, O dst)
0297 {
0298 return uninitialized_move_dispatch(first, last, dst, is_memop_safe_for_range<I, O>());
0299 }
0300
0301
0302
0303
0304
0305 template <typename I, typename O>
0306 inline
0307 O move_dispatch(I first, I last, O dst,
0308 std::true_type )
0309 {
0310 typedef typename boost::iterator_value<I>::type value_type;
0311 typename boost::iterator_difference<I>::type d = std::distance(first, last);
0312
0313 ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
0314 return dst + d;
0315 }
0316
0317 template <typename I, typename O>
0318 inline
0319 O move_dispatch(I first, I last, O dst,
0320 std::false_type )
0321 {
0322 return std::move(first, last, dst);
0323 }
0324
0325 template <typename I, typename O>
0326 inline
0327 O move(I first, I last, O dst)
0328 {
0329 return move_dispatch(first, last, dst, is_memop_safe_for_range<I, O>());
0330 }
0331
0332
0333
0334 template <typename BDI, typename BDO>
0335 inline
0336 BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
0337 std::true_type )
0338 {
0339 typedef typename boost::iterator_value<BDI>::type value_type;
0340 typename boost::iterator_difference<BDI>::type d = std::distance(first, last);
0341
0342 BDO foo(dst - d);
0343 ::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d);
0344 return foo;
0345 }
0346
0347 template <typename BDI, typename BDO>
0348 inline
0349 BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
0350 std::false_type )
0351 {
0352 return std::move_backward(first, last, dst);
0353 }
0354
0355 template <typename BDI, typename BDO>
0356 inline
0357 BDO move_backward(BDI first, BDI last, BDO dst)
0358 {
0359 return move_backward_dispatch(first, last, dst, is_memop_safe_for_range<BDI, BDO>());
0360 }
0361
0362
0363
0364 template <typename I, typename O>
0365 inline
0366 O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst,
0367 std::true_type )
0368 {
0369 return varray_detail::uninitialized_move(first, last, dst);
0370 }
0371
0372 template <typename I, typename O>
0373 inline
0374 O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst,
0375 std::false_type const& )
0376 {
0377 return varray_detail::uninitialized_copy(first, last, dst);
0378 }
0379
0380 template <typename I, typename O>
0381 inline
0382 O uninitialized_move_if_noexcept(I first, I last, O dst)
0383 {
0384 typedef std::is_nothrow_move_constructible<
0385 typename ::boost::iterator_value<O>::type
0386 > use_move;
0387
0388 return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move());
0389 }
0390
0391
0392
0393 template <typename I, typename O>
0394 inline
0395 O move_if_noexcept_dispatch(I first, I last, O dst,
0396 std::true_type )
0397 {
0398 return varray_detail::move(first, last, dst);
0399 }
0400
0401 template <typename I, typename O>
0402 inline
0403 O move_if_noexcept_dispatch(I first, I last, O dst,
0404 std::false_type )
0405 {
0406 return varray_detail::copy(first, last, dst);
0407 }
0408
0409 template <typename I, typename O>
0410 inline
0411 O move_if_noexcept(I first, I last, O dst)
0412 {
0413 typedef std::is_nothrow_move_constructible<
0414 typename ::boost::iterator_value<O>::type
0415 > use_move;
0416
0417 return move_if_noexcept_dispatch(first, last, dst, use_move());
0418 }
0419
0420
0421
0422 template <typename I>
0423 inline
0424 void uninitialized_fill_dispatch(I , I ,
0425 std::true_type const& ,
0426 std::true_type const& )
0427 {}
0428
0429 template <typename I>
0430 inline
0431 void uninitialized_fill_dispatch(I first, I last,
0432 std::true_type const& ,
0433 std::false_type const& )
0434 {
0435 typedef typename boost::iterator_value<I>::type value_type;
0436 for ( ; first != last ; ++first )
0437 new (boost::addressof(*first)) value_type();
0438 }
0439
0440 template <typename I, typename DisableTrivialInit>
0441 inline
0442 void uninitialized_fill_dispatch(I first, I last,
0443 std::false_type const& ,
0444 DisableTrivialInit const& )
0445 {
0446 typedef typename boost::iterator_value<I>::type value_type;
0447 I it = first;
0448
0449 BOOST_TRY
0450 {
0451 for ( ; it != last ; ++it )
0452 new (boost::addressof(*it)) value_type();
0453 }
0454 BOOST_CATCH(...)
0455 {
0456 varray_detail::destroy(first, it);
0457 BOOST_RETHROW;
0458 }
0459 BOOST_CATCH_END
0460 }
0461
0462 template <typename I, typename DisableTrivialInit>
0463 inline
0464 void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
0465 {
0466 typedef typename boost::iterator_value<I>::type value_type;
0467 uninitialized_fill_dispatch(first, last, std::is_trivially_constructible<value_type>(), disable_trivial_init);
0468 }
0469
0470
0471
0472 template <typename I>
0473 inline
0474 void construct_dispatch(std::true_type , I )
0475 {}
0476
0477 template <typename I>
0478 inline
0479 void construct_dispatch(std::false_type , I pos)
0480 {
0481 typedef typename ::boost::iterator_value<I>::type value_type;
0482 new (static_cast<void*>(boost::addressof(*pos))) value_type();
0483 }
0484
0485 template <typename DisableTrivialInit, typename I>
0486 inline
0487 void construct(DisableTrivialInit const&, I pos)
0488 {
0489 typedef typename ::boost::iterator_value<I>::type value_type;
0490 typedef std::integral_constant
0491 <
0492 bool,
0493 std::is_trivially_constructible<value_type>::value
0494 &&
0495 DisableTrivialInit::value
0496 > dont_init;
0497
0498 construct_dispatch(dont_init(), pos);
0499 }
0500
0501
0502
0503 template <typename I, typename V>
0504 inline
0505 void construct_copy_dispatch(I pos, V const& v,
0506 std::true_type )
0507 {
0508 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
0509 }
0510
0511 template <typename I, typename P>
0512 inline
0513 void construct_copy_dispatch(I pos, P const& p,
0514 std::false_type const& )
0515 {
0516 typedef typename boost::iterator_value<I>::type V;
0517 new (static_cast<void*>(boost::addressof(*pos))) V(p);
0518 }
0519
0520 template <typename DisableTrivialInit, typename I, typename P>
0521 inline
0522 void construct(DisableTrivialInit const&,
0523 I pos, P const& p)
0524 {
0525 construct_copy_dispatch(pos, p, is_memop_safe_for_value<I, P>());
0526 }
0527
0528
0529
0530 template <typename I, typename V>
0531 inline
0532 void construct_move_dispatch(I pos, V const& v,
0533 std::true_type const& )
0534 {
0535 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
0536 }
0537
0538 template <typename I, typename P>
0539 inline
0540 void construct_move_dispatch(I pos, P&& p,
0541 std::false_type const& )
0542 {
0543 typedef typename boost::iterator_value<I>::type V;
0544 new (static_cast<void*>(boost::addressof(*pos))) V(std::move(p));
0545 }
0546
0547 template <typename DisableTrivialInit, typename I, typename P>
0548 inline
0549 void construct(DisableTrivialInit const&, I pos, P&& p)
0550 {
0551 construct_move_dispatch(pos, std::move(p), is_memop_safe_for_value<I, P>());
0552 }
0553
0554
0555
0556 template <typename DisableTrivialInit, typename I, class ...Args>
0557 inline
0558 void construct(DisableTrivialInit const&,
0559 I pos,
0560 Args&& ...args)
0561 {
0562 typedef typename boost::iterator_value<I>::type V;
0563 new (static_cast<void*>(boost::addressof(*pos))) V(std::forward<Args>(args)...);
0564 }
0565
0566
0567
0568 template <typename I, typename V>
0569 inline
0570 void assign_copy_dispatch(I pos, V const& v,
0571 std::true_type )
0572 {
0573
0574 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
0575 }
0576
0577 template <typename I, typename V>
0578 inline
0579 void assign_copy_dispatch(I pos, V const& v,
0580 std::false_type )
0581 {
0582 *pos = v;
0583 }
0584
0585 template <typename I, typename V>
0586 inline
0587 void assign(I pos, V const& v)
0588 {
0589 assign_copy_dispatch(pos, v, is_memop_safe_for_value<I, V>());
0590 }
0591
0592 template <typename I, typename V>
0593 inline
0594 void assign_move_dispatch(I pos, V const& v,
0595 std::true_type )
0596 {
0597
0598 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
0599 }
0600
0601 template <typename I, typename V>
0602 inline
0603 void assign_move_dispatch(I pos, V&& v,
0604 std::false_type )
0605 {
0606 *pos = std::move(v);
0607 }
0608
0609 template <typename I, typename V>
0610 inline
0611 void assign(I pos, V&& v)
0612 {
0613 assign_move_dispatch(pos, std::move(v), is_memop_safe_for_value<I, V>());
0614 }
0615
0616
0617
0618 template <typename I, typename F>
0619 inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count)
0620 {
0621 std::size_t count = 0;
0622 F it = dest;
0623
0624 BOOST_TRY
0625 {
0626 for ( ; first != last ; ++it, ++first, ++count )
0627 {
0628 if ( max_count <= count )
0629 return (std::numeric_limits<std::size_t>::max)();
0630
0631
0632 construct(0, it, *first);
0633 }
0634 }
0635 BOOST_CATCH(...)
0636 {
0637 varray_detail::destroy(dest, it);
0638 BOOST_RETHROW;
0639 }
0640 BOOST_CATCH_END
0641
0642 return count;
0643 }
0644
0645
0646
0647 template<class T>
0648 class scoped_destructor
0649 {
0650 public:
0651 scoped_destructor(T * ptr) : m_ptr(ptr) {}
0652
0653 ~scoped_destructor()
0654 {
0655 if(m_ptr)
0656 varray_detail::destroy(m_ptr);
0657 }
0658
0659 void release() { m_ptr = 0; }
0660
0661 private:
0662 T * m_ptr;
0663 };
0664
0665 }}}}}
0666
0667 #endif