Chris@16: // Boost.Geometry Chris@16: // Chris@16: // varray details Chris@16: // Chris@101: // Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland. Chris@16: // Copyright (c) 2011-2013 Andrew Hundt. Chris@16: // Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP Chris@16: #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: //#include Chris@16: //#include Chris@16: //#include Chris@16: //#include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: Chris@101: #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@101: #include Chris@101: #endif Chris@101: Chris@16: // TODO - move vectors iterators optimization to the other, optional file instead of checking defines? Chris@16: Chris@16: #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS) Chris@16: #include Chris@16: #include Chris@16: #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS Chris@16: Chris@16: namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail { Chris@16: Chris@16: template Chris@16: struct are_elements_contiguous : boost::is_pointer Chris@16: {}; Chris@16: Chris@16: // EXPERIMENTAL - not finished Chris@16: // Conditional setup - mark vector iterators defined in known implementations Chris@16: // as iterators pointing to contiguous ranges Chris@16: Chris@16: #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS) Chris@16: Chris@16: template Chris@16: struct are_elements_contiguous< Chris@16: boost::container::container_detail::vector_const_iterator Chris@16: > : boost::true_type Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct are_elements_contiguous< Chris@16: boost::container::container_detail::vector_iterator Chris@16: > : boost::true_type Chris@16: {}; Chris@16: Chris@16: #if defined(BOOST_DINKUMWARE_STDLIB) Chris@16: Chris@16: template Chris@16: struct are_elements_contiguous< Chris@16: std::_Vector_const_iterator Chris@16: > : boost::true_type Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct are_elements_contiguous< Chris@16: std::_Vector_iterator Chris@16: > : boost::true_type Chris@16: {}; Chris@16: Chris@16: #elif defined(BOOST_GNU_STDLIB) Chris@16: Chris@16: template Chris@16: struct are_elements_contiguous< Chris@16: __gnu_cxx::__normal_iterator > Chris@16: > : boost::true_type Chris@16: {}; Chris@16: Chris@16: #elif defined(_LIBCPP_VERSION) Chris@16: Chris@16: // TODO - test it first Chris@16: //template Chris@16: //struct are_elements_contiguous< Chris@16: // __wrap_iter

Chris@16: //> : boost::true_type Chris@16: //{}; Chris@16: Chris@16: #else // OTHER_STDLIB Chris@16: Chris@16: // TODO - add other iterators implementations Chris@16: Chris@16: #endif // STDLIB Chris@16: Chris@16: #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS Chris@16: Chris@16: // True if iterator values are the same and both iterators points to the ranges of contiguous elements Chris@16: Chris@16: template Chris@16: struct are_corresponding : Chris@16: ::boost::mpl::and_< Chris@16: ::boost::is_same< Chris@16: ::boost::remove_const< Chris@16: typename ::boost::iterator_value::type Chris@16: >, Chris@16: ::boost::remove_const< Chris@16: typename ::boost::iterator_value::type Chris@16: > Chris@16: >, Chris@16: are_elements_contiguous, Chris@16: are_elements_contiguous Chris@16: > Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct is_corresponding_value : Chris@16: ::boost::is_same< Chris@16: ::boost::remove_const< Chris@16: typename ::boost::iterator_value::type Chris@16: >, Chris@16: ::boost::remove_const Chris@16: > Chris@16: {}; Chris@16: Chris@16: // destroy(I, I) Chris@16: Chris@16: template Chris@16: void destroy_dispatch(I /*first*/, I /*last*/, Chris@16: boost::true_type const& /*has_trivial_destructor*/) Chris@16: {} Chris@16: Chris@16: template Chris@16: void destroy_dispatch(I first, I last, Chris@16: boost::false_type const& /*has_trivial_destructor*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: for ( ; first != last ; ++first ) Chris@16: first->~value_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: void destroy(I first, I last) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: destroy_dispatch(first, last, has_trivial_destructor()); Chris@16: } Chris@16: Chris@16: // destroy(I) Chris@16: Chris@16: template Chris@16: void destroy_dispatch(I /*pos*/, Chris@16: boost::true_type const& /*has_trivial_destructor*/) Chris@16: {} Chris@16: Chris@16: template Chris@16: void destroy_dispatch(I pos, Chris@16: boost::false_type const& /*has_trivial_destructor*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: pos->~value_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: void destroy(I pos) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: destroy_dispatch(pos, has_trivial_destructor()); Chris@16: } Chris@16: Chris@16: // copy(I, I, O) Chris@16: Chris@16: template Chris@16: inline O copy_dispatch(I first, I last, O dst, Chris@16: boost::mpl::bool_ const& /*use_memmove*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: typename boost::iterator_difference::type d = std::distance(first, last); Chris@16: Chris@16: ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); Chris@16: return dst + d; Chris@16: } Chris@16: Chris@16: template Chris@16: inline O copy_dispatch(I first, I last, O dst, Chris@16: boost::mpl::bool_ const& /*use_memmove*/) Chris@16: { Chris@16: return std::copy(first, last, dst); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline O copy(I first, I last, O dst) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: are_corresponding, Chris@16: ::boost::has_trivial_assign< Chris@16: typename ::boost::iterator_value::type Chris@16: > Chris@16: >::type Chris@16: use_memmove; Chris@16: Chris@16: return copy_dispatch(first, last, dst, use_memmove()); // may throw Chris@16: } Chris@16: Chris@16: // uninitialized_copy(I, I, O) Chris@16: Chris@16: template Chris@16: inline Chris@16: O uninitialized_copy_dispatch(I first, I last, O dst, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: typename boost::iterator_difference::type d = std::distance(first, last); Chris@16: Chris@16: ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); Chris@16: return dst + d; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: F uninitialized_copy_dispatch(I first, I last, F dst, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: return std::uninitialized_copy(first, last, dst); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: F uninitialized_copy(I first, I last, F dst) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: are_corresponding, Chris@16: ::boost::has_trivial_copy< Chris@16: typename ::boost::iterator_value::type Chris@16: > Chris@16: >::type Chris@16: use_memcpy; Chris@16: Chris@16: return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw Chris@16: } Chris@16: Chris@16: // uninitialized_move(I, I, O) Chris@16: Chris@16: template Chris@16: inline Chris@16: O uninitialized_move_dispatch(I first, I last, O dst, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: typename boost::iterator_difference::type d = std::distance(first, last); Chris@16: Chris@16: ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); Chris@16: return dst + d; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: O uninitialized_move_dispatch(I first, I last, O dst, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: //return boost::uninitialized_move(first, last, dst); // may throw Chris@16: Chris@16: O o = dst; Chris@16: Chris@16: BOOST_TRY Chris@16: { Chris@16: typedef typename std::iterator_traits::value_type value_type; Chris@16: for (; first != last; ++first, ++o ) Chris@16: new (boost::addressof(*o)) value_type(boost::move(*first)); Chris@16: } Chris@16: BOOST_CATCH(...) Chris@16: { Chris@16: destroy(dst, o); Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: Chris@16: return dst; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: O uninitialized_move(I first, I last, O dst) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: are_corresponding, Chris@16: ::boost::has_trivial_copy< Chris@16: typename ::boost::iterator_value::type Chris@16: > Chris@16: >::type Chris@16: use_memcpy; Chris@16: Chris@16: return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw Chris@16: } Chris@16: Chris@16: // TODO - move uses memmove - implement 2nd version using memcpy? Chris@16: Chris@16: // move(I, I, O) Chris@16: Chris@16: template Chris@16: inline Chris@16: O move_dispatch(I first, I last, O dst, Chris@16: boost::mpl::bool_ const& /*use_memmove*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: typename boost::iterator_difference::type d = std::distance(first, last); Chris@16: Chris@16: ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); Chris@16: return dst + d; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: O move_dispatch(I first, I last, O dst, Chris@16: boost::mpl::bool_ const& /*use_memmove*/) Chris@16: { Chris@16: return boost::move(first, last, dst); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: O move(I first, I last, O dst) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: are_corresponding, Chris@16: ::boost::has_trivial_assign< Chris@16: typename ::boost::iterator_value::type Chris@16: > Chris@16: >::type Chris@16: use_memmove; Chris@16: Chris@16: return move_dispatch(first, last, dst, use_memmove()); // may throw Chris@16: } Chris@16: Chris@16: // move_backward(BDI, BDI, BDO) Chris@16: Chris@16: template Chris@16: inline Chris@16: BDO move_backward_dispatch(BDI first, BDI last, BDO dst, Chris@16: boost::mpl::bool_ const& /*use_memmove*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: typename boost::iterator_difference::type d = std::distance(first, last); Chris@16: Chris@16: BDO foo(dst - d); Chris@16: ::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d); Chris@16: return foo; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: BDO move_backward_dispatch(BDI first, BDI last, BDO dst, Chris@16: boost::mpl::bool_ const& /*use_memmove*/) Chris@16: { Chris@16: return boost::move_backward(first, last, dst); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: BDO move_backward(BDI first, BDI last, BDO dst) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: are_corresponding, Chris@16: ::boost::has_trivial_assign< Chris@16: typename ::boost::iterator_value::type Chris@16: > Chris@16: >::type Chris@16: use_memmove; Chris@16: Chris@16: return move_backward_dispatch(first, last, dst, use_memmove()); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: struct has_nothrow_move : public Chris@16: ::boost::mpl::or_< Chris@16: boost::mpl::bool_< Chris@16: ::boost::has_nothrow_move< Chris@16: typename ::boost::remove_const::type Chris@16: >::value Chris@16: >, Chris@16: boost::mpl::bool_< Chris@16: ::boost::has_nothrow_move::value Chris@16: > Chris@16: > Chris@16: {}; Chris@16: Chris@16: // uninitialized_move_if_noexcept(I, I, O) Chris@16: Chris@16: template Chris@16: inline Chris@16: O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) Chris@16: { return varray_detail::uninitialized_move(first, last, dst); } Chris@16: Chris@16: template Chris@16: inline Chris@16: O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) Chris@16: { return varray_detail::uninitialized_copy(first, last, dst); } Chris@16: Chris@16: template Chris@16: inline Chris@16: O uninitialized_move_if_noexcept(I first, I last, O dst) Chris@16: { Chris@16: typedef typename has_nothrow_move< Chris@16: typename ::boost::iterator_value::type Chris@16: >::type use_move; Chris@16: Chris@16: return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw Chris@16: } Chris@16: Chris@16: // move_if_noexcept(I, I, O) Chris@16: Chris@16: template Chris@16: inline Chris@16: O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) Chris@16: { return move(first, last, dst); } Chris@16: Chris@16: template Chris@16: inline Chris@16: O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_ const& /*use_move*/) Chris@16: { return copy(first, last, dst); } Chris@16: Chris@16: template Chris@16: inline Chris@16: O move_if_noexcept(I first, I last, O dst) Chris@16: { Chris@16: typedef typename has_nothrow_move< Chris@16: typename ::boost::iterator_value::type Chris@16: >::type use_move; Chris@16: Chris@16: return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw Chris@16: } Chris@16: Chris@16: // uninitialized_fill(I, I) Chris@16: Chris@16: template Chris@16: inline Chris@16: void uninitialized_fill_dispatch(I /*first*/, I /*last*/, Chris@16: boost::true_type const& /*has_trivial_constructor*/, Chris@16: boost::true_type const& /*disable_trivial_init*/) Chris@16: {} Chris@16: Chris@16: template Chris@16: inline Chris@16: void uninitialized_fill_dispatch(I first, I last, Chris@16: boost::true_type const& /*has_trivial_constructor*/, Chris@16: boost::false_type const& /*disable_trivial_init*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: for ( ; first != last ; ++first ) Chris@16: new (boost::addressof(*first)) value_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void uninitialized_fill_dispatch(I first, I last, Chris@16: boost::false_type const& /*has_trivial_constructor*/, Chris@16: DisableTrivialInit const& /*not_used*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: I it = first; Chris@16: Chris@16: BOOST_TRY Chris@16: { Chris@16: for ( ; it != last ; ++it ) Chris@16: new (boost::addressof(*it)) value_type(); // may throw Chris@16: } Chris@16: BOOST_CATCH(...) Chris@16: { Chris@16: destroy(first, it); Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init) Chris@16: { Chris@16: typedef typename boost::iterator_value::type value_type; Chris@16: uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor(), disable_trivial_init); // may throw Chris@16: } Chris@16: Chris@16: // construct(I) Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct_dispatch(boost::mpl::bool_ const& /*dont_init*/, I /*pos*/) Chris@16: {} Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct_dispatch(boost::mpl::bool_ const& /*dont_init*/, I pos) Chris@16: { Chris@16: typedef typename ::boost::iterator_value::type value_type; Chris@16: new (static_cast(::boost::addressof(*pos))) value_type(); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct(DisableTrivialInit const&, I pos) Chris@16: { Chris@16: typedef typename ::boost::iterator_value::type value_type; Chris@16: typedef typename ::boost::mpl::and_< Chris@16: boost::has_trivial_constructor, Chris@16: DisableTrivialInit Chris@16: >::type dont_init; Chris@16: Chris@16: construct_dispatch(dont_init(), pos); // may throw Chris@16: } Chris@16: Chris@16: // construct(I, V) Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct_copy_dispatch(I pos, V const& v, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct_copy_dispatch(I pos, P const& p, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type V; Chris@16: new (static_cast(boost::addressof(*pos))) V(p); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct(DisableTrivialInit const&, Chris@16: I pos, P const& p) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: is_corresponding_value, Chris@16: ::boost::has_trivial_copy

Chris@16: >::type Chris@16: use_memcpy; Chris@16: Chris@16: construct_copy_dispatch(pos, p, use_memcpy()); // may throw Chris@16: } Chris@16: Chris@16: // Needed by push_back(V &&) Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct_move_dispatch(I pos, V const& v, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct_move_dispatch(I pos, BOOST_RV_REF(P) p, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: typedef typename boost::iterator_value::type V; Chris@16: new (static_cast(boost::addressof(*pos))) V(::boost::move(p)); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: is_corresponding_value, Chris@16: ::boost::has_trivial_move_constructor

Chris@16: >::type Chris@16: use_memcpy; Chris@16: Chris@16: construct_move_dispatch(pos, ::boost::move(p), use_memcpy()); // may throw Chris@16: } Chris@16: Chris@16: // Needed by emplace_back() and emplace() Chris@16: Chris@16: #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE) Chris@101: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@16: Chris@16: template Chris@16: inline Chris@16: void construct(DisableTrivialInit const&, Chris@16: I pos, Chris@16: BOOST_FWD_REF(Args) ...args) Chris@16: { Chris@16: typedef typename boost::iterator_value::type V; Chris@16: new (static_cast(boost::addressof(*pos))) V(::boost::forward(args)...); // may throw Chris@16: } Chris@16: Chris@101: #else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: Chris@101: // BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 const& p0 Chris@101: // !BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 && p0 Chris@16: // which means that version with one parameter may take V const& v Chris@16: Chris@101: #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT(N) \ Chris@101: template \ Chris@16: inline \ Chris@16: void construct(DisableTrivialInit const&, \ Chris@16: I pos, \ Chris@101: BOOST_FWD_REF(P) p \ Chris@101: BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \ Chris@16: { \ Chris@16: typedef typename boost::iterator_value::type V; \ Chris@16: new \ Chris@16: (static_cast(boost::addressof(*pos))) \ Chris@101: V(boost::forward

