Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:34

0001 // Boost.Geometry
0002 //
0003 // varray details
0004 //
0005 // Copyright (c) 2011-2013 Andrew Hundt.
0006 // Copyright (c) 2012-2023 Adam Wulkiewicz, Lodz, Poland.
0007 //
0008 // This file was modified by Oracle on 2020.
0009 // Modifications copyright (c) 2020, Oracle and/or its affiliates.
0010 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0011 //
0012 // Use, modification and distribution is subject to the Boost Software License,
0013 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0014 // http://www.boost.org/LICENSE_1_0.txt)
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 // TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
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 // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
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 // EXPERIMENTAL - not finished
0048 // Conditional setup - mark vector iterators defined in known implementations
0049 // as iterators pointing to contiguous ranges
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 // TODO - test it first
0090 //template <typename P>
0091 //struct are_elements_contiguous<
0092 //    __wrap_iter<P>
0093 //> : std::true_type
0094 //{};
0095 
0096 #else // OTHER_STDLIB
0097 
0098 // TODO - add other iterators implementations
0099 
0100 #endif // STDLIB
0101 
0102 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
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 // destroy(I, I)
0156 
0157 template <typename I>
0158 void destroy_dispatch(I /*first*/, I /*last*/,
0159                       std::true_type /*has_trivial_destructor*/)
0160 {}
0161 
0162 template <typename I>
0163 void destroy_dispatch(I first, I last,
0164                       std::false_type /*has_trivial_destructor*/)
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 // destroy(I)
0179 
0180 template <typename I>
0181 void destroy_dispatch(I /*pos*/,
0182                       std::true_type /*has_trivial_destructor*/)
0183 {}
0184 
0185 template <typename I>
0186 void destroy_dispatch(I pos,
0187                       std::false_type /*has_trivial_destructor*/)
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 // copy(I, I, O)
0201 
0202 template <typename I, typename O>
0203 inline O copy_dispatch(I first, I last, O dst,
0204                        std::true_type /*use_memmove*/)
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 /*use_memmove*/)
0216 {
0217     return std::copy(first, last, dst);                                         // may throw
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>());    // may throw
0224 }
0225 
0226 // uninitialized_copy(I, I, O)
0227 
0228 template <typename I, typename O>
0229 inline
0230 O uninitialized_copy_dispatch(I first, I last, O dst,
0231                               std::true_type /*use_memcpy*/)
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 /*use_memcpy*/)
0244 {
0245     return std::uninitialized_copy(first, last, dst);                                       // may throw
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>());  // may throw
0253 }
0254 
0255 // uninitialized_move(I, I, O)
0256 
0257 template <typename I, typename O>
0258 inline
0259 O uninitialized_move_dispatch(I first, I last, O dst,
0260                               std::true_type /*use_memcpy*/)
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 /*use_memcpy*/)
0273 {
0274     //return boost::uninitialized_move(first, last, dst);                         // may throw
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>()); // may throw
0299 }
0300 
0301 // TODO - move uses memmove - implement 2nd version using memcpy?
0302 
0303 // move(I, I, O)
0304 
0305 template <typename I, typename O>
0306 inline
0307 O move_dispatch(I first, I last, O dst,
0308                 std::true_type /*use_memmove*/)
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 /*use_memmove*/)
0321 {
0322     return std::move(first, last, dst);                                           // may throw
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>());      // may throw
0330 }
0331 
0332 // move_backward(BDI, BDI, BDO)
0333 
0334 template <typename BDI, typename BDO>
0335 inline
0336 BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
0337                            std::true_type /*use_memmove*/)
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 /*use_memmove*/)
0351 {
0352     return std::move_backward(first, last, dst);                                  // may throw
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>()); // may throw
0360 }
0361 
0362 // uninitialized_move_if_noexcept(I, I, O)
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 /*use_move*/)
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& /*use_move*/)
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());         // may throw
0389 }
0390 
0391 // move_if_noexcept(I, I, O)
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 /*use_move*/)
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 /*use_move*/)
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());         // may throw
0418 }
0419 
0420 // uninitialized_fill(I, I)
0421 
0422 template <typename I>
0423 inline
0424 void uninitialized_fill_dispatch(I /*first*/, I /*last*/,
0425                                  std::true_type const& /*has_trivial_constructor*/,
0426                                  std::true_type const& /*disable_trivial_init*/)
0427 {}
0428 
0429 template <typename I>
0430 inline
0431 void uninitialized_fill_dispatch(I first, I last,
0432                                  std::true_type const& /*has_trivial_constructor*/,
0433                                  std::false_type const& /*disable_trivial_init*/)
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& /*has_trivial_constructor*/,
0444                                  DisableTrivialInit const& /*not_used*/)
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();                           // may throw
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);     // may throw
0468 }
0469 
0470 // construct(I)
0471 
0472 template <typename I>
0473 inline
0474 void construct_dispatch(std::true_type /*dont_init*/, I /*pos*/)
0475 {}
0476 
0477 template <typename I>
0478 inline
0479 void construct_dispatch(std::false_type /*dont_init*/, I pos)
0480 {
0481     typedef typename ::boost::iterator_value<I>::type value_type;
0482     new (static_cast<void*>(boost::addressof(*pos))) value_type();                      // may throw
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);                                                // may throw
0499 }
0500 
0501 // construct(I, V)
0502 
0503 template <typename I, typename V>
0504 inline
0505 void construct_copy_dispatch(I pos, V const& v,
0506                              std::true_type /*use_memcpy*/)
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& /*use_memcpy*/)
0515 {
0516     typedef typename boost::iterator_value<I>::type V;
0517     new (static_cast<void*>(boost::addressof(*pos))) V(p);                      // may throw
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>());           // may throw
0526 }
0527 
0528 // Needed by push_back(V &&)
0529 
0530 template <typename I, typename V>
0531 inline
0532 void construct_move_dispatch(I pos, V const& v,
0533                              std::true_type const& /*use_memcpy*/)
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& /*use_memcpy*/)
0542 {
0543     typedef typename boost::iterator_value<I>::type V;
0544     new (static_cast<void*>(boost::addressof(*pos))) V(std::move(p));       // may throw
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>()); // may throw
0552 }
0553 
0554 // Needed by emplace_back() and emplace()
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)...);    // may throw
0564 }
0565 
0566 // assign(I, V)
0567 
0568 template <typename I, typename V>
0569 inline
0570 void assign_copy_dispatch(I pos, V const& v,
0571                           std::true_type /*use_memcpy*/)
0572 {
0573 // TODO - use memmove here?
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 /*use_memcpy*/)
0581 {
0582     *pos = v;                                                                   // may throw
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>());              // may throw
0590 }
0591 
0592 template <typename I, typename V>
0593 inline
0594 void assign_move_dispatch(I pos, V const& v,
0595                           std::true_type /*use_memcpy*/)
0596 {
0597 // TODO - use memmove here?
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 /*use_memcpy*/)
0605 {
0606     *pos = std::move(v);                                                          // may throw
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 // uninitialized_copy_s
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             // dummy 0 as DisableTrivialInit
0632             construct(0, it, *first);                                              // may throw
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 // scoped_destructor
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 }}}}} // namespace boost::geometry::index::detail::varray_detail
0666 
0667 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP