diff options
Diffstat (limited to 'boost/geometry/index/detail/rtree/pack_create.hpp')
-rw-r--r-- | boost/geometry/index/detail/rtree/pack_create.hpp | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/boost/geometry/index/detail/rtree/pack_create.hpp b/boost/geometry/index/detail/rtree/pack_create.hpp index 46bf357fc4..b7be41ab2b 100644 --- a/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/boost/geometry/index/detail/rtree/pack_create.hpp @@ -2,7 +2,7 @@ // // R-tree initial packing // -// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2015 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 @@ -122,7 +122,7 @@ class pack typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf; typedef typename Allocators::node_pointer node_pointer; - typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr; + typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer; typedef typename Allocators::size_type size_type; typedef typename geometry::point_type<Box>::type point_type; @@ -161,10 +161,21 @@ public: geometry::assign_inverse(hint_box); for ( ; first != last ; ++first ) { - geometry::expand(hint_box, translator(*first)); + // NOTE: support for iterators not returning true references adapted + // to Geometry concept and default translator returning true reference + // An alternative would be to dereference the iterator and translate + // in one expression each time the indexable was needed. + typename std::iterator_traits<InIt>::reference in_ref = *first; + typename Translator::result_type indexable = translator(in_ref); + + // NOTE: added for consistency with insert() + // CONSIDER: alternative - ignore invalid indexable or throw an exception + BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(indexable), "Indexable is invalid"); + + geometry::expand(hint_box, indexable); point_type pt; - geometry::centroid(translator(*first), pt); + geometry::centroid(indexable, pt); entries.push_back(std::make_pair(pt, first)); } @@ -187,17 +198,19 @@ private: internal_element per_level(EIt first, EIt last, Box const& hint_box, std::size_t values_count, subtree_elements_counts const& subtree_counts, parameters_type const& parameters, Translator const& translator, Allocators & allocators) { - BOOST_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count); + BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count, + "unexpected parameters"); if ( subtree_counts.maxc <= 1 ) { // ROOT or LEAF - BOOST_ASSERT(values_count <= parameters.get_max_elements()); + BOOST_GEOMETRY_INDEX_ASSERT(values_count <= parameters.get_max_elements(), + "too big number of elements"); // if !root check m_parameters.get_min_elements() <= count // create new leaf node node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A) - node_auto_ptr auto_remover(n, allocators); + subtree_destroyer auto_remover(n, allocators); leaf & l = rtree::get<leaf>(*n); // reserve space for values @@ -207,8 +220,11 @@ private: geometry::assign_inverse(elements_box); for ( ; first != last ; ++first ) { - rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C) + // NOTE: push_back() must be called at the end in order to support move_iterator. + // The iterator is dereferenced 2x (no temporary reference) to support + // non-true reference types and move_iterator without boost::forward<>. geometry::expand(elements_box, translator(*(first->second))); + rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C) } auto_remover.release(); @@ -222,7 +238,7 @@ private: // create new internal node node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A) - node_auto_ptr auto_remover(n, allocators); + subtree_destroyer auto_remover(n, allocators); internal_node & in = rtree::get<internal_node>(*n); // reserve space for values @@ -248,9 +264,11 @@ private: internal_elements & elements, Box & elements_box, parameters_type const& parameters, Translator const& translator, Allocators & allocators) { - BOOST_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count); + BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count, + "unexpected parameters"); - BOOST_ASSERT_MSG( subtree_counts.minc <= values_count, "too small number of elements"); + BOOST_GEOMETRY_INDEX_ASSERT(subtree_counts.minc <= values_count, + "too small number of elements"); // only one packet if ( values_count <= subtree_counts.maxc ) @@ -262,7 +280,7 @@ private: // in case if push_back() do throw here // and even if this is not probable (previously reserved memory, nonthrowing pairs copy) // this case is also tested by exceptions test. - node_auto_ptr auto_remover(el.second, allocators); + subtree_destroyer auto_remover(el.second, allocators); // this container should have memory allocated, reserve() called outside elements.push_back(el); // MAY THROW (A?,C) - however in normal conditions shouldn't auto_remover.release(); @@ -343,7 +361,7 @@ private: { if ( subtree_counts.minc <= r ) // e.g. 10 <= 2 == false { - //BOOST_ASSERT_MSG(0 < n, "unexpected value"); + //BOOST_GEOMETRY_INDEX_ASSERT(0 < n, "unexpected value"); median_count = ((n+1)/2) * subtree_counts.maxc; // if calculated ((2+1)/2) * 25 which would be ok, but not in all cases } else // r < subtree_counts.second // e.g. 2 < 10 == true @@ -354,7 +372,7 @@ private: if ( r == 0 ) // e.g. false { // n can't be equal to 0 because then there wouldn't be any element in the other node - //BOOST_ASSERT_MSG(0 < n, "unexpected value"); + //BOOST_GEOMETRY_INDEX_ASSERT(0 < n, "unexpected value"); median_count = ((n+1)/2) * subtree_counts.maxc; // if calculated ((1+1)/2) * 25 which would be ok, but not in all cases } else |