(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/ \ Chris@16: } \ Chris@16: Chris@101: BOOST_MOVE_ITERATE_1TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT) Chris@101: #undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT Chris@101: Chris@101: #endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE Chris@16: Chris@16: // assign(I, V) Chris@16: Chris@16: template Chris@16: inline Chris@16: void assign_copy_dispatch(I pos, V const& v, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: // TODO - use memmove here? Chris@16: ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void assign_copy_dispatch(I pos, V const& v, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: *pos = v; // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void assign(I pos, V const& v) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: is_corresponding_value, Chris@16: ::boost::has_trivial_assign Chris@16: >::type Chris@16: use_memcpy; Chris@16: Chris@16: assign_copy_dispatch(pos, v, use_memcpy()); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void assign_move_dispatch(I pos, V const& v, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: // TODO - use memmove here? Chris@16: ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void assign_move_dispatch(I pos, BOOST_RV_REF(V) v, Chris@16: boost::mpl::bool_ const& /*use_memcpy*/) Chris@16: { Chris@16: *pos = boost::move(v); // may throw Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: void assign(I pos, BOOST_RV_REF(V) v) Chris@16: { Chris@16: typedef typename Chris@16: ::boost::mpl::and_< Chris@16: is_corresponding_value, Chris@16: ::boost::has_trivial_move_assign Chris@16: >::type Chris@16: use_memcpy; Chris@16: Chris@16: assign_move_dispatch(pos, ::boost::move(v), use_memcpy()); Chris@16: } Chris@16: Chris@16: // uninitialized_copy_s Chris@16: Chris@16: template Chris@16: inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count) Chris@16: { Chris@16: std::size_t count = 0; Chris@16: F it = dest; Chris@16: Chris@16: BOOST_TRY Chris@16: { Chris@16: for ( ; first != last ; ++it, ++first, ++count ) Chris@16: { Chris@16: if ( max_count <= count ) Chris@16: return (std::numeric_limits::max)(); Chris@16: Chris@16: // dummy 0 as DisableTrivialInit Chris@16: construct(0, it, *first); // may throw Chris@16: } Chris@16: } Chris@16: BOOST_CATCH(...) Chris@16: { Chris@16: destroy(dest, it); Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: Chris@16: return count; Chris@16: } Chris@16: Chris@16: // scoped_destructor Chris@16: Chris@16: template Chris@16: class scoped_destructor Chris@16: { Chris@16: public: Chris@16: scoped_destructor(T * ptr) : m_ptr(ptr) {} Chris@16: Chris@16: ~scoped_destructor() Chris@16: { Chris@16: if(m_ptr) Chris@16: destroy(m_ptr); Chris@16: } Chris@16: Chris@16: void release() { m_ptr = 0; } Chris@16: Chris@16: private: Chris@16: T * m_ptr; Chris@16: }; Chris@16: Chris@16: }}}}} // namespace boost::geometry::index::detail::varray_detail Chris@16: Chris@16: #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP