diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
commit | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch) | |
tree | 7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/geometry/index/detail/varray_detail.hpp | |
parent | bb4dd8289b351fae6b55e303f189127a394a1edd (diff) | |
download | boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2 boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip |
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/geometry/index/detail/varray_detail.hpp')
-rw-r--r-- | boost/geometry/index/detail/varray_detail.hpp | 756 |
1 files changed, 756 insertions, 0 deletions
diff --git a/boost/geometry/index/detail/varray_detail.hpp b/boost/geometry/index/detail/varray_detail.hpp new file mode 100644 index 0000000000..962d4d8288 --- /dev/null +++ b/boost/geometry/index/detail/varray_detail.hpp @@ -0,0 +1,756 @@ +// Boost.Geometry +// +// varray details +// +// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2013 Andrew Hundt. +// +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP + +#include <cstddef> +#include <cstring> +#include <memory> +#include <limits> + +#include <boost/mpl/if.hpp> +#include <boost/mpl/and.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/int.hpp> + +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/has_trivial_assign.hpp> +#include <boost/type_traits/has_trivial_copy.hpp> +#include <boost/type_traits/has_trivial_constructor.hpp> +#include <boost/type_traits/has_trivial_destructor.hpp> +#include <boost/type_traits/has_trivial_move_constructor.hpp> +#include <boost/type_traits/has_trivial_move_assign.hpp> +//#include <boost/type_traits/has_nothrow_constructor.hpp> +//#include <boost/type_traits/has_nothrow_copy.hpp> +//#include <boost/type_traits/has_nothrow_assign.hpp> +//#include <boost/type_traits/has_nothrow_destructor.hpp> + +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/config.hpp> +#include <boost/move/move.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/iterator/iterator_traits.hpp> + +// TODO - move vectors iterators optimization to the other, optional file instead of checking defines? + +#if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS) +#include <vector> +#include <boost/container/vector.hpp> +#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS + +namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail { + +template <typename I> +struct are_elements_contiguous : boost::is_pointer<I> +{}; + +// EXPERIMENTAL - not finished +// Conditional setup - mark vector iterators defined in known implementations +// as iterators pointing to contiguous ranges + +#if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS) + +template <typename Pointer> +struct are_elements_contiguous< + boost::container::container_detail::vector_const_iterator<Pointer> +> : boost::true_type +{}; + +template <typename Pointer> +struct are_elements_contiguous< + boost::container::container_detail::vector_iterator<Pointer> +> : boost::true_type +{}; + +#if defined(BOOST_DINKUMWARE_STDLIB) + +template <typename T> +struct are_elements_contiguous< + std::_Vector_const_iterator<T> +> : boost::true_type +{}; + +template <typename T> +struct are_elements_contiguous< + std::_Vector_iterator<T> +> : boost::true_type +{}; + +#elif defined(BOOST_GNU_STDLIB) + +template <typename P, typename T, typename A> +struct are_elements_contiguous< + __gnu_cxx::__normal_iterator<P, std::vector<T, A> > +> : boost::true_type +{}; + +#elif defined(_LIBCPP_VERSION) + +// TODO - test it first +//template <typename P> +//struct are_elements_contiguous< +// __wrap_iter<P> +//> : boost::true_type +//{}; + +#else // OTHER_STDLIB + +// TODO - add other iterators implementations + +#endif // STDLIB + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS + +// True if iterator values are the same and both iterators points to the ranges of contiguous elements + +template <typename I, typename O> +struct are_corresponding : + ::boost::mpl::and_< + ::boost::is_same< + ::boost::remove_const< + typename ::boost::iterator_value<I>::type + >, + ::boost::remove_const< + typename ::boost::iterator_value<O>::type + > + >, + are_elements_contiguous<I>, + are_elements_contiguous<O> + > +{}; + +template <typename I, typename V> +struct is_corresponding_value : + ::boost::is_same< + ::boost::remove_const< + typename ::boost::iterator_value<I>::type + >, + ::boost::remove_const<V> + > +{}; + +// destroy(I, I) + +template <typename I> +void destroy_dispatch(I /*first*/, I /*last*/, + boost::true_type const& /*has_trivial_destructor*/) +{} + +template <typename I> +void destroy_dispatch(I first, I last, + boost::false_type const& /*has_trivial_destructor*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + for ( ; first != last ; ++first ) + first->~value_type(); +} + +template <typename I> +void destroy(I first, I last) +{ + typedef typename boost::iterator_value<I>::type value_type; + destroy_dispatch(first, last, has_trivial_destructor<value_type>()); +} + +// destroy(I) + +template <typename I> +void destroy_dispatch(I /*pos*/, + boost::true_type const& /*has_trivial_destructor*/) +{} + +template <typename I> +void destroy_dispatch(I pos, + boost::false_type const& /*has_trivial_destructor*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + pos->~value_type(); +} + +template <typename I> +void destroy(I pos) +{ + typedef typename boost::iterator_value<I>::type value_type; + destroy_dispatch(pos, has_trivial_destructor<value_type>()); +} + +// copy(I, I, O) + +template <typename I, typename O> +inline O copy_dispatch(I first, I last, O dst, + boost::mpl::bool_<true> const& /*use_memmove*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + typename boost::iterator_difference<I>::type d = std::distance(first, last); + + ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); + return dst + d; +} + +template <typename I, typename O> +inline O copy_dispatch(I first, I last, O dst, + boost::mpl::bool_<false> const& /*use_memmove*/) +{ + return std::copy(first, last, dst); // may throw +} + +template <typename I, typename O> +inline O copy(I first, I last, O dst) +{ + typedef typename + ::boost::mpl::and_< + are_corresponding<I, O>, + ::boost::has_trivial_assign< + typename ::boost::iterator_value<O>::type + > + >::type + use_memmove; + + return copy_dispatch(first, last, dst, use_memmove()); // may throw +} + +// uninitialized_copy(I, I, O) + +template <typename I, typename O> +inline +O uninitialized_copy_dispatch(I first, I last, O dst, + boost::mpl::bool_<true> const& /*use_memcpy*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + typename boost::iterator_difference<I>::type d = std::distance(first, last); + + ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); + return dst + d; +} + +template <typename I, typename F> +inline +F uninitialized_copy_dispatch(I first, I last, F dst, + boost::mpl::bool_<false> const& /*use_memcpy*/) +{ + return std::uninitialized_copy(first, last, dst); // may throw +} + +template <typename I, typename F> +inline +F uninitialized_copy(I first, I last, F dst) +{ + typedef typename + ::boost::mpl::and_< + are_corresponding<I, F>, + ::boost::has_trivial_copy< + typename ::boost::iterator_value<F>::type + > + >::type + use_memcpy; + + return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw +} + +// uninitialized_move(I, I, O) + +template <typename I, typename O> +inline +O uninitialized_move_dispatch(I first, I last, O dst, + boost::mpl::bool_<true> const& /*use_memcpy*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + typename boost::iterator_difference<I>::type d = std::distance(first, last); + + ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); + return dst + d; +} + +template <typename I, typename O> +inline +O uninitialized_move_dispatch(I first, I last, O dst, + boost::mpl::bool_<false> const& /*use_memcpy*/) +{ + //return boost::uninitialized_move(first, last, dst); // may throw + + O o = dst; + + BOOST_TRY + { + typedef typename std::iterator_traits<O>::value_type value_type; + for (; first != last; ++first, ++o ) + new (boost::addressof(*o)) value_type(boost::move(*first)); + } + BOOST_CATCH(...) + { + destroy(dst, o); + BOOST_RETHROW; + } + BOOST_CATCH_END + + return dst; +} + +template <typename I, typename O> +inline +O uninitialized_move(I first, I last, O dst) +{ + typedef typename + ::boost::mpl::and_< + are_corresponding<I, O>, + ::boost::has_trivial_copy< + typename ::boost::iterator_value<O>::type + > + >::type + use_memcpy; + + return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw +} + +// TODO - move uses memmove - implement 2nd version using memcpy? + +// move(I, I, O) + +template <typename I, typename O> +inline +O move_dispatch(I first, I last, O dst, + boost::mpl::bool_<true> const& /*use_memmove*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + typename boost::iterator_difference<I>::type d = std::distance(first, last); + + ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d); + return dst + d; +} + +template <typename I, typename O> +inline +O move_dispatch(I first, I last, O dst, + boost::mpl::bool_<false> const& /*use_memmove*/) +{ + return boost::move(first, last, dst); // may throw +} + +template <typename I, typename O> +inline +O move(I first, I last, O dst) +{ + typedef typename + ::boost::mpl::and_< + are_corresponding<I, O>, + ::boost::has_trivial_assign< + typename ::boost::iterator_value<O>::type + > + >::type + use_memmove; + + return move_dispatch(first, last, dst, use_memmove()); // may throw +} + +// move_backward(BDI, BDI, BDO) + +template <typename BDI, typename BDO> +inline +BDO move_backward_dispatch(BDI first, BDI last, BDO dst, + boost::mpl::bool_<true> const& /*use_memmove*/) +{ + typedef typename boost::iterator_value<BDI>::type value_type; + typename boost::iterator_difference<BDI>::type d = std::distance(first, last); + + BDO foo(dst - d); + ::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d); + return foo; +} + +template <typename BDI, typename BDO> +inline +BDO move_backward_dispatch(BDI first, BDI last, BDO dst, + boost::mpl::bool_<false> const& /*use_memmove*/) +{ + return boost::move_backward(first, last, dst); // may throw +} + +template <typename BDI, typename BDO> +inline +BDO move_backward(BDI first, BDI last, BDO dst) +{ + typedef typename + ::boost::mpl::and_< + are_corresponding<BDI, BDO>, + ::boost::has_trivial_assign< + typename ::boost::iterator_value<BDO>::type + > + >::type + use_memmove; + + return move_backward_dispatch(first, last, dst, use_memmove()); // may throw +} + +template <typename T> +struct has_nothrow_move : public + ::boost::mpl::or_< + boost::mpl::bool_< + ::boost::has_nothrow_move< + typename ::boost::remove_const<T>::type + >::value + >, + boost::mpl::bool_< + ::boost::has_nothrow_move<T>::value + > + > +{}; + +// uninitialized_move_if_noexcept(I, I, O) + +template <typename I, typename O> +inline +O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/) +{ return varray_detail::uninitialized_move(first, last, dst); } + +template <typename I, typename O> +inline +O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/) +{ return varray_detail::uninitialized_copy(first, last, dst); } + +template <typename I, typename O> +inline +O uninitialized_move_if_noexcept(I first, I last, O dst) +{ + typedef typename has_nothrow_move< + typename ::boost::iterator_value<O>::type + >::type use_move; + + return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw +} + +// move_if_noexcept(I, I, O) + +template <typename I, typename O> +inline +O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/) +{ return move(first, last, dst); } + +template <typename I, typename O> +inline +O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/) +{ return copy(first, last, dst); } + +template <typename I, typename O> +inline +O move_if_noexcept(I first, I last, O dst) +{ + typedef typename has_nothrow_move< + typename ::boost::iterator_value<O>::type + >::type use_move; + + return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw +} + +// uninitialized_fill(I, I) + +template <typename I> +inline +void uninitialized_fill_dispatch(I /*first*/, I /*last*/, + boost::true_type const& /*has_trivial_constructor*/, + boost::true_type const& /*disable_trivial_init*/) +{} + +template <typename I> +inline +void uninitialized_fill_dispatch(I first, I last, + boost::true_type const& /*has_trivial_constructor*/, + boost::false_type const& /*disable_trivial_init*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + for ( ; first != last ; ++first ) + new (boost::addressof(*first)) value_type(); +} + +template <typename I, typename DisableTrivialInit> +inline +void uninitialized_fill_dispatch(I first, I last, + boost::false_type const& /*has_trivial_constructor*/, + DisableTrivialInit const& /*not_used*/) +{ + typedef typename boost::iterator_value<I>::type value_type; + I it = first; + + BOOST_TRY + { + for ( ; it != last ; ++it ) + new (boost::addressof(*it)) value_type(); // may throw + } + BOOST_CATCH(...) + { + destroy(first, it); + BOOST_RETHROW; + } + BOOST_CATCH_END +} + +template <typename I, typename DisableTrivialInit> +inline +void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init) +{ + typedef typename boost::iterator_value<I>::type value_type; + uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw +} + +// construct(I) + +template <typename I> +inline +void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I /*pos*/) +{} + +template <typename I> +inline +void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos) +{ + typedef typename ::boost::iterator_value<I>::type value_type; + new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw +} + +template <typename DisableTrivialInit, typename I> +inline +void construct(DisableTrivialInit const&, I pos) +{ + typedef typename ::boost::iterator_value<I>::type value_type; + typedef typename ::boost::mpl::and_< + boost::has_trivial_constructor<value_type>, + DisableTrivialInit + >::type dont_init; + + construct_dispatch(dont_init(), pos); // may throw +} + +// construct(I, V) + +template <typename I, typename V> +inline +void construct_copy_dispatch(I pos, V const& v, + boost::mpl::bool_<true> const& /*use_memcpy*/) +{ + ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); +} + +template <typename I, typename P> +inline +void construct_copy_dispatch(I pos, P const& p, + boost::mpl::bool_<false> const& /*use_memcpy*/) +{ + typedef typename boost::iterator_value<I>::type V; + new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw +} + +template <typename DisableTrivialInit, typename I, typename P> +inline +void construct(DisableTrivialInit const&, + I pos, P const& p) +{ + typedef typename + ::boost::mpl::and_< + is_corresponding_value<I, P>, + ::boost::has_trivial_copy<P> + >::type + use_memcpy; + + construct_copy_dispatch(pos, p, use_memcpy()); // may throw +} + +// Needed by push_back(V &&) + +template <typename I, typename V> +inline +void construct_move_dispatch(I pos, V const& v, + boost::mpl::bool_<true> const& /*use_memcpy*/) +{ + ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); +} + +template <typename I, typename P> +inline +void construct_move_dispatch(I pos, BOOST_RV_REF(P) p, + boost::mpl::bool_<false> const& /*use_memcpy*/) +{ + typedef typename boost::iterator_value<I>::type V; + new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw +} + +template <typename DisableTrivialInit, typename I, typename P> +inline +void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p) +{ + typedef typename + ::boost::mpl::and_< + is_corresponding_value<I, P>, + ::boost::has_trivial_move_constructor<P> + >::type + use_memcpy; + + construct_move_dispatch(pos, ::boost::move(p), use_memcpy()); // may throw +} + +// Needed by emplace_back() and emplace() + +#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template <typename DisableTrivialInit, typename I, class ...Args> +inline +void construct(DisableTrivialInit const&, + I pos, + BOOST_FWD_REF(Args) ...args) +{ + typedef typename boost::iterator_value<I>::type V; + new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw +} + +#else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES + +// BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 const& p0 +// !BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 && p0 +// which means that version with one parameter may take V const& v + +#define BOOST_PP_LOCAL_MACRO(n) \ +template <typename DisableTrivialInit, typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \ +inline \ +void construct(DisableTrivialInit const&, \ + I pos, \ + BOOST_CONTAINER_PP_PARAM(P, p) \ + BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ +{ \ + typedef typename boost::iterator_value<I>::type V; \ + new \ + (static_cast<void*>(boost::addressof(*pos))) \ + V(p, BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); /*may throw*/ \ +} \ +// +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) +#include BOOST_PP_LOCAL_ITERATE() + +#endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE + +// assign(I, V) + +template <typename I, typename V> +inline +void assign_copy_dispatch(I pos, V const& v, + boost::mpl::bool_<true> const& /*use_memcpy*/) +{ +// TODO - use memmove here? + ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); +} + +template <typename I, typename V> +inline +void assign_copy_dispatch(I pos, V const& v, + boost::mpl::bool_<false> const& /*use_memcpy*/) +{ + *pos = v; // may throw +} + +template <typename I, typename V> +inline +void assign(I pos, V const& v) +{ + typedef typename + ::boost::mpl::and_< + is_corresponding_value<I, V>, + ::boost::has_trivial_assign<V> + >::type + use_memcpy; + + assign_copy_dispatch(pos, v, use_memcpy()); // may throw +} + +template <typename I, typename V> +inline +void assign_move_dispatch(I pos, V const& v, + boost::mpl::bool_<true> const& /*use_memcpy*/) +{ +// TODO - use memmove here? + ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V)); +} + +template <typename I, typename V> +inline +void assign_move_dispatch(I pos, BOOST_RV_REF(V) v, + boost::mpl::bool_<false> const& /*use_memcpy*/) +{ + *pos = boost::move(v); // may throw +} + +template <typename I, typename V> +inline +void assign(I pos, BOOST_RV_REF(V) v) +{ + typedef typename + ::boost::mpl::and_< + is_corresponding_value<I, V>, + ::boost::has_trivial_move_assign<V> + >::type + use_memcpy; + + assign_move_dispatch(pos, ::boost::move(v), use_memcpy()); +} + +// uninitialized_copy_s + +template <typename I, typename F> +inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count) +{ + std::size_t count = 0; + F it = dest; + + BOOST_TRY + { + for ( ; first != last ; ++it, ++first, ++count ) + { + if ( max_count <= count ) + return (std::numeric_limits<std::size_t>::max)(); + + // dummy 0 as DisableTrivialInit + construct(0, it, *first); // may throw + } + } + BOOST_CATCH(...) + { + destroy(dest, it); + BOOST_RETHROW; + } + BOOST_CATCH_END + + return count; +} + +// scoped_destructor + +template<class T> +class scoped_destructor +{ +public: + scoped_destructor(T * ptr) : m_ptr(ptr) {} + + ~scoped_destructor() + { + if(m_ptr) + destroy(m_ptr); + } + + void release() { m_ptr = 0; } + +private: + T * m_ptr; +}; + +}}}}} // namespace boost::geometry::index::detail::varray_detail + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP |