// Boost.Geometry Index // // R-tree nodes // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // 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_RTREE_NODE_NODE_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP #include #include #include #include #include #include //#include //#include //#include #include #include #include #include #include #include #include namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { // elements box template inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr) { Box result; if ( first == last ) { geometry::assign_inverse(result); return result; } detail::bounds(element_indexable(*first, tr), result); ++first; for ( ; first != last ; ++first ) geometry::expand(result, element_indexable(*first, tr)); return result; } // destroys subtree if the element is internal node's element template struct destroy_element { typedef typename Options::parameters_type parameters_type; typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; typedef rtree::node_auto_ptr node_auto_ptr; inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators) { node_auto_ptr dummy(element.second, allocators); element.second = 0; } inline static void apply(typename leaf::elements_type::value_type &, Allocators &) {} }; // destroys stored subtrees if internal node's elements are passed template struct destroy_elements { template inline static void apply(Range & elements, Allocators & allocators) { apply(boost::begin(elements), boost::end(elements), allocators); } template inline static void apply(It first, It last, Allocators & allocators) { typedef boost::mpl::bool_< boost::is_same< Value, typename std::iterator_traits::value_type >::value > is_range_of_values; apply_dispatch(first, last, allocators, is_range_of_values()); } private: template inline static void apply_dispatch(It first, It last, Allocators & allocators, boost::mpl::bool_ const& /*is_range_of_values*/) { typedef rtree::node_auto_ptr node_auto_ptr; for ( ; first != last ; ++first ) { node_auto_ptr dummy(first->second, allocators); first->second = 0; } } template inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/, boost::mpl::bool_ const& /*is_range_of_values*/) {} }; // clears node, deletes all subtrees stored in node template struct clear_node { typedef typename Options::parameters_type parameters_type; typedef typename rtree::node::type node; typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; inline static void apply(node & node, Allocators & allocators) { rtree::visitors::is_leaf ilv; rtree::apply_visitor(ilv, node); if ( ilv.result ) { apply(rtree::get(node), allocators); } else { apply(rtree::get(node), allocators); } } inline static void apply(internal_node & internal_node, Allocators & allocators) { destroy_elements::apply(rtree::elements(internal_node), allocators); rtree::elements(internal_node).clear(); } inline static void apply(leaf & leaf, Allocators &) { rtree::elements(leaf).clear(); } }; template void move_from_back(Container & container, Iterator it) { BOOST_GEOMETRY_INDEX_ASSERT(!container.empty(), "cannot copy from empty container"); Iterator back_it = container.end(); --back_it; if ( it != back_it ) { *it = boost::move(*back_it); // MAY THROW (copy) } } }} // namespace detail::rtree }}} // namespace boost::geometry::index #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP