diff --git a/doc/index/imports.qbk b/doc/index/imports.qbk index 4502ee41c..535395091 100644 --- a/doc/index/imports.qbk +++ b/doc/index/imports.qbk @@ -14,6 +14,7 @@ [import src/examples/rtree/variants_map.cpp] [import src/examples/rtree/value_shared_ptr.cpp] [import src/examples/rtree/value_index.cpp] +[import src/examples/rtree/range_adaptors.cpp] [import src/examples/rtree/iterative_query.cpp] [import src/examples/rtree/interprocess.cpp] [import src/examples/rtree/mapped_file.cpp] diff --git a/doc/index/rtree/creation.qbk b/doc/index/rtree/creation.qbk index 6ea609b08..7f5f8290a 100644 --- a/doc/index/rtree/creation.qbk +++ b/doc/index/rtree/creation.qbk @@ -164,7 +164,7 @@ stored in another container. [h4 Additional interface] The __rtree__ allows creation, inserting and removing of Values from a range. The range may be passed as -[first, last) Iterators pair or as a Range. +`[first, last)` Iterators pair or as a Range adapted to one of the Boost.Range Concepts. namespace bgi = boost::geometry::index; typedef std::pair __value__; @@ -184,13 +184,13 @@ The __rtree__ allows creation, inserting and removing of Values from a range. Th // create R-tree with default constructor and insert values with insert(Range) RTree rt3; - rt3.insert(values); + rt3.insert(values_range); // create R-tree with constructor taking Iterators RTree rt4(values.begin(), values.end()); // create R-tree with constructor taking Range - RTree rt5(values); + RTree rt5(values_range); // remove values with remove(Value const&) BOOST_FOREACH(__value__ const& v, values) @@ -200,7 +200,13 @@ The __rtree__ allows creation, inserting and removing of Values from a range. Th rt2.remove(values.begin(), values.end()); // remove values with remove(Range) - rt3.remove(values); + rt3.remove(values_range); + +Furthermore, it's possible to pass a Range adapted by one of the Boost.Range adaptors into the rtree (more complete example can be found in the *Examples* section). + + // create Rtree containing `std::pair` from a container of Boxes on the fly. + RTree rt6(boxes | boost::adaptors::indexed() + | boost::adaptors::transformed(pair_maker())); [h4 Insert iterator] diff --git a/doc/index/rtree/examples.qbk b/doc/index/rtree/examples.qbk index ba82e88f0..37157caa5 100644 --- a/doc/index/rtree/examples.qbk +++ b/doc/index/rtree/examples.qbk @@ -46,10 +46,16 @@ [include ../src/examples/rtree/value_index_results.qbk] [endsect] +[section Range adaptors] +[rtree_range_adaptors] +[h4 Expected results] +[include ../src/examples/rtree/range_adaptors_results.qbk] +[endsect] + [section Iterative query] [rtree_iterative_query] [h4 Expected results] -[include ../src/examples/rtree/iterative_query.qbk] +[include ../src/examples/rtree/iterative_query_results.qbk] [endsect] [section Index stored in shared memory using Boost.Interprocess] diff --git a/doc/index/src/examples/rtree/Jamfile.v2 b/doc/index/src/examples/rtree/Jamfile.v2 index 3e03c6000..e28a6e07b 100644 --- a/doc/index/src/examples/rtree/Jamfile.v2 +++ b/doc/index/src/examples/rtree/Jamfile.v2 @@ -10,6 +10,7 @@ exe iterative_query : iterative_query.cpp ; exe polygons_shared_ptr : polygons_shared_ptr.cpp ; exe polygons_vector : polygons_vector.cpp ; exe quick_start : quick_start.cpp ; +exe range_adaptors : range_adaptors.cpp ; exe value_index : value_index.cpp ; exe value_shared_ptr : value_shared_ptr.cpp ; exe variants_map : variants_map.cpp ; diff --git a/doc/index/src/examples/rtree/iterative_query.cpp b/doc/index/src/examples/rtree/iterative_query.cpp index 32ce87606..1afb53ee5 100644 --- a/doc/index/src/examples/rtree/iterative_query.cpp +++ b/doc/index/src/examples/rtree/iterative_query.cpp @@ -22,7 +22,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -int main(void) +int main() { typedef bg::model::point point; typedef point value; diff --git a/doc/index/src/examples/rtree/iterative_query.qbk b/doc/index/src/examples/rtree/iterative_query_results.qbk similarity index 100% rename from doc/index/src/examples/rtree/iterative_query.qbk rename to doc/index/src/examples/rtree/iterative_query_results.qbk diff --git a/doc/index/src/examples/rtree/polygons_shared_ptr.cpp b/doc/index/src/examples/rtree/polygons_shared_ptr.cpp index 0d34e23fe..a97e78805 100644 --- a/doc/index/src/examples/rtree/polygons_shared_ptr.cpp +++ b/doc/index/src/examples/rtree/polygons_shared_ptr.cpp @@ -26,7 +26,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; diff --git a/doc/index/src/examples/rtree/polygons_vector.cpp b/doc/index/src/examples/rtree/polygons_vector.cpp index 7102862c6..28fc9c183 100644 --- a/doc/index/src/examples/rtree/polygons_vector.cpp +++ b/doc/index/src/examples/rtree/polygons_vector.cpp @@ -25,7 +25,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; diff --git a/doc/index/src/examples/rtree/quick_start.cpp b/doc/index/src/examples/rtree/quick_start.cpp index fd3834449..d95836cf5 100644 --- a/doc/index/src/examples/rtree/quick_start.cpp +++ b/doc/index/src/examples/rtree/quick_start.cpp @@ -29,7 +29,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; //] -int main(void) +int main() { //[rtree_quickstart_valuetype typedef bg::model::point point; @@ -47,7 +47,7 @@ int main(void) for ( unsigned i = 0 ; i < 10 ; ++i ) { // create a box - box b(point(i, i), point(i + 0.5f, i + 0.5f)); + box b(point(i + 0.0f, i + 0.0f), point(i + 0.5f, i + 0.5f)); // insert new value rtree.insert(std::make_pair(b, i)); } diff --git a/doc/index/src/examples/rtree/range_adaptors.cpp b/doc/index/src/examples/rtree/range_adaptors.cpp new file mode 100644 index 000000000..f01d978cf --- /dev/null +++ b/doc/index/src/examples/rtree/range_adaptors.cpp @@ -0,0 +1,79 @@ +// Boost.Geometry Index +// +// Quickbook Examples +// +// 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) + +//[rtree_range_adaptors + +#include +#include +#include + +#include + +// Boost.Range +#include +// adaptors +#include +#include + +// a container +#include + +// just for output +#include + +namespace bg = boost::geometry; +namespace bgi = boost::geometry::index; + +// Define a function object converting a value_type of indexed Range into std::pair<>. +// This is a generic implementation but of course it'd be possible to use some +// specific types. One could also take Value as template parameter and access +// first_type and second_type members, etc. +template +struct pair_maker +{ + typedef std::pair result_type; + template + inline result_type operator()(T const& v) const + { + return result_type(v.value(), v.index()); + } +}; + +int main() +{ + typedef bg::model::point point; + typedef bg::model::box box; + + typedef std::vector container; + typedef container::size_type size_type; + + typedef std::pair value; + + // create a container of boxes + container boxes; + for ( size_type i = 0 ; i < 10 ; ++i ) + { + // add a box into the container + box b(point(i + 0.0f, i + 0.0f), point(i + 0.5f, i + 0.5f)); + boxes.push_back(b); + } + + // create the rtree using default constructor + bgi::rtree< value, bgi::quadratic<16> > + rtree(boxes | boost::adaptors::indexed() + | boost::adaptors::transformed(pair_maker())); + + // print the number of values using boxes[0] as indexable + std::cout << rtree.count(boxes[0]) << std::endl; + + return 0; +} + +//] diff --git a/doc/index/src/examples/rtree/range_adaptors_results.qbk b/doc/index/src/examples/rtree/range_adaptors_results.qbk new file mode 100644 index 000000000..a50537ae3 --- /dev/null +++ b/doc/index/src/examples/rtree/range_adaptors_results.qbk @@ -0,0 +1,11 @@ +[/============================================================================ + Boost.Geometry Index + + Copyright (c) 2011-2014 Adam Wulkiewicz. + + 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) +=============================================================================/] + + 1 diff --git a/doc/index/src/examples/rtree/value_index.cpp b/doc/index/src/examples/rtree/value_index.cpp index 6f245403b..f005c4d42 100644 --- a/doc/index/src/examples/rtree/value_index.cpp +++ b/doc/index/src/examples/rtree/value_index.cpp @@ -37,7 +37,7 @@ public: result_type operator()(size_t i) const { return container[i]; } }; -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; @@ -52,7 +52,7 @@ int main(void) for ( unsigned i = 0 ; i < 10 ; ++i ) { // add a box - boxes.push_back(box(point(i, i), point(i+0.5f, i+0.5f))); + boxes.push_back(box(point(i+0.0f, i+0.0f), point(i+0.5f, i+0.5f))); } // display boxes diff --git a/doc/index/src/examples/rtree/value_shared_ptr.cpp b/doc/index/src/examples/rtree/value_shared_ptr.cpp index bf20646fe..33701e09f 100644 --- a/doc/index/src/examples/rtree/value_shared_ptr.cpp +++ b/doc/index/src/examples/rtree/value_shared_ptr.cpp @@ -38,7 +38,7 @@ struct indexable< boost::shared_ptr > }}} // namespace boost::geometry::index -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; @@ -54,7 +54,7 @@ int main(void) for ( unsigned i = 0 ; i < 10 ; ++i ) { // create a box - shp b(new box(point(i, i), point(i+0.5f, i+0.5f))); + shp b(new box(point(i+0.0f, i+0.0f), point(i+0.5f, i+0.5f))); // display new box std::cout << bg::wkt(*b) << std::endl; diff --git a/doc/index/src/examples/rtree/variants_map.cpp b/doc/index/src/examples/rtree/variants_map.cpp index efc043e3d..24ffe899e 100644 --- a/doc/index/src/examples/rtree/variants_map.cpp +++ b/doc/index/src/examples/rtree/variants_map.cpp @@ -65,7 +65,7 @@ struct envelope_visitor : public boost::static_visitor }; -int main(void) +int main() { // geometries container map geometries; diff --git a/doc/quickref.xml b/doc/quickref.xml index 232451723..38801566d 100644 --- a/doc/quickref.xml +++ b/doc/quickref.xml @@ -733,10 +733,10 @@ swap(rtree &) insert(value_type const &) insert(Iterator, Iterator) - insert(Range const &) + insert(ConvertibleOrRange const &) remove(value_type const &) remove(Iterator, Iterator) - remove(Range const &) + remove(ConvertibleOrRange const &) query(Predicates const &, OutIter) qbegin(Predicates const &) qend() @@ -756,10 +756,10 @@ insert(rtree<...> &, Value const &) insert(rtree<...> &, Iterator, Iterator) - insert(rtree<...> &, Range const &) + insert(rtree<...> &, ConvertibleOrRange const &) remove(rtree<...> &, Value const &) remove(rtree<...> &, Iterator, Iterator) - remove(rtree<...> &, Range const &) + remove(rtree<...> &, ConvertibleOrRange const &) query(rtree<...> const &, Predicates const &, OutIter) qbegin(rtree<...> const &, Predicates const &) qend(rtree<...> const &) diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 40f4939be..7fd40cdd0 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -21,9 +21,16 @@ [*Improvements] +* The support of parameters convertible to value_type in rtree insert(), remove() and count() functions + [*Solved tickets] +* [@https://svn.boost.org/trac/boost/ticket/8402 8402] Implicit casts warnings +* [@https://svn.boost.org/trac/boost/ticket/9354 9354] Bug in winding strategy affecting within() and covered_by() for non-cartesian coordinate systems +* [@https://svn.boost.org/trac/boost/ticket/10177 10177] Missing include * [@https://svn.boost.org/trac/boost/ticket/10398 10398] Wrong neighbour check in buffer, calculating turns +* [@https://svn.boost.org/trac/boost/ticket/10615 10615] Rtree constructor feature request +* [@https://svn.boost.org/trac/boost/ticket/10643 10643] Invalid point_on_surface() result for big coordinates [*Bugfixes] @@ -61,6 +68,7 @@ * [@https://svn.boost.org/trac/boost/ticket/9628 9628] Wrong result of within() due to the winding strategy not working correctly for nearly-horizontal segments * [@https://svn.boost.org/trac/boost/ticket/9828 9828] boost::geometry::union_(...) creates redundant closing point * [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike +* [@https://svn.boost.org/trac/boost/ticket/9941 9941] Add support for touches(box, box) * [@https://svn.boost.org/trac/boost/ticket/9947 9947] Missing info about WKT in documentation * [@https://svn.boost.org/trac/boost/ticket/9759 9759] Invalid results of R-tree knn queries for non-cartesian coordinate systems * [@https://svn.boost.org/trac/boost/ticket/10019 10019] Difference of Linestring and Box returns their intersection diff --git a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp index 23b09e1c8..395921cca 100644 --- a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp @@ -135,10 +135,6 @@ class piece_turn_visitor it2 != it2_last; prev2 = it2++, the_model.operations[1].seg_id.segment_index++) { - // Revert (this is used more often - should be common function TODO) - the_model.operations[0].other_id = the_model.operations[1].seg_id; - the_model.operations[1].other_id = the_model.operations[0].seg_id; - iterator next2 = next_point(ring2, it2); // TODO: internally get_turn_info calculates robust points. diff --git a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp index 18c33bfc3..f2efcb309 100644 --- a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp +++ b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp @@ -128,7 +128,7 @@ private: linestring const& ls2 = range::at(m_multilinestring, - turn.operations[0].other_id.multi_index); + turn.operations[1].seg_id.multi_index); return is_boundary_point_of(turn.point, ls1) diff --git a/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp b/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp index 2272bbf32..c59139a92 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp @@ -104,12 +104,12 @@ private: , m_parent_id(num_nodes, -1) {} - inline int parent_id(vertex_handle v) const + inline signed_index_type parent_id(vertex_handle v) const { return m_parent_id[v->id()]; } - inline void set_parent_id(vertex_handle v, int id) + inline void set_parent_id(vertex_handle v, signed_index_type id) { m_parent_id[v->id()] = id; } @@ -125,7 +125,7 @@ private: } private: std::vector m_visited; - std::vector m_parent_id; + std::vector m_parent_id; }; @@ -145,7 +145,7 @@ private: = m_neighbors[v->id()].begin(); nit != m_neighbors[v->id()].end(); ++nit) { - if ( static_cast((*nit)->id()) != data.parent_id(v) ) + if ( static_cast((*nit)->id()) != data.parent_id(v) ) { if ( data.visited(*nit) ) { @@ -153,7 +153,7 @@ private: } else { - data.set_parent_id(*nit, static_cast(v->id())); + data.set_parent_id(*nit, static_cast(v->id())); stack.push(*nit); } } @@ -173,7 +173,7 @@ public: // inserts a ring vertex in the graph and returns its handle // ring id's are zero-based (so the first interior ring has id 1) - inline vertex_handle add_vertex(int id) + inline vertex_handle add_vertex(signed_index_type id) { return m_vertices.insert(vertex(static_cast(id))).first; } diff --git a/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp b/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp index b14355639..6824921b6 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp @@ -40,11 +40,11 @@ inline void debug_print_turns(TurnIterator first, TurnIterator beyond) << " {" << tit->operations[0].seg_id.multi_index << ", " - << tit->operations[0].other_id.multi_index + << tit->operations[1].seg_id.multi_index << "} {" << tit->operations[0].seg_id.ring_index << ", " - << tit->operations[0].other_id.ring_index + << tit->operations[1].seg_id.ring_index << "} " << geometry::dsv(tit->point) << "]"; diff --git a/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp b/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp index 9841aafd2..f9d926770 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp @@ -94,7 +94,7 @@ public: using namespace detail::overlay; if ( turn.operations[0].seg_id.ring_index - == turn.operations[0].other_id.ring_index ) + == turn.operations[1].seg_id.ring_index ) { return false; } @@ -122,7 +122,7 @@ public: using namespace detail::overlay; if ( turn.operations[0].seg_id.multi_index - == turn.operations[0].other_id.multi_index ) + == turn.operations[1].seg_id.multi_index ) { return base::apply(turn); } diff --git a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp index 3934d1ba4..3d0ebb5f8 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp @@ -76,16 +76,16 @@ private: TurnIterator turns_beyond) { // collect all polygons that have turns - std::set multi_indices; + std::set multi_indices; for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) { multi_indices.insert(tit->operations[0].seg_id.multi_index); - multi_indices.insert(tit->operations[0].other_id.multi_index); + multi_indices.insert(tit->operations[1].seg_id.multi_index); } // put polygon iterators without turns in a vector std::vector polygon_iterators; - int multi_index = 0; + signed_index_type multi_index = 0; for (PolygonIterator it = polygons_first; it != polygons_beyond; ++it, ++multi_index) { @@ -112,7 +112,7 @@ private: class has_multi_index { public: - has_multi_index(int multi_index) + has_multi_index(signed_index_type multi_index) : m_multi_index(multi_index) {} @@ -120,11 +120,11 @@ private: inline bool operator()(Turn const& turn) const { return turn.operations[0].seg_id.multi_index == m_multi_index - && turn.operations[0].other_id.multi_index == m_multi_index; + && turn.operations[1].seg_id.multi_index == m_multi_index; } private: - int const m_multi_index; + signed_index_type const m_multi_index; }; @@ -138,7 +138,7 @@ private: TurnIterator turns_first, TurnIterator turns_beyond) { - int multi_index = 0; + signed_index_type multi_index = 0; for (PolygonIterator it = polygons_first; it != polygons_beyond; ++it, ++multi_index) { diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index 6df9b2c3d..3a9199920 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -175,22 +175,22 @@ protected: { // collect the interior ring indices that have turns with the // exterior ring - std::set ring_indices; + std::set ring_indices; for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) { if ( tit->operations[0].seg_id.ring_index == -1 ) { - BOOST_ASSERT( tit->operations[0].other_id.ring_index != -1 ); - ring_indices.insert(tit->operations[0].other_id.ring_index); + BOOST_ASSERT( tit->operations[1].seg_id.ring_index != -1 ); + ring_indices.insert(tit->operations[1].seg_id.ring_index); } - else if ( tit->operations[0].other_id.ring_index == -1 ) + else if ( tit->operations[1].seg_id.ring_index == -1 ) { BOOST_ASSERT( tit->operations[0].seg_id.ring_index != -1 ); ring_indices.insert(tit->operations[0].seg_id.ring_index); } } - int ring_index = 0; + signed_index_type ring_index = 0; for (RingIterator it = rings_first; it != rings_beyond; ++it, ++ring_index) { @@ -207,7 +207,7 @@ protected: for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) { ring_indices.insert(tit->operations[0].seg_id.ring_index); - ring_indices.insert(tit->operations[0].other_id.ring_index); + ring_indices.insert(tit->operations[1].seg_id.ring_index); } // put iterators for interior rings without turns in a vector @@ -290,7 +290,7 @@ protected: typename graph::vertex_handle v1 = g.add_vertex ( tit->operations[0].seg_id.ring_index + 1 ); typename graph::vertex_handle v2 = g.add_vertex - ( tit->operations[0].other_id.ring_index + 1 ); + ( tit->operations[1].seg_id.ring_index + 1 ); typename graph::vertex_handle vip = g.add_vertex(tit->point); g.add_edge(v1, vip); diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp index 5ee9b031e..20a6d7f48 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp @@ -53,7 +53,7 @@ struct copy_segment_point_range SegmentIdentifier const& seg_id, bool second, PointOut& point) { - int index = seg_id.segment_index; + signed_index_type index = seg_id.segment_index; if (second) { index++; @@ -112,7 +112,7 @@ struct copy_segment_point_box SegmentIdentifier const& seg_id, bool second, PointOut& point) { - int index = seg_id.segment_index; + signed_index_type index = seg_id.segment_index; if (second) { index++; diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp index 5aae862ce..ceeb1a3b8 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp @@ -63,7 +63,8 @@ struct copy_segments_ring typename RangeOut > static inline void apply(Ring const& ring, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { @@ -92,10 +93,10 @@ struct copy_segments_ring // So we use the ever-circling iterator and determine when to step out - int const from_index = seg_id.segment_index + 1; + signed_index_type const from_index = seg_id.segment_index + 1; // Sanity check - BOOST_ASSERT(from_index < int(boost::size(view))); + BOOST_ASSERT(from_index < static_cast(boost::size(view))); ec_iterator it(boost::begin(view), boost::end(view), boost::begin(view) + from_index); @@ -103,12 +104,12 @@ struct copy_segments_ring // [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK // [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK // [1..1], travel the whole ring round - typedef typename boost::range_difference::type size_type; - size_type const count = from_index <= to_index + signed_index_type const count = from_index <= to_index ? to_index - from_index + 1 - : int(boost::size(view)) - from_index + to_index + 1; + : static_cast(boost::size(view)) + - from_index + to_index + 1; - for (size_type i = 0; i < count; ++i, ++it) + for (signed_index_type i = 0; i < count; ++i, ++it) { detail::overlay::append_no_dups_or_spikes(current_output, *it, robust_policy); } @@ -149,27 +150,27 @@ public: typename RangeOut > static inline void apply(LineString const& ls, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { - int const from_index = seg_id.segment_index + 1; + signed_index_type const from_index = seg_id.segment_index + 1; // Sanity check if ( from_index > to_index || from_index < 0 - || to_index >= static_cast(boost::size(ls)) ) + || to_index >= static_cast(boost::size(ls)) ) { return; } - typedef typename boost::range_difference::type diff_t; - diff_t const count = to_index - from_index + 1; + signed_index_type const count = to_index - from_index + 1; typename boost::range_iterator::type it = boost::begin(ls) + from_index; - for (diff_t i = 0; i < count; ++i, ++it) + for (signed_index_type i = 0; i < count; ++i, ++it) { append_to_output(current_output, *it, robust_policy, boost::integral_constant()); @@ -188,7 +189,8 @@ struct copy_segments_polygon typename RangeOut > static inline void apply(Polygon const& polygon, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { @@ -217,14 +219,15 @@ struct copy_segments_box typename RangeOut > static inline void apply(Box const& box, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { - int index = seg_id.segment_index + 1; + signed_index_type index = seg_id.segment_index + 1; BOOST_ASSERT(index < 5); - int const count = index <= to_index + signed_index_type const count = index <= to_index ? to_index - index + 1 : 5 - index + to_index + 1; @@ -235,7 +238,7 @@ struct copy_segments_box // (possibly cyclic) copy to output // (see comments in ring-version) - for (int i = 0; i < count; i++, index++) + for (signed_index_type i = 0; i < count; i++, index++) { detail::overlay::append_no_dups_or_spikes(current_output, bp[index % 5], robust_policy); @@ -256,7 +259,8 @@ struct copy_segments_multi typename RangeOut > static inline void apply(MultiGeometry const& multi_geometry, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { @@ -343,7 +347,8 @@ template typename RangeOut > inline void copy_segments(Geometry const& geometry, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& range_out) { diff --git a/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp b/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp index 6668c9924..ef32edeef 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp @@ -37,7 +37,7 @@ struct enrichment_info // vertex to which is free travel after this IP, // so from "segment_index+1" to "travels_to_vertex_index", without IP-s, // can be -1 - int travels_to_vertex_index; + signed_index_type travels_to_vertex_index; // same but now IP index, so "next IP index" but not on THIS segment int travels_to_ip_index; diff --git a/include/boost/geometry/algorithms/detail/overlay/follow.hpp b/include/boost/geometry/algorithms/detail/overlay/follow.hpp index 83aa4ce6e..acf38d09a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow.hpp @@ -163,7 +163,7 @@ struct action_selector static inline void enter(LineStringOut& current_piece, LineString const& , segment_identifier& segment_id, - int , Point const& point, + signed_index_type , Point const& point, Operation const& operation, RobustPolicy const& , OutputIterator& ) @@ -186,7 +186,7 @@ struct action_selector static inline void leave(LineStringOut& current_piece, LineString const& linestring, segment_identifier& segment_id, - int index, Point const& point, + signed_index_type index, Point const& point, Operation const& , RobustPolicy const& robust_policy, OutputIterator& out) @@ -217,7 +217,7 @@ struct action_selector static inline void isolated_point(LineStringOut&, LineString const&, segment_identifier&, - int, Point const& point, + signed_index_type, Point const& point, Operation const& , OutputIterator& out) { LineStringOut isolated_point_ls; @@ -268,7 +268,7 @@ struct action_selector static inline void enter(LineStringOut& current_piece, LineString const& linestring, segment_identifier& segment_id, - int index, Point const& point, + signed_index_type index, Point const& point, Operation const& operation, RobustPolicy const& robust_policy, OutputIterator& out) @@ -289,7 +289,7 @@ struct action_selector static inline void leave(LineStringOut& current_piece, LineString const& linestring, segment_identifier& segment_id, - int index, Point const& point, + signed_index_type index, Point const& point, Operation const& operation, RobustPolicy const& robust_policy, OutputIterator& out) @@ -309,7 +309,7 @@ struct action_selector static inline void isolated_point(LineStringOut&, LineString const&, segment_identifier&, - int, Point const&, + signed_index_type, Point const&, Operation const&, OutputIterator&) { } @@ -496,7 +496,7 @@ public : false, RemoveSpikes >::apply(linestring, current_segment_id, - static_cast(boost::size(linestring) - 1), + static_cast(boost::size(linestring) - 1), robust_policy, current_piece); } diff --git a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp index 2954921a0..85378e08b 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp @@ -265,7 +265,7 @@ protected: false, false // do not reverse; do not remove spikes >::apply(linestring, current_segment_id, - static_cast(boost::size(linestring) - 1), + static_cast(boost::size(linestring) - 1), robust_policy, current_piece); } @@ -380,7 +380,7 @@ protected: }; template - static inline int get_multi_index(TurnIterator it) + static inline signed_index_type get_multi_index(TurnIterator it) { return boost::begin(it->operations)->seg_id.multi_index; } @@ -388,10 +388,10 @@ protected: class has_other_multi_id { private: - int m_multi_id; + signed_index_type m_multi_id; public: - has_other_multi_id(int multi_id) + has_other_multi_id(signed_index_type multi_id) : m_multi_id(multi_id) {} template @@ -422,7 +422,7 @@ public: // Iterate through all intersection points (they are // ordered along the each linestring) - int current_multi_id = get_multi_index(first); + signed_index_type current_multi_id = get_multi_index(first); oit = copy_linestrings::apply(ls_first, ls_first + current_multi_id, @@ -439,7 +439,7 @@ public: oit = Base::apply(*(ls_first + current_multi_id), linear, per_ls_current, per_ls_next, oit); - int next_multi_id(-1); + signed_index_type next_multi_id(-1); linestring_iterator ls_next = ls_beyond; if ( per_ls_next != beyond ) { diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp index 513bfd372..a96538c43 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp @@ -278,13 +278,12 @@ public : typedef typename boost::range_value::type turn_info; turn_info ti; - ti.operations[0].seg_id = segment_identifier(source_id1, - sec1.ring_id.multi_index, sec1.ring_id.ring_index, index1), - ti.operations[1].seg_id = segment_identifier(source_id2, - sec2.ring_id.multi_index, sec2.ring_id.ring_index, index2), - - ti.operations[0].other_id = ti.operations[1].seg_id; - ti.operations[1].other_id = ti.operations[0].seg_id; + ti.operations[0].seg_id + = segment_identifier(source_id1, sec1.ring_id.multi_index, + sec1.ring_id.ring_index, index1); + ti.operations[1].seg_id + = segment_identifier(source_id2, sec2.ring_id.multi_index, + sec2.ring_id.ring_index, index2); std::size_t const size_before = boost::size(turns); @@ -678,8 +677,6 @@ private: turn_info ti; ti.operations[0].seg_id = seg_id; - ti.operations[0].other_id = ti.operations[1].seg_id; - ti.operations[1].other_id = seg_id; ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 0); TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2, diff --git a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp index 29e0dad0c..44b5a0df3 100644 --- a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @@ -74,19 +74,17 @@ inline void map_turns(Map& map, TurnPoints const& turn_points) typedef typename boost::range_value::type turn_point_type; typedef typename turn_point_type::container_type container_type; - int index = 0; for (typename boost::range_iterator::type it = boost::begin(turn_points); it != boost::end(turn_points); - ++it, ++index) + ++it) { if (! skip(*it)) { - int op_index = 0; for (typename boost::range_iterator::type op_it = boost::begin(it->operations); op_it != boost::end(it->operations); - ++op_it, ++op_index) + ++op_it) { ring_identifier ring_id ( diff --git a/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp b/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp index e510b5bf9..516ec349e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp @@ -14,19 +14,19 @@ # define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER #endif - -#include +#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER) +#include +#endif -#include -#include - +#include namespace boost { namespace geometry { + // Internal struct to uniquely identify a segment // on a linestring,ring // or polygon (needs ring_index) @@ -40,7 +40,10 @@ struct segment_identifier , segment_index(-1) {} - inline segment_identifier(int src, int mul, int rin, int seg) + inline segment_identifier(signed_index_type src, + signed_index_type mul, + signed_index_type rin, + signed_index_type seg) : source_index(src) , multi_index(mul) , ring_index(rin) @@ -78,10 +81,10 @@ struct segment_identifier } #endif - int source_index; - int multi_index; - int ring_index; - int segment_index; + signed_index_type source_index; + signed_index_type multi_index; + signed_index_type ring_index; + signed_index_type segment_index; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp index bde86b4d7..59d2ba703 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp @@ -149,7 +149,9 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2, } -inline bool select_source(operation_type operation, int source1, int source2) +inline bool select_source(operation_type operation, + signed_index_type source1, + signed_index_type source2) { return (operation == operation_intersection && source1 != source2) || (operation == operation_union && source1 == source2) @@ -324,7 +326,7 @@ public : detail::overlay::debug_traverse(*current, *current_iit, "Selected "); - unsigned int i = 0; + typename boost::range_size::type i = 0; while (current_iit != iit && state.good()) { diff --git a/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp index 91a133789..26669a4b1 100644 --- a/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp @@ -59,7 +59,6 @@ struct turn_operation { operation_type operation; segment_identifier seg_id; - segment_identifier other_id; SegmentRatio fraction; inline turn_operation() diff --git a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp index 1896b0ffa..31d206ac9 100644 --- a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp @@ -230,7 +230,7 @@ struct areal_areal || may_update(result) ) { // sort turns - typedef turns::less<0, turns::less_op_areal_areal> less; + typedef turns::less<0, turns::less_op_areal_areal<0> > less; std::sort(turns.begin(), turns.end(), less()); /*if ( may_update(result) @@ -269,7 +269,7 @@ struct areal_areal || may_update(result) ) { // sort turns - typedef turns::less<1, turns::less_op_areal_areal> less; + typedef turns::less<1, turns::less_op_areal_areal<1> > less; std::sort(turns.begin(), turns.end(), less()); /*if ( may_update(result) diff --git a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp index b1f341eb0..3159ab329 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp @@ -244,7 +244,7 @@ struct linear_areal { // for different multi or same ring id: x, u, i, c // for same multi and different ring id: c, i, u, x - typedef turns::less<0, turns::less_op_linear_areal> less; + typedef turns::less<0, turns::less_op_linear_areal<0> > less; std::sort(turns.begin(), turns.end(), less()); turns_analyser analyser; @@ -341,7 +341,7 @@ struct linear_areal else { // u, c - typedef turns::less<1, turns::less_op_areal_linear> less; + typedef turns::less<1, turns::less_op_areal_linear<1> > less; std::sort(it, next, less()); // analyse diff --git a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp index f7ac7f5ed..263c82de5 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp @@ -161,7 +161,7 @@ struct linear_linear || may_update(result) || may_update(result) ) { - typedef turns::less<0, turns::less_op_linear_linear> less; + typedef turns::less<0, turns::less_op_linear_linear<0> > less; std::sort(turns.begin(), turns.end(), less()); turns_analyser analyser; @@ -181,7 +181,7 @@ struct linear_linear || may_update(result) || may_update(result) ) { - typedef turns::less<1, turns::less_op_linear_linear> less; + typedef turns::less<1, turns::less_op_linear_linear<1> > less; std::sort(turns.begin(), turns.end(), less()); turns_analyser analyser; @@ -626,7 +626,7 @@ struct linear_linear typename detail::single_geometry_return_type::type ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id); typename detail::single_geometry_return_type::type - ls2_ref = detail::single_geometry(other_geometry, turn.operations[op_id].other_id); + ls2_ref = detail::single_geometry(other_geometry, turn.operations[other_op_id].seg_id); // only one of those should be true: diff --git a/include/boost/geometry/algorithms/detail/relate/turns.hpp b/include/boost/geometry/algorithms/detail/relate/turns.hpp index b8c292bee..cef9b81ef 100644 --- a/include/boost/geometry/algorithms/detail/relate/turns.hpp +++ b/include/boost/geometry/algorithms/detail/relate/turns.hpp @@ -92,8 +92,8 @@ struct get_turns template struct op_to_int { - template - inline int operator()(Op const& op) const + template + inline int operator()(detail::overlay::turn_operation const& op) const { switch(op.operation) { @@ -108,85 +108,111 @@ struct op_to_int } }; -template +template struct less_op_xxx_linear { - template - inline bool operator()(Op const& left, Op const& right) + template + inline bool operator()(Turn const& left, Turn const& right) const { static OpToInt op_to_int; - return op_to_int(left) < op_to_int(right); + return op_to_int(left.operations[OpId]) < op_to_int(right.operations[OpId]); } }; +template struct less_op_linear_linear - : less_op_xxx_linear< op_to_int<0,2,3,1,4,0> > + : less_op_xxx_linear< OpId, op_to_int<0,2,3,1,4,0> > {}; +template struct less_op_linear_areal { - template - inline bool operator()(Op const& left, Op const& right) + template + inline bool operator()(Turn const& left, Turn const& right) const { + static const std::size_t other_op_id = (OpId + 1) % 2; static turns::op_to_int<0,2,3,1,4,0> op_to_int_xuic; static turns::op_to_int<0,3,2,1,4,0> op_to_int_xiuc; - if ( left.other_id.multi_index == right.other_id.multi_index ) + segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id; + segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id; + + if ( left_other_seg_id.multi_index == right_other_seg_id.multi_index ) { - if ( left.other_id.ring_index == right.other_id.ring_index ) - return op_to_int_xuic(left) < op_to_int_xuic(right); + typedef typename Turn::turn_operation_type operation_type; + operation_type const& left_operation = left.operations[OpId]; + operation_type const& right_operation = right.operations[OpId]; + + if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index ) + { + return op_to_int_xuic(left_operation) + < op_to_int_xuic(right_operation); + } else - return op_to_int_xiuc(left) < op_to_int_xiuc(right); + { + return op_to_int_xiuc(left_operation) + < op_to_int_xiuc(right_operation); + } } else { - //return op_to_int_xuic(left) < op_to_int_xuic(right); - return left.other_id.multi_index < right.other_id.multi_index; + //return op_to_int_xuic(left.operations[OpId]) < op_to_int_xuic(right.operations[OpId]); + return left_other_seg_id.multi_index < right_other_seg_id.multi_index; } } }; +template struct less_op_areal_linear - : less_op_xxx_linear< op_to_int<0,1,0,0,2,0> > + : less_op_xxx_linear< OpId, op_to_int<0,1,0,0,2,0> > {}; +template struct less_op_areal_areal { - template - inline bool operator()(Op const& left, Op const& right) + template + inline bool operator()(Turn const& left, Turn const& right) const { + static const std::size_t other_op_id = (OpId + 1) % 2; static op_to_int<0, 1, 2, 3, 4, 0> op_to_int_uixc; static op_to_int<0, 2, 1, 3, 4, 0> op_to_int_iuxc; - if ( left.other_id.multi_index == right.other_id.multi_index ) + segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id; + segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id; + + typedef typename Turn::turn_operation_type operation_type; + operation_type const& left_operation = left.operations[OpId]; + operation_type const& right_operation = right.operations[OpId]; + + if ( left_other_seg_id.multi_index == right_other_seg_id.multi_index ) { - if ( left.other_id.ring_index == right.other_id.ring_index ) + if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index ) { - return op_to_int_uixc(left) < op_to_int_uixc(right); + return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation); } else { - if ( left.other_id.ring_index == -1 ) + if ( left_other_seg_id.ring_index == -1 ) { - if ( left.operation == overlay::operation_union ) + if ( left_operation.operation == overlay::operation_union ) return false; - else if ( left.operation == overlay::operation_intersection ) + else if ( left_operation.operation == overlay::operation_intersection ) return true; } - else if ( right.other_id.ring_index == -1 ) + else if ( right_other_seg_id.ring_index == -1 ) { - if ( right.operation == overlay::operation_union ) + if ( right_operation.operation == overlay::operation_union ) return true; - else if ( right.operation == overlay::operation_intersection ) + else if ( right_operation.operation == overlay::operation_intersection ) return false; } - return op_to_int_iuxc(left) < op_to_int_iuxc(right); + return op_to_int_iuxc(left_operation) < op_to_int_iuxc(right_operation); } } else { - return op_to_int_uixc(left) < op_to_int_uixc(right); + return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation); } } }; @@ -194,20 +220,19 @@ struct less_op_areal_areal // sort turns by G1 - source_index == 0 by: // seg_id -> distance -> operation template > > + typename LessOp = less_op_xxx_linear< OpId, op_to_int<> > > struct less { BOOST_STATIC_ASSERT(OpId < 2); - template static inline - bool use_fraction(Op const& left, Op const& right) + template + static inline bool use_fraction(Turn const& left, Turn const& right) { - static LessOp less_op; + static const LessOp less_op; - if ( left.fraction == right.fraction ) - return less_op(left, right); - else - return left.fraction < right.fraction; + return left.operations[OpId].fraction < right.operations[OpId].fraction + || ( left.operations[OpId].fraction == right.operations[OpId].fraction + && less_op(left, right) ); } template @@ -216,7 +241,7 @@ struct less segment_identifier const& sl = left.operations[OpId].seg_id; segment_identifier const& sr = right.operations[OpId].seg_id; - return sl < sr || ( sl == sr && use_fraction(left.operations[OpId], right.operations[OpId]) ); + return sl < sr || ( sl == sr && use_fraction(left, right) ); } }; diff --git a/include/boost/geometry/algorithms/detail/ring_identifier.hpp b/include/boost/geometry/algorithms/detail/ring_identifier.hpp index 9209ee030..bc3fe1fef 100644 --- a/include/boost/geometry/algorithms/detail/ring_identifier.hpp +++ b/include/boost/geometry/algorithms/detail/ring_identifier.hpp @@ -10,6 +10,14 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP +#if defined(BOOST_GEOMETRY_DEBUG_IDENTIFIER) +#include +#endif + + +#include + + namespace boost { namespace geometry { @@ -24,7 +32,9 @@ struct ring_identifier , ring_index(-1) {} - inline ring_identifier(int src, int mul, int rin) + inline ring_identifier(signed_index_type src, + signed_index_type mul, + signed_index_type rin) : source_index(src) , multi_index(mul) , ring_index(rin) @@ -58,9 +68,9 @@ struct ring_identifier #endif - int source_index; - int multi_index; - int ring_index; + signed_index_type source_index; + signed_index_type multi_index; + signed_index_type ring_index; }; diff --git a/include/boost/geometry/algorithms/detail/signed_index_type.hpp b/include/boost/geometry/algorithms/detail/signed_index_type.hpp new file mode 100644 index 000000000..36dcf4de4 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/signed_index_type.hpp @@ -0,0 +1,29 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// 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_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP + + +#include +#include + + +namespace boost { namespace geometry +{ + + +typedef boost::make_signed::type signed_index_type; +//typedef std::ptrdiff_t signed_index_type; + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP diff --git a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp index 7e21c654e..c29d5863b 100644 --- a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp @@ -30,13 +30,14 @@ namespace detail { namespace turns // seg_id -> fraction -> other_id -> operation template < - typename IdLess = std::less, + typename IdLess = std::less, int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0, std::size_t OpId = 0 > struct less_seg_fraction_other_op { BOOST_STATIC_ASSERT(OpId < 2); + static const std::size_t other_op_id = (OpId + 1) % 2; template static inline int order_op(Op const& op) @@ -59,30 +60,33 @@ struct less_seg_fraction_other_op return order_op(left) < order_op(right); } - template - static inline bool use_other_id(Op const& left, Op const& right) + template + static inline bool use_other_id(Turn const& left, Turn const& right) { - if ( left.other_id.multi_index != right.other_id.multi_index ) + segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id; + segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id; + + if ( left_other_seg_id.multi_index != right_other_seg_id.multi_index ) { - return left.other_id.multi_index < right.other_id.multi_index; + return left_other_seg_id.multi_index < right_other_seg_id.multi_index; } - if ( left.other_id.ring_index != right.other_id.ring_index ) + if ( left_other_seg_id.ring_index != right_other_seg_id.ring_index ) { - return left.other_id.ring_index != right.other_id.ring_index; + return left_other_seg_id.ring_index != right_other_seg_id.ring_index; } - if ( left.other_id.segment_index != right.other_id.segment_index ) + if ( left_other_seg_id.segment_index != right_other_seg_id.segment_index ) { - return IdLess()(left.other_id.segment_index, - right.other_id.segment_index); + return IdLess()(left_other_seg_id.segment_index, + right_other_seg_id.segment_index); } - return use_operation(left, right); + return use_operation(left.operations[OpId], right.operations[OpId]); } - template - static inline bool use_fraction(Op const& left, Op const& right) + template + static inline bool use_fraction(Turn const& left, Turn const& right) { - return left.fraction < right.fraction - || ( geometry::math::equals(left.fraction, right.fraction) + return left.operations[OpId].fraction < right.operations[OpId].fraction + || ( geometry::math::equals(left.operations[OpId].fraction, right.operations[OpId].fraction) && use_other_id(left, right) ); } @@ -93,7 +97,7 @@ struct less_seg_fraction_other_op segment_identifier const& sl = left.operations[OpId].seg_id; segment_identifier const& sr = right.operations[OpId].seg_id; - return sl < sr || ( sl == sr && use_fraction(left.operations[OpId], right.operations[OpId]) ); + return sl < sr || ( sl == sr && use_fraction(left, right) ); } }; diff --git a/include/boost/geometry/algorithms/detail/turns/print_turns.hpp b/include/boost/geometry/algorithms/detail/turns/print_turns.hpp index 8b42a0ce9..b339e11c9 100644 --- a/include/boost/geometry/algorithms/detail/turns/print_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/print_turns.hpp @@ -62,10 +62,6 @@ static inline void print_turns(Geometry1 const& g1, << ", m: " << turn.operations[0].seg_id.multi_index << ", r: " << turn.operations[0].seg_id.ring_index << ", s: " << turn.operations[0].seg_id.segment_index << ", "; - out << "other: " << turn.operations[0].other_id.source_index - << ", m: " << turn.operations[0].other_id.multi_index - << ", r: " << turn.operations[0].other_id.ring_index - << ", s: " << turn.operations[0].other_id.segment_index; out << ", fr: " << fraction[0]; out << ", col?: " << turn.operations[0].is_collinear; out << ' ' << geometry::dsv(turn.point) << ' '; @@ -80,10 +76,6 @@ static inline void print_turns(Geometry1 const& g1, << ", m: " << turn.operations[1].seg_id.multi_index << ", r: " << turn.operations[1].seg_id.ring_index << ", s: " << turn.operations[1].seg_id.segment_index << ", "; - out << "other: " << turn.operations[1].other_id.source_index - << ", m: " << turn.operations[1].other_id.multi_index - << ", r: " << turn.operations[1].other_id.ring_index - << ", s: " << turn.operations[1].other_id.segment_index; out << ", fr: " << fraction[1]; out << ", col?: " << turn.operations[1].is_collinear; out << ' ' << geometry::dsv(turn.point) << ' '; diff --git a/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp b/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp index d48736c8f..ccb19efb7 100644 --- a/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp @@ -39,7 +39,7 @@ private: { return geometry::equals(t1.point, t2.point) && t1.operations[0].seg_id == t2.operations[0].seg_id - && t1.operations[0].other_id == t2.operations[0].other_id; + && t1.operations[1].seg_id == t2.operations[1].seg_id; } }; diff --git a/include/boost/geometry/algorithms/for_each.hpp b/include/boost/geometry/algorithms/for_each.hpp index f23a42d21..c5c099b1a 100644 --- a/include/boost/geometry/algorithms/for_each.hpp +++ b/include/boost/geometry/algorithms/for_each.hpp @@ -41,8 +41,7 @@ #include #include - -#include +#include namespace boost { namespace geometry @@ -95,30 +94,23 @@ struct fe_range_per_point }; -struct fe_range_per_segment +template +struct fe_range_per_segment_with_closure { template static inline void apply(Range& range, Functor& f) { - typedef typename closeable_view - < - Range, closure::value - >::type view_type; - typedef typename add_const_if_c < is_const::value, typename point_type::type >::type point_type; - typedef typename boost::range_iterator::type - iterator_type; + typedef typename boost::range_iterator::type iterator_type; - view_type view(range); - - iterator_type it = boost::begin(view); + iterator_type it = boost::begin(range); iterator_type previous = it++; - while(it != boost::end(view)) + while(it != boost::end(range)) { model::referring_segment s(*previous, *it); f(s); @@ -128,6 +120,41 @@ struct fe_range_per_segment }; +template <> +struct fe_range_per_segment_with_closure +{ + template + static inline void apply(Range& range, Functor& f) + { + fe_range_per_segment_with_closure::apply(range, f); + + model::referring_segment + < + typename add_const_if_c + < + is_const::value, + typename point_type::type + >::type + > s(range::back(range), range::front(range)); + + f(s); + } +}; + + +struct fe_range_per_segment +{ + template + static inline void apply(Range& range, Functor& f) + { + fe_range_per_segment_with_closure + < + closure::value + >::apply(range, f); + } +}; + + struct fe_polygon_per_point { template diff --git a/include/boost/geometry/algorithms/point_on_surface.hpp b/include/boost/geometry/algorithms/point_on_surface.hpp index a6f7ed71d..3fa83bfe6 100644 --- a/include/boost/geometry/algorithms/point_on_surface.hpp +++ b/include/boost/geometry/algorithms/point_on_surface.hpp @@ -5,6 +5,11 @@ // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -142,63 +147,30 @@ struct min_of_intruder } }; -template -inline void calculate_centroid(Point& point, Segments const& segments) + +template +inline void calculate_average(Point& point, std::vector

const& points) { - if (segments.size() == 3) - { - // In almost all cases, the segments do have 3 values. In that case we use another - // centroid calculation, which should be slightly faster - // and is more precise (case #geos_1_test_overlay => normal centroid is outside! TODO) + typedef typename geometry::coordinate_type::type coordinate_type; + typedef typename std::vector

::const_iterator iterator_type; + typedef typename std::vector

::size_type size_type; - typedef typename geometry::coordinate_type::type coordinate_type; - coordinate_type const three = 3.0; - coordinate_type const sx = geometry::get<0>(segments[0]) + geometry::get<0>(segments[1]) + geometry::get<0>(segments[2]); - coordinate_type const sy = geometry::get<1>(segments[0]) + geometry::get<1>(segments[1]) + geometry::get<1>(segments[2]); - geometry::set<0>(point, sx / three); - geometry::set<1>(point, sy / three); - return; + coordinate_type x = 0; + coordinate_type y = 0; + + iterator_type end = points.end(); + for ( iterator_type it = points.begin() ; it != end ; ++it) + { + x += geometry::get<0>(*it); + y += geometry::get<1>(*it); } - // For 4 or more segments, we use normal centroid calculation - - // Specify centroid, it should have "areal_tag" to have correct calculation - typedef typename strategy::centroid::services::default_strategy - < - typename cs_tag::type, - areal_tag, - dimension::type::value, - Point, - Point - >::type strategy_type; - - strategy_type strategy; - - - // Ignore warning (because using static method sometimes) on strategy - boost::ignore_unused_variable_warning(strategy); - - - typename strategy_type::state_type state; - - typedef typename boost::range_iterator::type iterator_type; - - iterator_type begin = boost::begin(segments); - iterator_type end = boost::end(segments); - iterator_type it = begin; - iterator_type previous = it++; - for (; it != end; ++previous, ++it) - { - strategy.apply(*previous, *it, state); - } - // Close it explicitly: - strategy.apply(*previous, *begin, state); - - strategy.result(state, point); + size_type const count = points.size(); + geometry::set<0>(point, x / count); + geometry::set<1>(point, y / count); } - template inline void replace_extremes_for_self_tangencies(Extremes& extremes, Intruders& intruders, CoordinateType const& max_intruder) { @@ -304,8 +276,8 @@ inline bool calculate_point_on_surface(Geometry const& geometry, Point& point) } } - // Now calculate the centroid of the (possibly adapted) extremes - calculate_centroid(point, extremes); + // Now calculate the average/centroid of the (possibly adapted) extremes + calculate_average(point, extremes); return true; } diff --git a/include/boost/geometry/core/coordinate_dimension.hpp b/include/boost/geometry/core/coordinate_dimension.hpp index e11ff33af..85da6b424 100644 --- a/include/boost/geometry/core/coordinate_dimension.hpp +++ b/include/boost/geometry/core/coordinate_dimension.hpp @@ -58,7 +58,15 @@ template struct dimension : dimension::type> {}; template -struct dimension : traits::dimension::type> {}; +struct dimension + : traits::dimension::type> +{ + BOOST_MPL_ASSERT_MSG( + (traits::dimension::type>::value > 0), + INVALID_DIMENSION_VALUE, + (traits::dimension::type>) + ); +}; } // namespace core_dispatch #endif diff --git a/include/boost/geometry/index/detail/algorithms/content.hpp b/include/boost/geometry/index/detail/algorithms/content.hpp index 1c4739d8e..028113e0e 100644 --- a/include/boost/geometry/index/detail/algorithms/content.hpp +++ b/include/boost/geometry/index/detail/algorithms/content.hpp @@ -2,7 +2,7 @@ // // n-dimensional content (hypervolume) - 2d area, 3d volume, ... // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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 @@ -24,11 +24,11 @@ struct default_content_result namespace dispatch { -template +template ::value> struct content_box { BOOST_STATIC_ASSERT(0 < CurrentDimension); - //BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension::value); static inline typename detail::default_content_result::type apply(Box const& b) { @@ -66,7 +66,7 @@ struct content { static typename default_content_result::type apply(Indexable const& b) { - return dispatch::content_box::value>::apply(b); + return dispatch::content_box::apply(b); } }; @@ -75,9 +75,11 @@ struct content template typename default_content_result::type content(Indexable const& b) { - return dispatch::content::type - >::apply(b); + return dispatch::content + < + Indexable, + typename tag::type + >::apply(b); } }}}} // namespace boost::geometry::index::detail diff --git a/include/boost/geometry/index/detail/algorithms/is_valid.hpp b/include/boost/geometry/index/detail/algorithms/is_valid.hpp index 0450f3b65..d85ac56d6 100644 --- a/include/boost/geometry/index/detail/algorithms/is_valid.hpp +++ b/include/boost/geometry/index/detail/algorithms/is_valid.hpp @@ -1,6 +1,6 @@ // Boost.Geometry Index // -// n-dimensional box's / point validity check +// n-dimensional Indexable validity check // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // @@ -11,20 +11,17 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace dispatch { -template +template ::value> struct is_valid_box { - BOOST_MPL_ASSERT_MSG( - (0 < dimension::value && - 0 < Dimension && - Dimension <= static_cast(dimension::value)), - INVALID_DIMENSION_PARAMETER, - (is_valid_box)); - static inline bool apply(Box const& b) { return is_valid_box::apply(b) && @@ -41,7 +38,8 @@ struct is_valid_box } }; -template +template ::type> struct is_valid { BOOST_MPL_ASSERT_MSG( @@ -64,7 +62,7 @@ struct is_valid { static inline bool apply(Indexable const& b) { - return dispatch::is_valid_box::value>::apply(b); + return dispatch::is_valid_box::apply(b); } }; @@ -82,7 +80,7 @@ struct is_valid template inline bool is_valid(Indexable const& b) { - return dispatch::is_valid::type>::apply(b); + return dispatch::is_valid::apply(b); } }}}} // namespace boost::geometry::index::detail diff --git a/include/boost/geometry/index/detail/algorithms/margin.hpp b/include/boost/geometry/index/detail/algorithms/margin.hpp index 8e2685ab3..d4876600a 100644 --- a/include/boost/geometry/index/detail/algorithms/margin.hpp +++ b/include/boost/geometry/index/detail/algorithms/margin.hpp @@ -2,7 +2,7 @@ // // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc... // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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 @@ -25,7 +25,9 @@ struct default_margin_result >::type type; }; -//template +//template ::value> //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); @@ -38,7 +40,7 @@ struct default_margin_result // } //}; // -//template +//template //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); @@ -49,7 +51,7 @@ struct default_margin_result // } //}; // -//template +//template //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); @@ -69,16 +71,16 @@ struct default_margin_result // } //}; // -//template +//template ::value> //struct margin_for_each_dimension //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); -// BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension::value); // // static inline typename default_margin_result::type apply(Box const& b) // { // return margin_for_each_dimension::apply(b) + -// margin_for_each_edge::value>::apply(b); +// margin_for_each_edge::apply(b); // } //}; // @@ -87,7 +89,7 @@ struct default_margin_result //{ // static inline typename default_margin_result::type apply(Box const& b) // { -// return margin_for_each_edge::value>::apply(b); +// return margin_for_each_edge::apply(b); // } //}; @@ -95,11 +97,11 @@ struct default_margin_result // Now it's sum of edges lengths // maybe margin_for_each_dimension should be used to get more or less hypersurface? -template +template ::value> struct simple_margin_for_each_dimension { BOOST_STATIC_ASSERT(0 < CurrentDimension); - //BOOST_STATIC_ASSERT(CurrentDimension <= dimension::value); static inline typename default_margin_result::type apply(Box const& b) { @@ -140,8 +142,8 @@ struct comparable_margin static inline result_type apply(Box const& g) { - //return detail::margin_for_each_dimension::value>::apply(g); - return detail::simple_margin_for_each_dimension::value>::apply(g); + //return detail::margin_for_each_dimension::apply(g); + return detail::simple_margin_for_each_dimension::apply(g); } }; @@ -159,7 +161,7 @@ typename default_margin_result::type comparable_margin(Geometry const& //template //typename default_margin_result::type margin(Box const& b) //{ -// return 2 * detail::margin_for_each_dimension::value>::apply(b); +// return 2 * detail::margin_for_each_dimension::apply(b); //} }}}} // namespace boost::geometry::index::detail diff --git a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp index bfe603001..b5ba1cf91 100644 --- a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp @@ -222,7 +222,6 @@ struct pick_seeds_impl typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename coordinate_type::type coordinate_type; typedef find_greatest_normalized_separation< Elements, Parameters, Translator, @@ -282,26 +281,24 @@ struct pick_seeds_impl // from void linear_pick_seeds(node_pointer const& n, unsigned int &seed1, unsigned int &seed2) const template -struct pick_seeds +inline void pick_seeds(Elements const& elements, + Parameters const& parameters, + Translator const& tr, + size_t & seed1, + size_t & seed2) { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename coordinate_type::type coordinate_type; - static const size_t dimension = geometry::dimension::value; - - typedef pick_seeds_impl impl; + typedef pick_seeds_impl + < + Elements, Parameters, Translator, + geometry::dimension::value + > impl; typedef typename impl::separation_type separation_type; - static inline void apply(Elements const& elements, - Parameters const& parameters, - Translator const& tr, - size_t & seed1, - size_t & seed2) - { - separation_type separation = 0; - pick_seeds_impl::apply(elements, parameters, tr, separation, seed1, seed2); - } + separation_type separation = 0; + impl::apply(elements, parameters, tr, separation, seed1, seed2); }; } // namespace linear @@ -337,18 +334,16 @@ struct redistribute_elements::type + container_type; + container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy) // calculate initial seeds size_t seed1 = 0; size_t seed2 = 0; - linear::pick_seeds< - elements_type, - parameters_type, - Translator - >::apply(elements_copy, parameters, translator, seed1, seed2); + linear::pick_seeds(elements_copy, parameters, translator, seed1, seed2); // prepare nodes' elements containers elements1.clear(); diff --git a/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp index 477d937db..43dff56bc 100644 --- a/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp +++ b/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp @@ -1,84 +1,63 @@ // Boost.Geometry Index // -// R-tree nodes dynamic visitor and nodes base type +// R-tree nodes weak visitor and nodes base type // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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_DYNAMIC_VISITOR_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { -// visitor forward declaration +// empty visitor template -struct dynamic_visitor; +struct weak_visitor {}; // node template -struct dynamic_node -{ - virtual ~dynamic_node() {} - virtual void apply_visitor(dynamic_visitor &) = 0; - virtual void apply_visitor(dynamic_visitor &) const = 0; -}; +struct weak_node {}; // nodes variants forward declarations template -struct dynamic_internal_node; +struct weak_internal_node; template -struct dynamic_leaf; - -// visitor - -template -struct dynamic_visitor -{ - typedef dynamic_internal_node internal_node; - typedef dynamic_leaf leaf; - - virtual ~dynamic_visitor() {} - - virtual void operator()(internal_node const&) = 0; - virtual void operator()(leaf const&) = 0; -}; - -template -struct dynamic_visitor -{ - typedef dynamic_internal_node internal_node; - typedef dynamic_leaf leaf; - - virtual ~dynamic_visitor() {} - - virtual void operator()(internal_node &) = 0; - virtual void operator()(leaf &) = 0; -}; +struct weak_leaf; // nodes conversion -template -inline Derived & get(dynamic_node & n) +template +inline Derived & get(weak_node & n) { - BOOST_GEOMETRY_INDEX_ASSERT(dynamic_cast(&n), "can't cast to a Derived type"); return static_cast(n); } // apply visitor -template -inline void apply_visitor(Visitor & v, Visitable & n) +template +inline void apply_visitor(Visitor & v, + raw_node & n, + bool is_internal_node) { BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr"); - n.apply_visitor(v); + if ( is_internal_node ) + { + typedef raw_internal_node internal_node; + v(get(n)); + } + else + { + typedef raw_leaf leaf; + v(get(n)); + } } }} // namespace detail::rtree diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index d788cdc0d..a632ece66 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -2,7 +2,7 @@ // // R-tree nodes // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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 @@ -17,14 +17,15 @@ #include #include #include +#include -#include -#include -#include +//#include +//#include +//#include -#include -#include -#include +#include +#include +#include #include @@ -84,29 +85,31 @@ struct destroy_element template struct destroy_elements { - 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 & elements, Allocators & allocators) + template + inline static void apply(Range & elements, Allocators & allocators) { - for ( size_t i = 0 ; i < elements.size() ; ++i ) - { - node_auto_ptr dummy(elements[i].second, allocators); - elements[i].second = 0; - } + apply(boost::begin(elements), boost::end(elements), allocators); } - inline static void apply(typename leaf::elements_type &, Allocators &) - {} - - inline static void apply(typename internal_node::elements_type::iterator first, - typename internal_node::elements_type::iterator last, - Allocators & 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); @@ -114,9 +117,9 @@ struct destroy_elements } } - inline static void apply(typename leaf::elements_type::iterator /*first*/, - typename leaf::elements_type::iterator /*last*/, - Allocators & /*allocators*/) + template + inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/, + boost::mpl::bool_ const& /*is_range_of_values*/) {} }; diff --git a/include/boost/geometry/index/detail/rtree/node/node_elements.hpp b/include/boost/geometry/index/detail/rtree/node/node_elements.hpp new file mode 100644 index 000000000..e3bfb701f --- /dev/null +++ b/include/boost/geometry/index/detail/rtree/node/node_elements.hpp @@ -0,0 +1,95 @@ +// Boost.Geometry Index +// +// R-tree node elements access +// +// 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_ELEMENTS_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP + +#include +#include +#include + +namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { + +// element's indexable type + +template +struct element_indexable_type +{ + typedef typename indexable_type::type type; +}; + +template +struct element_indexable_type< + rtree::ptr_pair, + Translator +> +{ + typedef First type; +}; + +// element's indexable getter + +template +typename result_type::type +element_indexable(Element const& el, Translator const& tr) +{ + return tr(el); +} + +template +First const& +element_indexable(rtree::ptr_pair const& el, Translator const& /*tr*/) +{ + return el.first; +} + +// nodes elements + +template +struct elements_type +{ + typedef typename Node::elements_type type; +}; + +template +inline typename elements_type::type & +elements(Node & n) +{ + return n.elements; +} + +template +inline typename elements_type::type const& +elements(Node const& n) +{ + return n.elements; +} + +// elements derived type + +template +struct container_from_elements_type +{ + typedef boost::container::vector type; +}; + +template +struct container_from_elements_type, NewValue> +{ + typedef detail::varray type; +}; + +}} // namespace detail::rtree + +}}} // namespace boost::geometry::index + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp similarity index 65% rename from include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp rename to include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp index 8cf7c9c0d..f13dd1036 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp @@ -1,15 +1,15 @@ // Boost.Geometry Index // -// R-tree nodes based on Boost.Variant, storing std::vectors +// R-tree nodes based on Boost.Variant, storing dynamic-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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_DEFAULT_VARIANT_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP namespace boost { namespace geometry { namespace index { @@ -18,19 +18,19 @@ namespace detail { namespace rtree { // nodes default types template -struct static_internal_node +struct variant_internal_node { - typedef typename Allocators::node_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - - typedef boost::container::vector< - rtree::ptr_pair, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + rtree::ptr_pair, + typename Allocators::node_allocator_type::template rebind + < + rtree::ptr_pair + >::other + > elements_type; template - inline static_internal_node(Al const& al) + inline variant_internal_node(Al const& al) : elements(al) {} @@ -38,19 +38,19 @@ struct static_internal_node }; template -struct static_leaf +struct variant_leaf { - typedef typename Allocators::node_allocator_type::template rebind< - Value - >::other elements_allocator_type; - - typedef boost::container::vector< - Value, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + Value, + typename Allocators::node_allocator_type::template rebind + < + Value + >::other + > elements_type; template - inline static_leaf(Al const& al) + inline variant_leaf(Al const& al) : elements(al) {} @@ -60,30 +60,30 @@ struct static_leaf // nodes traits template -struct node +struct node { typedef boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > type; }; template -struct internal_node +struct internal_node { - typedef static_internal_node type; + typedef variant_internal_node type; }; template -struct leaf +struct leaf { - typedef static_leaf type; + typedef variant_leaf type; }; // visitor traits template -struct visitor +struct visitor { typedef static_visitor<> type; }; @@ -91,9 +91,12 @@ struct visitor -class allocators +class allocators : public Allocator::template rebind< - typename node, node_s_mem_dynamic_tag>::type + typename node< + Value, Parameters, Box, + allocators, + node_variant_dynamic_tag>::type >::other { typedef typename Allocator::template rebind< @@ -112,15 +115,11 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other node_allocator_type; inline allocators() @@ -168,7 +167,7 @@ public: // create_node_variant template -struct create_static_node +struct create_variant_node { template static inline VariantPtr apply(AllocNode & alloc_node) @@ -193,7 +192,7 @@ struct create_static_node // destroy_node_variant template -struct destroy_static_node +struct destroy_variant_node { template static inline void apply(AllocNode & alloc_node, VariantPtr n) @@ -210,15 +209,15 @@ struct destroy_static_node template struct create_node< Allocators, - static_internal_node + variant_internal_node > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_internal_node + variant_internal_node >::apply(allocators.node_allocator()); } }; @@ -226,15 +225,15 @@ struct create_node< template struct create_node< Allocators, - static_leaf + variant_leaf > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_leaf + variant_leaf >::apply(allocators.node_allocator()); } }; @@ -244,13 +243,13 @@ struct create_node< template struct destroy_node< Allocators, - static_internal_node + variant_internal_node > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_static_node< - static_internal_node + destroy_variant_node< + variant_internal_node >::apply(allocators.node_allocator(), n); } }; @@ -258,13 +257,13 @@ struct destroy_node< template struct destroy_node< Allocators, - static_leaf + variant_leaf > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_static_node< - static_leaf + destroy_variant_node< + variant_leaf >::apply(allocators.node_allocator(), n); } }; @@ -273,4 +272,4 @@ struct destroy_node< }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/variant_static.hpp similarity index 62% rename from include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp rename to include/boost/geometry/index/detail/rtree/node/variant_static.hpp index 5df869c95..f6e9761b2 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_static.hpp @@ -2,14 +2,14 @@ // // R-tree nodes based on Boost.Variant, storing static-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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_DEFAULT_STATIC_VARIANT_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP namespace boost { namespace geometry { namespace index { @@ -18,37 +18,29 @@ namespace detail { namespace rtree { // nodes default types template -struct static_internal_node +struct variant_internal_node { - typedef typename Allocators::node_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - typedef detail::varray< rtree::ptr_pair, Parameters::max_elements + 1 > elements_type; template - inline static_internal_node(Alloc const&) {} + inline variant_internal_node(Alloc const&) {} elements_type elements; }; template -struct static_leaf +struct variant_leaf { - typedef typename Allocators::node_allocator_type::template rebind< - Value - >::other elements_allocator_type; - typedef detail::varray< Value, Parameters::max_elements + 1 > elements_type; template - inline static_leaf(Alloc const&) {} + inline variant_leaf(Alloc const&) {} elements_type elements; }; @@ -56,30 +48,30 @@ struct static_leaf // nodes traits template -struct node +struct node { typedef boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > type; }; template -struct internal_node +struct internal_node { - typedef static_internal_node type; + typedef variant_internal_node type; }; template -struct leaf +struct leaf { - typedef static_leaf type; + typedef variant_leaf type; }; // visitor traits template -struct visitor +struct visitor { typedef static_visitor<> type; }; @@ -87,9 +79,13 @@ struct visitor -struct allocators +struct allocators : public Allocator::template rebind< - typename node, node_s_mem_static_tag>::type + typename node< + Value, Parameters, Box, + allocators, + node_variant_static_tag + >::type >::other { typedef typename Allocator::template rebind< @@ -108,15 +104,11 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other node_allocator_type; inline allocators() @@ -166,15 +158,15 @@ public: template struct create_node< Allocators, - static_internal_node + variant_internal_node > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_internal_node + variant_internal_node >::apply(allocators.node_allocator()); } }; @@ -182,15 +174,15 @@ struct create_node< template struct create_node< Allocators, - static_leaf + variant_leaf > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_leaf + variant_leaf >::apply(allocators.node_allocator()); } }; @@ -199,4 +191,4 @@ struct create_node< }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/static_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/variant_visitor.hpp similarity index 64% rename from include/boost/geometry/index/detail/rtree/node/static_visitor.hpp rename to include/boost/geometry/index/detail/rtree/node/variant_visitor.hpp index 9b74b1e41..ffd67039d 100644 --- a/include/boost/geometry/index/detail/rtree/node/static_visitor.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_visitor.hpp @@ -2,14 +2,14 @@ // // R-tree nodes static visitor related code // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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_STATIC_VISITOR_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP #include @@ -20,18 +20,18 @@ namespace detail { namespace rtree { // nodes variants forward declarations template -struct static_internal_node; +struct variant_internal_node; template -struct static_leaf; +struct variant_leaf; // nodes conversion template inline V & get( boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > & v) { return boost::get(v); @@ -42,8 +42,8 @@ inline V & get( template inline void apply_visitor(Visitor & v, boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > & n) { boost::apply_visitor(v, n); @@ -52,8 +52,8 @@ inline void apply_visitor(Visitor & v, template inline void apply_visitor(Visitor & v, boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > const& n) { boost::apply_visitor(v, n); @@ -63,4 +63,4 @@ inline void apply_visitor(Visitor & v, }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp similarity index 54% rename from include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp rename to include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp index 1e3cd58d5..b828b35f4 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp @@ -1,167 +1,107 @@ // Boost.Geometry Index // -// R-tree nodes based on run-time polymorphism, storing std::vectors +// R-tree nodes based on static conversion, storing dynamic-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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_DEFAULT_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { -template -struct dynamic_internal_node - : public dynamic_node +template +struct weak_internal_node + : public weak_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - - typedef boost::container::vector< - rtree::ptr_pair, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + rtree::ptr_pair, + typename Allocators::internal_node_allocator_type::template rebind + < + rtree::ptr_pair + >::other + > elements_type; template - inline dynamic_internal_node(Al const& al) + inline weak_internal_node(Al const& al) : elements(al) {} - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } - elements_type elements; }; -template -struct dynamic_leaf - : public dynamic_node +template +struct weak_leaf + : public weak_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - Value - >::other elements_allocator_type; - - typedef boost::container::vector< - Value, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + Value, + typename Allocators::leaf_allocator_type::template rebind + < + Value + >::other + > elements_type; template - inline dynamic_leaf(Al const& al) + inline weak_leaf(Al const& al) : elements(al) {} - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } - elements_type elements; }; // nodes traits template -struct node +struct node { - typedef dynamic_node type; + typedef weak_node type; }; template -struct internal_node +struct internal_node { - typedef dynamic_internal_node type; + typedef weak_internal_node type; }; template -struct leaf +struct leaf { - typedef dynamic_leaf type; + typedef weak_leaf type; }; // visitor traits template -struct visitor +struct visitor { - typedef dynamic_visitor type; -}; - -// element's indexable type - -template -struct element_indexable_type -{ - typedef typename indexable_type::type type; -}; - -template -struct element_indexable_type< - rtree::ptr_pair, - Translator -> -{ - typedef First type; -}; - -// element's indexable getter - -template -typename result_type::type -element_indexable(Element const& el, Translator const& tr) -{ - return tr(el); -} - -template -First const& -element_indexable(rtree::ptr_pair const& el, Translator const& /*tr*/) -{ - return el.first; -} - -// nodes elements - -template -struct elements_type -{ - typedef typename Node::elements_type type; -}; - -template -inline typename elements_type::type & -elements(Node & n) -{ - return n.elements; -} - -template -inline typename elements_type::type const& -elements(Node const& n) -{ - return n.elements; -} - -// elements derived type -template -struct container_from_elements_type -{ - typedef boost::container::vector type; + typedef weak_visitor type; }; // allocators template -class allocators +class allocators : public Allocator::template rebind< - typename internal_node, node_d_mem_dynamic_tag>::type + typename internal_node< + Value, Parameters, Box, + allocators, + node_weak_dynamic_tag + >::type >::other , public Allocator::template rebind< - typename leaf, node_d_mem_dynamic_tag>::type + typename leaf< + Value, Parameters, Box, + allocators, + node_weak_dynamic_tag + >::type >::other { typedef typename Allocator::template rebind< @@ -180,19 +120,15 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename internal_node::type + typename internal_node::type >::other internal_node_allocator_type; typedef typename Allocator::template rebind< - typename leaf::type + typename leaf::type >::other leaf_allocator_type; inline allocators() @@ -248,7 +184,7 @@ public: // create_node_impl template -struct create_dynamic_node +struct create_weak_node { template static inline BaseNodePtr apply(AllocNode & alloc_node) @@ -273,7 +209,7 @@ struct create_dynamic_node // destroy_node_impl template -struct destroy_dynamic_node +struct destroy_weak_node { template static inline void apply(AllocNode & alloc_node, BaseNodePtr n) @@ -292,15 +228,15 @@ struct destroy_dynamic_node template struct create_node< Allocators, - dynamic_internal_node + weak_internal_node > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_dynamic_node< + return create_weak_node< typename Allocators::node_pointer, - dynamic_internal_node + weak_internal_node >::apply(allocators.internal_node_allocator()); } }; @@ -308,15 +244,15 @@ struct create_node< template struct create_node< Allocators, - dynamic_leaf + weak_leaf > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_dynamic_node< + return create_weak_node< typename Allocators::node_pointer, - dynamic_leaf + weak_leaf >::apply(allocators.leaf_allocator()); } }; @@ -326,13 +262,13 @@ struct create_node< template struct destroy_node< Allocators, - dynamic_internal_node + weak_internal_node > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_dynamic_node< - dynamic_internal_node + destroy_weak_node< + weak_internal_node >::apply(allocators.internal_node_allocator(), n); } }; @@ -340,13 +276,13 @@ struct destroy_node< template struct destroy_node< Allocators, - dynamic_leaf + weak_leaf > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_dynamic_node< - dynamic_leaf + destroy_weak_node< + weak_leaf >::apply(allocators.leaf_allocator(), n); } }; @@ -355,4 +291,4 @@ struct destroy_node< }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/weak_static.hpp similarity index 57% rename from include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp rename to include/boost/geometry/index/detail/rtree/node/weak_static.hpp index 184c48e44..632e35678 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/weak_static.hpp @@ -1,60 +1,46 @@ // Boost.Geometry Index // -// R-tree nodes based on runtime-polymorphism, storing static-size containers +// R-tree nodes based on static conversion, storing static-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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_DEFAULT_STATIC_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { template -struct dynamic_internal_node - : public dynamic_node +struct weak_internal_node + : public weak_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - typedef detail::varray< rtree::ptr_pair, Parameters::max_elements + 1 > elements_type; template - inline dynamic_internal_node(Alloc const&) {} - - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + inline weak_internal_node(Alloc const&) {} elements_type elements; }; template -struct dynamic_leaf - : public dynamic_node +struct weak_leaf + : public weak_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - Value - >::other elements_allocator_type; - typedef detail::varray< Value, Parameters::max_elements + 1 > elements_type; template - inline dynamic_leaf(Alloc const&) {} - - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + inline weak_leaf(Alloc const&) {} elements_type elements; }; @@ -62,52 +48,45 @@ struct dynamic_leaf // nodes traits template -struct node +struct node { - typedef dynamic_node type; + typedef weak_node type; }; template -struct internal_node +struct internal_node { - typedef dynamic_internal_node type; + typedef weak_internal_node type; }; template -struct leaf +struct leaf { - typedef dynamic_leaf type; + typedef weak_leaf type; }; template -struct visitor +struct visitor { - typedef dynamic_visitor type; -}; - -// elements derived type -template -struct container_from_elements_type, NewValue> -{ - typedef detail::varray type; + typedef weak_visitor type; }; // allocators template -class allocators +class allocators : public Allocator::template rebind< typename internal_node< Value, Parameters, Box, - allocators, - node_d_mem_static_tag + allocators, + node_weak_static_tag >::type >::other , public Allocator::template rebind< typename leaf< Value, Parameters, Box, - allocators, - node_d_mem_static_tag + allocators, + node_weak_static_tag >::type >::other { @@ -127,19 +106,15 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename internal_node::type + typename internal_node::type >::other internal_node_allocator_type; typedef typename Allocator::template rebind< - typename leaf::type + typename leaf::type >::other leaf_allocator_type; inline allocators() @@ -196,4 +171,4 @@ public: }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp new file mode 100644 index 000000000..08d84778e --- /dev/null +++ b/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp @@ -0,0 +1,67 @@ +// Boost.Geometry Index +// +// R-tree nodes weak visitor and nodes base type +// +// 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_WEAK_VISITOR_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP + +namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { + +// empty visitor +template +struct weak_visitor {}; + +// node + +template +struct weak_node {}; + +// nodes variants forward declarations + +template +struct weak_internal_node; + +template +struct weak_leaf; + +// nodes conversion + +template +inline Derived & get(weak_node & n) +{ + return static_cast(n); +} + +// apply visitor + +template +inline void apply_visitor(Visitor & v, + weak_node & n, + bool is_internal_node) +{ + BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr"); + if ( is_internal_node ) + { + typedef weak_internal_node internal_node; + v(get(n)); + } + else + { + typedef weak_leaf leaf; + v(get(n)); + } +} + +}} // namespace detail::rtree + +}}} // namespace boost::geometry::index + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP diff --git a/include/boost/geometry/index/detail/rtree/options.hpp b/include/boost/geometry/index/detail/rtree/options.hpp index b7947402c..ff772834d 100644 --- a/include/boost/geometry/index/detail/rtree/options.hpp +++ b/include/boost/geometry/index/detail/rtree/options.hpp @@ -2,7 +2,7 @@ // // R-tree options, algorithms, parameters // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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 @@ -35,10 +35,10 @@ struct quadratic_tag {}; struct rstar_tag {}; // NodeTag -struct node_d_mem_dynamic_tag {}; -struct node_d_mem_static_tag {}; -struct node_s_mem_dynamic_tag {}; -struct node_s_mem_static_tag {}; +struct node_variant_dynamic_tag {}; +struct node_variant_static_tag {}; +//struct node_weak_dynamic_tag {}; +//struct node_weak_static_tag {}; template struct options @@ -66,7 +66,7 @@ struct options_type< index::linear > choose_by_content_diff_tag, split_default_tag, linear_tag, - node_s_mem_static_tag + node_variant_static_tag > type; }; @@ -79,7 +79,7 @@ struct options_type< index::quadratic > choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_s_mem_static_tag + node_variant_static_tag > type; }; @@ -92,7 +92,7 @@ struct options_type< index::rstar type; }; @@ -105,7 +105,7 @@ struct options_type< index::rstar type; //}; @@ -118,7 +118,7 @@ struct options_type< index::dynamic_linear > choose_by_content_diff_tag, split_default_tag, linear_tag, - node_s_mem_dynamic_tag + node_variant_dynamic_tag > type; }; @@ -131,7 +131,7 @@ struct options_type< index::dynamic_quadratic > choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_s_mem_dynamic_tag + node_variant_dynamic_tag > type; }; @@ -144,7 +144,7 @@ struct options_type< index::dynamic_rstar > choose_by_overlap_diff_tag, split_default_tag, rstar_tag, - node_s_mem_dynamic_tag + node_variant_dynamic_tag > type; }; diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index e3ac16aef..46bf357fc 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -125,11 +125,11 @@ class pack typedef rtree::node_auto_ptr node_auto_ptr; typedef typename Allocators::size_type size_type; - typedef typename traits::point_type::type point_type; - typedef typename traits::coordinate_type::type coordinate_type; + typedef typename geometry::point_type::type point_type; + typedef typename geometry::coordinate_type::type coordinate_type; typedef typename detail::default_content_result::type content_type; typedef typename Options::parameters_type parameters_type; - static const std::size_t dimension = traits::dimension::value; + static const std::size_t dimension = geometry::dimension::value; typedef typename rtree::container_from_elements_type< typename rtree::elements_type::type, diff --git a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp index c7e948a05..634d87986 100644 --- a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp @@ -28,60 +28,56 @@ namespace detail { namespace rtree { namespace quadratic { -template -struct pick_seeds +template +inline void pick_seeds(Elements const& elements, + Parameters const& parameters, + Translator const& tr, + size_t & seed1, + size_t & seed2) { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename coordinate_type::type coordinate_type; typedef Box box_type; typedef typename index::detail::default_content_result::type content_type; typedef index::detail::bounded_view bounded_indexable_view; - static inline void apply(Elements const& elements, - Parameters const& parameters, - Translator const& tr, - size_t & seed1, - size_t & seed2) + const size_t elements_count = parameters.get_max_elements() + 1; + BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements"); + BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements"); + + content_type greatest_free_content = 0; + seed1 = 0; + seed2 = 1; + + for ( size_t i = 0 ; i < elements_count - 1 ; ++i ) { - const size_t elements_count = parameters.get_max_elements() + 1; - BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements"); - BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements"); - - content_type greatest_free_content = 0; - seed1 = 0; - seed2 = 1; - - for ( size_t i = 0 ; i < elements_count - 1 ; ++i ) + for ( size_t j = i + 1 ; j < elements_count ; ++j ) { - for ( size_t j = i + 1 ; j < elements_count ; ++j ) - { - indexable_type const& ind1 = rtree::element_indexable(elements[i], tr); - indexable_type const& ind2 = rtree::element_indexable(elements[j], tr); + indexable_type const& ind1 = rtree::element_indexable(elements[i], tr); + indexable_type const& ind2 = rtree::element_indexable(elements[j], tr); - box_type enlarged_box; - //geometry::convert(ind1, enlarged_box); - detail::bounds(ind1, enlarged_box); - geometry::expand(enlarged_box, ind2); + box_type enlarged_box; + //geometry::convert(ind1, enlarged_box); + detail::bounds(ind1, enlarged_box); + geometry::expand(enlarged_box, ind2); - bounded_indexable_view bounded_ind1(ind1); - bounded_indexable_view bounded_ind2(ind2); - content_type free_content = ( index::detail::content(enlarged_box) - - index::detail::content(bounded_ind1) ) - - index::detail::content(bounded_ind2); + bounded_indexable_view bounded_ind1(ind1); + bounded_indexable_view bounded_ind2(ind2); + content_type free_content = ( index::detail::content(enlarged_box) + - index::detail::content(bounded_ind1) ) + - index::detail::content(bounded_ind2); - if ( greatest_free_content < free_content ) - { - greatest_free_content = free_content; - seed1 = i; - seed2 = j; - } + if ( greatest_free_content < free_content ) + { + greatest_free_content = free_content; + seed1 = i; + seed2 = j; } } - - ::boost::ignore_unused_variable_warning(parameters); } -}; + + ::boost::ignore_unused_variable_warning(parameters); +} } // namespace quadratic @@ -114,20 +110,17 @@ struct redistribute_elements::type + container_type; + container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy) + container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy) // calculate initial seeds size_t seed1 = 0; size_t seed2 = 0; - quadratic::pick_seeds< - elements_type, - parameters_type, - Translator, - Box - >::apply(elements_copy, parameters, translator, seed1, seed2); + quadratic::pick_seeds(elements_copy, parameters, translator, seed1, seed2); // prepare nodes' elements containers elements1.clear(); @@ -170,7 +163,7 @@ struct redistribute_elements typedef typename Options::parameters_type parameters_type; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; inline level_insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Value const& v, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level) + size_type relative_level) : base(root, leafs_level, v, parameters, translator, allocators, relative_level) {} @@ -453,15 +457,16 @@ class insert::type leaf; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; public: inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0) + size_type relative_level = 0) : m_root(root), m_leafs_level(leafs_level), m_element(element) , m_parameters(parameters), m_translator(translator) , m_relative_level(relative_level), m_allocators(allocators) @@ -554,13 +559,13 @@ private: } node_pointer & m_root; - size_t & m_leafs_level; + size_type & m_leafs_level; Element const& m_element; parameters_type const& m_parameters; Translator const& m_translator; - size_t m_relative_level; + size_type m_relative_level; Allocators & m_allocators; }; diff --git a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp index 21bdc986d..8f270537f 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp @@ -89,13 +89,13 @@ private: Translator const& m_tr; }; -template +template struct choose_split_axis_and_index_for_corner { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_index, margin_type & sum_of_margins, @@ -160,19 +160,19 @@ struct choose_split_axis_and_index_for_corner } }; -//template +//template //struct choose_split_axis_and_index_for_axis //{ // BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag)); //}; -template +template struct choose_split_axis_and_index_for_axis { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_corner, size_t & choosen_index, @@ -187,20 +187,20 @@ struct choose_split_axis_and_index_for_axis content_type ovl1 = (std::numeric_limits::max)(); content_type con1 = (std::numeric_limits::max)(); - choose_split_axis_and_index_for_corner:: - apply(elements, index1, - som1, ovl1, con1, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index_for_corner + ::apply(elements, index1, + som1, ovl1, con1, + parameters, translator); // MAY THROW, STRONG size_t index2 = 0; margin_type som2 = 0; content_type ovl2 = (std::numeric_limits::max)(); content_type con2 = (std::numeric_limits::max)(); - choose_split_axis_and_index_for_corner:: - apply(elements, index2, - som2, ovl2, con2, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index_for_corner + ::apply(elements, index2, + som2, ovl2, con2, + parameters, translator); // MAY THROW, STRONG sum_of_margins = som1 + som2; @@ -221,13 +221,13 @@ struct choose_split_axis_and_index_for_axis } }; -template -struct choose_split_axis_and_index_for_axis +template +struct choose_split_axis_and_index_for_axis { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_corner, size_t & choosen_index, @@ -237,16 +237,16 @@ struct choose_split_axis_and_index_for_axis:: - apply(elements, choosen_index, - sum_of_margins, smallest_overlap, smallest_content, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index_for_corner + ::apply(elements, choosen_index, + sum_of_margins, smallest_overlap, smallest_content, + parameters, translator); // MAY THROW, STRONG choosen_corner = min_corner; } }; -template +template struct choose_split_axis_and_index { BOOST_STATIC_ASSERT(0 < Dimension); @@ -254,7 +254,7 @@ struct choose_split_axis_and_index typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_axis, size_t & choosen_corner, @@ -267,10 +267,10 @@ struct choose_split_axis_and_index { typedef typename rtree::element_indexable_type::type element_indexable_type; - choose_split_axis_and_index:: - apply(elements, choosen_axis, choosen_corner, choosen_index, - smallest_sum_of_margins, smallest_overlap, smallest_content, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index + ::apply(elements, choosen_axis, choosen_corner, choosen_index, + smallest_sum_of_margins, smallest_overlap, smallest_content, + parameters, translator); // MAY THROW, STRONG margin_type sum_of_margins = 0; @@ -281,7 +281,6 @@ struct choose_split_axis_and_index content_type content_val = (std::numeric_limits::max)(); choose_split_axis_and_index_for_axis< - Parameters, Box, Dimension - 1, typename tag::type @@ -299,13 +298,13 @@ struct choose_split_axis_and_index } }; -template -struct choose_split_axis_and_index +template +struct choose_split_axis_and_index { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_axis, size_t & choosen_corner, @@ -321,7 +320,6 @@ struct choose_split_axis_and_index choosen_axis = 0; choose_split_axis_and_index_for_axis< - Parameters, Box, 0, typename tag::type @@ -391,14 +389,17 @@ struct redistribute_elements::type elements_type; + typedef typename elements_type::value_type element_type; elements_type & elements1 = rtree::elements(n); elements_type & elements2 = rtree::elements(second_node); - // copy original elements - // TODO: use container_from_elements_type for std::allocator - elements_type elements_copy(elements1); // MAY THROW, STRONG - elements_type elements_backup(elements1); // MAY THROW, STRONG + // copy original elements - use in-memory storage (std::allocator) + // TODO: move if noexcept + typedef typename rtree::container_from_elements_type::type + container_type; + container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG + container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG size_t split_axis = 0; size_t split_corner = 0; @@ -412,14 +413,11 @@ struct redistribute_elements::apply(elements_copy, - split_axis, split_corner, split_index, - smallest_sum_of_margins, smallest_overlap, smallest_content, - parameters, translator); // MAY THROW, STRONG + rstar::choose_split_axis_and_index + ::apply(elements_copy, + split_axis, split_corner, split_index, + smallest_sum_of_margins, smallest_overlap, smallest_content, + parameters, translator); // MAY THROW, STRONG // TODO: awulkiew - get rid of following static_casts? BOOST_GEOMETRY_INDEX_ASSERT(split_axis < dimension, "unexpected value"); diff --git a/include/boost/geometry/index/detail/rtree/visitors/count.hpp b/include/boost/geometry/index/detail/rtree/visitors/count.hpp index f521944a4..7efd5b702 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/count.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/count.hpp @@ -15,7 +15,37 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template +template +struct count_helper +{ + template + static inline typename Translator::result_type indexable(Indexable const& i, Translator const&) + { + return i; + } + template + static inline bool equals(Indexable const& i, Value const& v, Translator const& tr) + { + return geometry::equals(i, tr(v)); + } +}; + +template +struct count_helper +{ + template + static inline typename Translator::result_type indexable(Value const& v, Translator const& tr) + { + return tr(v); + } + template + static inline bool equals(Value const& v1, Value const& v2, Translator const& tr) + { + return tr.equals(v1, v2); + } +}; + +template struct count : public rtree::visitor::type { @@ -23,8 +53,10 @@ struct count typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; - inline count(Indexable const& i, Translator const& t) - : indexable(i), tr(t), found_count(0) + typedef count_helper count_help; + + inline count(ValueOrIndexable const& vori, Translator const& t) + : value_or_indexable(vori), tr(t), found_count(0) {} inline void operator()(internal_node const& n) @@ -37,7 +69,8 @@ struct count it != elements.end(); ++it) { if ( geometry::covered_by( - return_ref_or_bounds(indexable), + return_ref_or_bounds( + count_help::indexable(value_or_indexable, tr)), it->first) ) { rtree::apply_visitor(*this, *it->second); @@ -55,66 +88,14 @@ struct count it != elements.end(); ++it) { // if value meets predicates - if ( geometry::equals(indexable, tr(*it)) ) + if ( count_help::equals(value_or_indexable, *it, tr) ) { ++found_count; } } } - Indexable const& indexable; - Translator const& tr; - typename Allocators::size_type found_count; -}; - -template -struct count - : public rtree::visitor::type -{ - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; - - inline count(Value const& v, Translator const& t) - : value(v), tr(t), found_count(0) - {} - - inline void operator()(internal_node const& n) - { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); - - // traverse nodes meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) - { - if ( geometry::covered_by( - return_ref_or_bounds(tr(value)), - it->first) ) - { - rtree::apply_visitor(*this, *it->second); - } - } - } - - inline void operator()(leaf const& n) - { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); - - // get all values meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) - { - // if value meets predicates - if ( tr.equals(value, *it) ) - { - ++found_count; - } - } - } - - Value const& value; + ValueOrIndexable const& value_or_indexable; Translator const& tr; typename Allocators::size_type found_count; }; diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index a5c16db8a..388b3193f 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -178,17 +178,20 @@ public: namespace visitors { namespace detail { -template +template struct insert_traverse_data { typedef typename rtree::elements_type::type elements_type; typedef typename elements_type::value_type element_type; + typedef typename elements_type::size_type elements_size_type; + typedef SizeType size_type; insert_traverse_data() : parent(0), current_child_index(0), current_level(0) {} - void move_to_next_level(InternalNodePtr new_parent, size_t new_child_index) + void move_to_next_level(InternalNodePtr new_parent, + elements_size_type new_child_index) { parent = new_parent; current_child_index = new_child_index; @@ -213,8 +216,8 @@ struct insert_traverse_data } InternalNodePtr parent; - size_t current_child_index; - size_t current_level; + elements_size_type current_child_index; + size_type current_level; }; // Default insert visitor @@ -231,17 +234,18 @@ protected: typedef rtree::node_auto_ptr node_auto_ptr; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; //typedef typename Allocators::internal_node_pointer internal_node_pointer; typedef internal_node * internal_node_pointer; inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0 + size_type relative_level = 0 ) : m_element(element) , m_parameters(parameters) @@ -298,7 +302,8 @@ protected: inline void traverse_apply_visitor(Visitor & visitor, internal_node &n, size_t choosen_node_index) { // save previous traverse inputs and set new ones - insert_traverse_data backup_traverse_data = m_traverse_data; + insert_traverse_data + backup_traverse_data = m_traverse_data; // calculate new traverse inputs m_traverse_data.move_to_next_level(&n, choosen_node_index); @@ -380,14 +385,14 @@ protected: Element const& m_element; parameters_type const& m_parameters; Translator const& m_translator; - const size_t m_relative_level; - const size_t m_level; + size_type const m_relative_level; + size_type const m_level; node_pointer & m_root_node; - size_t & m_leafs_level; + size_type & m_leafs_level; // traversing input parameters - insert_traverse_data m_traverse_data; + insert_traverse_data m_traverse_data; Allocators & m_allocators; }; @@ -414,14 +419,15 @@ public: typedef typename Options::parameters_type parameters_type; typedef typename base::node_pointer node_pointer; + typedef typename base::size_type size_type; inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0 + size_type relative_level = 0 ) : base(root, leafs_level, element, parameters, translator, allocators, relative_level) {} @@ -478,14 +484,15 @@ public: typedef typename Options::parameters_type parameters_type; typedef typename base::node_pointer node_pointer; + typedef typename base::size_type size_type; inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Value const& value, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0 + size_type relative_level = 0 ) : base(root, leafs_level, value, parameters, translator, allocators, relative_level) {} diff --git a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp index 8e6255346..d4890a368 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp @@ -32,13 +32,16 @@ class remove typedef rtree::node_auto_ptr node_auto_ptr; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; + + typedef typename rtree::elements_type::type::size_type internal_size_type; //typedef typename Allocators::internal_node_pointer internal_node_pointer; typedef internal_node * internal_node_pointer; public: inline remove(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Value const& value, parameters_type const& parameters, Translator const& translator, @@ -65,7 +68,7 @@ public: children_type & children = rtree::elements(n); // traverse children which boxes intersects value's box - size_t child_node_index = 0; + internal_size_type child_node_index = 0; for ( ; child_node_index < children.size() ; ++child_node_index ) { if ( geometry::covered_by( @@ -91,7 +94,7 @@ public: if ( m_is_underflow ) { element_iterator underfl_el_it = elements.begin() + child_node_index; - size_t relative_level = m_leafs_level - m_current_level; + size_type relative_level = m_leafs_level - m_current_level; // move node to the container - store node's relative level as well and return new underflow state m_is_underflow = store_underflowed_node(elements, underfl_el_it, relative_level); // MAY THROW (E: alloc, copy) @@ -170,14 +173,14 @@ public: private: - typedef std::vector< std::pair > UnderflowNodes; + typedef std::vector< std::pair > UnderflowNodes; - void traverse_apply_visitor(internal_node &n, size_t choosen_node_index) + void traverse_apply_visitor(internal_node &n, internal_size_type choosen_node_index) { // save previous traverse inputs and set new ones internal_node_pointer parent_bckup = m_parent; - size_t current_child_index_bckup = m_current_child_index; - size_t current_level_bckup = m_current_level; + internal_size_type current_child_index_bckup = m_current_child_index; + size_type current_level_bckup = m_current_level; m_parent = &n; m_current_child_index = choosen_node_index; @@ -195,7 +198,7 @@ private: bool store_underflowed_node( typename rtree::elements_type::type & elements, typename rtree::elements_type::type::iterator underfl_el_it, - size_t relative_level) + size_type relative_level) { // move node to the container - store node's relative level as well m_underflowed_nodes.push_back(std::make_pair(relative_level, underfl_el_it->second)); // MAY THROW (E: alloc, copy) @@ -263,7 +266,7 @@ private: } template - void reinsert_node_elements(Node &n, size_t node_relative_level) + void reinsert_node_elements(Node &n, size_type node_relative_level) { typedef typename rtree::elements_type::type elements_type; elements_type & elements = rtree::elements(n); @@ -302,15 +305,15 @@ private: Allocators & m_allocators; node_pointer & m_root_node; - size_t & m_leafs_level; + size_type & m_leafs_level; bool m_is_value_removed; UnderflowNodes m_underflowed_nodes; // traversing input parameters internal_node_pointer m_parent; - size_t m_current_child_index; - size_t m_current_level; + internal_size_type m_current_child_index; + size_type m_current_level; // traversing output parameters bool m_is_underflow; diff --git a/include/boost/geometry/index/detail/serialization.hpp b/include/boost/geometry/index/detail/serialization.hpp index fd5e371d4..34036e390 100644 --- a/include/boost/geometry/index/detail/serialization.hpp +++ b/include/boost/geometry/index/detail/serialization.hpp @@ -1,6 +1,6 @@ // Boost.Geometry Index // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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 @@ -225,7 +225,7 @@ template void serialize(Archive &, boost::geometry::index::dynami // TODO - move to index/detail/serialization.hpp or maybe geometry/serialization.hpp namespace boost { namespace geometry { namespace index { namespace detail { -template ::value> +template ::value> struct serialize_point { template @@ -239,7 +239,7 @@ struct serialize_point template static inline void load(Archive & ar, P & p, unsigned int version) { - typename traits::coordinate_type

::type c; + typename geometry::coordinate_type

::type c; ar >> boost::serialization::make_nvp("c", c); set(p, c); serialize_point::load(ar, p, version); diff --git a/include/boost/geometry/index/indexable.hpp b/include/boost/geometry/index/indexable.hpp index 5270ca22e..391b544f3 100644 --- a/include/boost/geometry/index/indexable.hpp +++ b/include/boost/geometry/index/indexable.hpp @@ -29,7 +29,11 @@ template struct is_indexable { static const bool value = - is_indexable_impl::type>::value; + is_indexable_impl + < + Indexable, + typename geometry::tag::type + >::value; }; /*! diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 09f07ffe7..503f47b89 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -590,9 +590,9 @@ public: } /*! - \brief Insert a range of values to the index. + \brief Insert a value created using convertible object or a range of values to the index. - \param rng The range of values. + \param conv_or_rng An object of type convertible to value_type or a range of values. \par Throws \li If Value copy constructor or copy assignment throws. @@ -604,17 +604,15 @@ public: elements must not be inserted or removed. Other operations are allowed however some of them may return invalid data. */ - template - inline void insert(Range const& rng) + template + inline void insert(ConvertibleOrRange const& conv_or_rng) { - BOOST_MPL_ASSERT_MSG((detail::is_range::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range)); + typedef boost::mpl::bool_ + < + boost::is_convertible::value + > is_conv_t; - if ( !m_members.root ) - this->raw_create(); - - typedef typename boost::range_const_iterator::type It; - for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) - this->raw_insert(*it); + this->insert_dispatch(conv_or_rng, is_conv_t()); } /*! @@ -675,13 +673,13 @@ public: } /*! - \brief Remove a range of values from the container. + \brief Remove value corresponding to an object convertible to it or a range of values from the container. In contrast to the \c std::set or std::map erase() method it removes values equal to these passed as a range. Furthermore, this method removes only one value for each one passed in the range, not all equal values. - \param rng The range of values. + \param conv_or_rng The object of type convertible to value_type or a range of values. \return The number of removed values. @@ -695,16 +693,15 @@ public: elements must not be inserted or removed. Other operations are allowed however some of them may return invalid data. */ - template - inline size_type remove(Range const& rng) + template + inline size_type remove(ConvertibleOrRange const& conv_or_rng) { - BOOST_MPL_ASSERT_MSG((detail::is_range::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range)); + typedef boost::mpl::bool_ + < + boost::is_convertible::value + > is_conv_t; - size_type result = 0; - typedef typename boost::range_const_iterator::type It; - for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) - result += this->raw_remove(*it); - return result; + return this->remove_dispatch(conv_or_rng, is_conv_t()); } /*! @@ -1091,10 +1088,35 @@ public: template size_type count(ValueOrIndexable const& vori) const { + enum { as_val = 0, as_ind, dont_know }; + typedef boost::mpl::int_ + < + boost::is_same::value ? + as_val : + boost::is_same::value ? + as_ind : + boost::is_convertible::value ? + as_ind : + boost::is_convertible::value ? + as_val : + dont_know + > variant; + + BOOST_MPL_ASSERT_MSG((variant::value != dont_know), + PASSED_OBJECT_NOT_CONVERTIBLE_TO_VALUE_NOR_INDEXABLE_TYPE, + (ValueOrIndexable)); + + typedef typename boost::mpl::if_c + < + variant::value == as_val, + value_type, + indexable_type + >::type value_or_indexable; + if ( !m_members.root ) return 0; - detail::rtree::visitors::count + detail::rtree::visitors::count count_v(vori, m_members.translator()); detail::rtree::apply_visitor(count_v, *m_members.root); @@ -1348,6 +1370,86 @@ private: dst.m_members.leafs_level = src.m_members.leafs_level; } + /*! + \brief Insert a value corresponding to convertible object into the index. + + \param val_conv The object convertible to value. + + \par Exception-safety + basic + */ + template + inline void insert_dispatch(ValueConvertible const& val_conv, + boost::mpl::bool_ const& /*is_convertible*/) + { + if ( !m_members.root ) + this->raw_create(); + + this->raw_insert(val_conv); + } + + /*! + \brief Insert a range of values into the index. + + \param rng The range of values. + + \par Exception-safety + basic + */ + template + inline void insert_dispatch(Range const& rng, + boost::mpl::bool_ const& /*is_convertible*/) + { + BOOST_MPL_ASSERT_MSG((detail::is_range::value), + PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE, + (Range)); + + if ( !m_members.root ) + this->raw_create(); + + typedef typename boost::range_const_iterator::type It; + for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) + this->raw_insert(*it); + } + + /*! + \brief Remove a value corresponding to convertible object from the index. + + \param val_conv The object convertible to value. + + \par Exception-safety + basic + */ + template + inline size_type remove_dispatch(ValueConvertible const& val_conv, + boost::mpl::bool_ const& /*is_convertible*/) + { + return this->raw_remove(val_conv); + } + + /*! + \brief Remove a range of values from the index. + + \param rng The range of values which will be removed from the container. + + \par Exception-safety + basic + */ + template + inline size_type remove_dispatch(Range const& rng, + boost::mpl::bool_ const& /*is_convertible*/) + { + BOOST_MPL_ASSERT_MSG((detail::is_range::value), + PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE, + (Range)); + + size_type result = 0; + typedef typename boost::range_const_iterator::type It; + for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) + result += this->raw_remove(*it); + return result; + } + /*! \brief Return values meeting predicates. @@ -1456,7 +1558,8 @@ It calls rtree::insert(value_type const&). \param v The value which will be stored in the index. */ template -inline void insert(rtree & tree, Value const& v) +inline void insert(rtree & tree, + Value const& v) { tree.insert(v); } @@ -1472,26 +1575,30 @@ It calls rtree::insert(Iterator, Iterator). \param first The beginning of the range of values. \param last The end of the range of values. */ -template -inline void insert(rtree & tree, Iterator first, Iterator last) +template +inline void insert(rtree & tree, + Iterator first, Iterator last) { tree.insert(first, last); } /*! -\brief Insert a range of values to the index. +\brief Insert a value created using convertible object or a range of values to the index. -It calls rtree::insert(Range const&). +It calls rtree::insert(ConvertibleOrRange const&). \ingroup rtree_functions -\param tree The spatial index. -\param rng The range of values. +\param tree The spatial index. +\param conv_or_rng The object of type convertible to value_type or a range of values. */ -template -inline void insert(rtree & tree, Range const& rng) +template +inline void insert(rtree & tree, + ConvertibleOrRange const& conv_or_rng) { - tree.insert(rng); + tree.insert(conv_or_rng); } /*! @@ -1511,7 +1618,8 @@ It calls rtree::remove(value_type const&). */ template inline typename rtree::size_type -remove(rtree & tree, Value const& v) +remove(rtree & tree, + Value const& v) { return tree.remove(v); } @@ -1534,34 +1642,39 @@ It calls rtree::remove(Iterator, Iterator). \return The number of removed values. */ -template +template inline typename rtree::size_type -remove(rtree & tree, Iterator first, Iterator last) +remove(rtree & tree, + Iterator first, Iterator last) { return tree.remove(first, last); } /*! -\brief Remove a range of values from the container. +\brief Remove a value corresponding to an object convertible to it or a range of values from the container. -Remove a range of values from the container. In contrast to the \c std::set or std::map erase() method +Remove a value corresponding to an object convertible to it or a range of values from the container. +In contrast to the \c std::set or std::map erase() method it removes values equal to these passed as a range. Furthermore this method removes only one value for each one passed in the range, not all equal values. -It calls rtree::remove(Range const&). +It calls rtree::remove(ConvertibleOrRange const&). \ingroup rtree_functions -\param tree The spatial index. -\param rng The range of values. +\param tree The spatial index. +\param conv_or_rng The object of type convertible to value_type or the range of values. \return The number of removed values. */ -template +template inline typename rtree::size_type -remove(rtree & tree, Range const& rng) +remove(rtree & tree, + ConvertibleOrRange const& conv_or_rng) { - return tree.remove(rng); + return tree.remove(conv_or_rng); } /*! diff --git a/include/boost/geometry/iterators/closing_iterator.hpp b/include/boost/geometry/iterators/closing_iterator.hpp index 7cd8fa015..a9f67d478 100644 --- a/include/boost/geometry/iterators/closing_iterator.hpp +++ b/include/boost/geometry/iterators/closing_iterator.hpp @@ -28,8 +28,9 @@ namespace boost { namespace geometry \brief Iterator which iterates through a range, but adds first element at end of the range \tparam Range range on which this class is based on \ingroup iterators -\note Use with "closing_iterator or "closing_iterator - to get non-const / const behaviour +\note It's const iterator treating the Range as one containing non-mutable elements. + For both "closing_iterator and "closing_iterator + const reference is always returned when dereferenced. \note This class is normally used from "closeable_view" if Close==true */ template diff --git a/index/test/rtree/Jamfile.v2 b/index/test/rtree/Jamfile.v2 index d906c8880..463ccb3fa 100644 --- a/index/test/rtree/Jamfile.v2 +++ b/index/test/rtree/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost.Geometry Index # -# Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +# 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 @@ -9,3 +9,9 @@ build-project exceptions ; build-project interprocess ; build-project generated ; + +test-suite boost-geometry-index-rtree + : + [ run rtree_values.cpp ] + [ compile-fail rtree_values_invalid.cpp ] + ; diff --git a/index/test/rtree/exceptions/test_throwing.hpp b/index/test/rtree/exceptions/test_throwing.hpp index dc621c0b3..5fc682ce5 100644 --- a/index/test/rtree/exceptions/test_throwing.hpp +++ b/index/test/rtree/exceptions/test_throwing.hpp @@ -2,7 +2,7 @@ // // Throwing objects implementation // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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 @@ -116,6 +116,13 @@ public: typedef typename container::reference reference; typedef typename container::const_reference const_reference; + inline throwing_varray() {} + + template + inline throwing_varray(It first, It last) + : container(first, last) + {} + inline void resize(size_type s) { throwing_varray_settings::throw_if_required(); @@ -135,4 +142,20 @@ public: } }; +// elements derived type trait + +namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { + +template +struct container_from_elements_type, NewValue> +{ + typedef throwing_varray type; +}; + +}} // namespace detail::rtree + +}}} // namespace boost::geometry::index + #endif // BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP diff --git a/index/test/rtree/exceptions/test_throwing_node.hpp b/index/test/rtree/exceptions/test_throwing_node.hpp index cbbb3b76d..d32c6bcca 100644 --- a/index/test/rtree/exceptions/test_throwing_node.hpp +++ b/index/test/rtree/exceptions/test_throwing_node.hpp @@ -1,9 +1,9 @@ // Boost.Geometry Index // -// R-tree nodes based on runtime-polymorphism, storing static-size containers +// R-tree nodes storing static-size containers // test version throwing exceptions on creation // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// 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 @@ -12,8 +12,6 @@ #ifndef BOOST_GEOMETRY_INDEX_TEST_RTREE_THROWING_NODE_HPP #define BOOST_GEOMETRY_INDEX_TEST_RTREE_THROWING_NODE_HPP -#include - #include struct throwing_nodes_stats @@ -41,7 +39,7 @@ namespace detail { namespace rtree { // options implementation (from options.hpp) -struct node_throwing_d_mem_static_tag {}; +struct node_throwing_static_tag {}; template struct options_type< linear_throwing > @@ -49,7 +47,7 @@ struct options_type< linear_throwing > typedef options< linear_throwing, insert_default_tag, choose_by_content_diff_tag, split_default_tag, linear_tag, - node_throwing_d_mem_static_tag + node_throwing_static_tag > type; }; @@ -59,7 +57,7 @@ struct options_type< quadratic_throwing > typedef options< quadratic_throwing, insert_default_tag, choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_throwing_d_mem_static_tag + node_throwing_static_tag > type; }; @@ -69,7 +67,7 @@ struct options_type< rstar_throwing, insert_reinsert_tag, choose_by_overlap_diff_tag, split_default_tag, rstar_tag, - node_throwing_d_mem_static_tag + node_throwing_static_tag > type; }; @@ -80,98 +78,105 @@ struct options_type< rstar_throwing -struct dynamic_internal_node - : public dynamic_node +struct variant_internal_node { typedef throwing_varray< rtree::ptr_pair, Parameters::max_elements + 1 > elements_type; - template - inline dynamic_internal_node(Dummy const&) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; } - inline ~dynamic_internal_node() { throwing_nodes_stats::get_internal_nodes_counter_ref()--; } + template + inline variant_internal_node(Alloc const&) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; } + inline ~variant_internal_node() { throwing_nodes_stats::get_internal_nodes_counter_ref()--; } - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + // required because variants are initialized using node object + // temporary must be taken into account + inline variant_internal_node(variant_internal_node const& n) + : elements(n.elements) + { + throwing_nodes_stats::get_internal_nodes_counter_ref()++; + } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + inline variant_internal_node(variant_internal_node && n) + : elements(boost::move(n.elements)) + { + throwing_nodes_stats::get_internal_nodes_counter_ref()++; + } +#endif elements_type elements; private: - dynamic_internal_node(dynamic_internal_node const&); - dynamic_internal_node & operator=(dynamic_internal_node const&); + variant_internal_node & operator=(variant_internal_node const& n); }; template -struct dynamic_leaf - : public dynamic_node +struct variant_leaf { typedef throwing_varray elements_type; - template - inline dynamic_leaf(Dummy const&) { throwing_nodes_stats::get_leafs_counter_ref()++; } - inline ~dynamic_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; } + template + inline variant_leaf(Alloc const&) { throwing_nodes_stats::get_leafs_counter_ref()++; } + inline ~variant_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; } - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + // required because variants are initialized using node object + // temporary must be taken into account + inline variant_leaf(variant_leaf const& n) + : elements(n.elements) + { + throwing_nodes_stats::get_leafs_counter_ref()++; + } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + inline variant_leaf(variant_leaf && n) + : elements(boost::move(n.elements)) + { + throwing_nodes_stats::get_leafs_counter_ref()++; + } +#endif elements_type elements; private: - dynamic_leaf(dynamic_leaf const&); - dynamic_leaf & operator=(dynamic_leaf const&); -}; - -// elements derived type -template -struct container_from_elements_type, NewValue> -{ - typedef throwing_varray type; + variant_leaf & operator=(variant_leaf const& n); }; // nodes traits template -struct node +struct node { - typedef dynamic_node type; + typedef boost::variant< + variant_leaf, + variant_internal_node + > type; }; template -struct internal_node +struct internal_node { - typedef dynamic_internal_node type; + typedef variant_internal_node type; }; template -struct leaf +struct leaf { - typedef dynamic_leaf type; + typedef variant_leaf type; }; +// visitor traits + template -struct visitor +struct visitor { - typedef dynamic_visitor type; + typedef static_visitor<> type; }; // allocators template -class allocators +struct allocators : public Allocator::template rebind< - typename internal_node< - Value, Parameters, Box, - allocators, - node_throwing_d_mem_static_tag - >::type - >::other - , Allocator::template rebind< - typename leaf< - Value, Parameters, Box, - allocators, - node_throwing_d_mem_static_tag - >::type + typename node, node_throwing_static_tag>::type >::other { typedef typename Allocator::template rebind< @@ -190,69 +195,57 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; - typedef typename Allocator::template rebind< - typename internal_node::type - >::other::pointer internal_node_pointer; +// typedef typename Allocator::template rebind< +// typename internal_node::type +// >::other::pointer internal_node_pointer; typedef typename Allocator::template rebind< - typename internal_node::type - >::other internal_node_allocator_type; - - typedef typename Allocator::template rebind< - typename leaf::type - >::other leaf_allocator_type; + typename node::type + >::other node_allocator_type; inline allocators() - : internal_node_allocator_type() - , leaf_allocator_type() + : node_allocator_type() {} template inline explicit allocators(Alloc const& alloc) - : internal_node_allocator_type(alloc) - , leaf_allocator_type(alloc) + : node_allocator_type(alloc) {} inline allocators(BOOST_FWD_REF(allocators) a) - : internal_node_allocator_type(boost::move(a.internal_node_allocator())) - , leaf_allocator_type(boost::move(a.leaf_allocator())) + : node_allocator_type(boost::move(a.node_allocator())) {} inline allocators & operator=(BOOST_FWD_REF(allocators) a) { - internal_node_allocator() = ::boost::move(a.internal_node_allocator()); - leaf_allocator() = ::boost::move(a.leaf_allocator()); + node_allocator() = boost::move(a.node_allocator()); return *this; } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES inline allocators & operator=(allocators const& a) { - internal_node_allocator() = a.internal_node_allocator(); - leaf_allocator() = a.leaf_allocator(); + node_allocator() = a.node_allocator(); return *this; } #endif void swap(allocators & a) { - boost::swap(internal_node_allocator(), a.internal_node_allocator()); - boost::swap(leaf_allocator(), a.leaf_allocator()); + boost::swap(node_allocator(), a.node_allocator()); } - bool operator==(allocators const& a) const { return leaf_allocator() == a.leaf_allocator(); } + bool operator==(allocators const& a) const { return node_allocator() == a.node_allocator(); } template - bool operator==(Alloc const& a) const { return leaf_allocator() == leaf_allocator_type(a); } + bool operator==(Alloc const& a) const { return node_allocator() == node_allocator_type(a); } - Allocator allocator() const { return Allocator(leaf_allocator()); } + Allocator allocator() const { return Allocator(node_allocator()); } - internal_node_allocator_type & internal_node_allocator() { return *this; } - internal_node_allocator_type const& internal_node_allocator() const { return *this; } - leaf_allocator_type & leaf_allocator() { return *this; } - leaf_allocator_type const& leaf_allocator() const { return *this; } + node_allocator_type & node_allocator() { return *this; } + node_allocator_type const& node_allocator() const { return *this; } }; struct node_bad_alloc : public std::exception @@ -283,7 +276,7 @@ struct throwing_node_settings template struct create_node< Allocators, - dynamic_internal_node + variant_internal_node > { static inline typename Allocators::node_pointer @@ -292,17 +285,17 @@ struct create_node< // throw if counter meets max count throwing_node_settings::throw_if_required(); - return create_dynamic_node< + return create_variant_node< typename Allocators::node_pointer, - dynamic_internal_node - >::apply(allocators.internal_node_allocator()); + variant_internal_node + >::apply(allocators.node_allocator()); } }; template struct create_node< Allocators, - dynamic_leaf + variant_leaf > { static inline typename Allocators::node_pointer @@ -311,10 +304,10 @@ struct create_node< // throw if counter meets max count throwing_node_settings::throw_if_required(); - return create_dynamic_node< + return create_variant_node< typename Allocators::node_pointer, - dynamic_leaf - >::apply(allocators.leaf_allocator()); + variant_leaf + >::apply(allocators.node_allocator()); } }; diff --git a/index/test/rtree/rtree_values.cpp b/index/test/rtree/rtree_values.cpp new file mode 100644 index 000000000..2a9c3a0dd --- /dev/null +++ b/index/test/rtree/rtree_values.cpp @@ -0,0 +1,84 @@ +// Boost.Geometry Index +// Unit Test + +// Copyright (c) 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) + +#include + + +#include + +struct point +{ + point(double xx = 0, double yy = 0) : x(xx), y(yy) {} + double x, y; +}; + +BOOST_GEOMETRY_REGISTER_POINT_2D(point, double, bg::cs::cartesian, x, y) + + +template +void test_pair() +{ + typedef std::pair Value; + + typename boost::remove_const::type box; + bg::assign_zero(box); + + Value val(box, 0); + + // sanity check + std::vector vec; + vec.push_back(val); + vec.push_back(std::make_pair(box, 0)); + vec.push_back(std::make_pair(box, (unsigned short)0)); + + bgi::rtree rt; + rt.insert(val); + rt.insert(std::make_pair(box, 0)); + rt.insert(std::make_pair(box, (unsigned short)0)); + BOOST_CHECK( rt.size() == 3 ); + + BOOST_CHECK( rt.count(val) == 3 ); + BOOST_CHECK( rt.count(std::make_pair(box, 0)) == 3 ); + BOOST_CHECK( rt.count(std::make_pair(box, (unsigned short)0)) == 3 ); + BOOST_CHECK( rt.count(box) == 3 ); + + BOOST_CHECK( rt.remove(val) == 1 ); + BOOST_CHECK( rt.remove(std::make_pair(box, 0)) == 1 ); + BOOST_CHECK( rt.remove(std::make_pair(box, (unsigned short)0)) == 1 ); + BOOST_CHECK( rt.size() == 0 ); +} + +template +void test_point() +{ + bgi::rtree rt; + + rt.insert(0.0); + BOOST_CHECK( rt.size() == 1 ); + BOOST_CHECK( rt.remove(0.0) == 1 ); +} + +int test_main(int, char* []) +{ + typedef bg::model::point Pt; + typedef bg::model::box Box; + + test_pair< Box, bgi::linear<16> >(); + test_pair< Box, bgi::quadratic<4> >(); + test_pair< Box, bgi::rstar<4> >(); + //test_rtree< Box const, bgi::linear<16> >(); + //test_rtree< Box const, bgi::quadratic<4> >(); + //test_rtree< Box const, bgi::rstar<4> >(); + + test_point< bgi::linear<16> >(); + test_point< bgi::quadratic<4> >(); + test_point< bgi::rstar<4> >(); + + return 0; +} diff --git a/index/test/rtree/rtree_values_invalid.cpp b/index/test/rtree/rtree_values_invalid.cpp new file mode 100644 index 000000000..d16861331 --- /dev/null +++ b/index/test/rtree/rtree_values_invalid.cpp @@ -0,0 +1,31 @@ +// Boost.Geometry Index +// Unit Test + +// Copyright (c) 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) + +#include + + +template +void test_rtree() +{ + bgi::rtree rt; + // coordinates aren't implicitly convertible to Point + rt.insert(1.0); + rt.remove(1.0); +} + +int test_main(int, char* []) +{ + typedef bg::model::point Pt; + + test_rtree >(); + test_rtree >(); + test_rtree >(); + + return 0; +} diff --git a/test/algorithms/distance_linear_areal.cpp b/test/algorithms/distance_linear_areal.cpp index 1665da019..b50b16853 100644 --- a/test/algorithms/distance_linear_areal.cpp +++ b/test/algorithms/distance_linear_areal.cpp @@ -28,6 +28,7 @@ typedef bg::model::multi_linestring multi_linestring_type; typedef bg::model::polygon polygon_type; typedef bg::model::polygon open_polygon_type; typedef bg::model::multi_polygon multi_polygon_type; +typedef bg::model::multi_polygon open_multipolygon_type; typedef bg::model::ring ring_type; typedef bg::model::box box_type; typedef bg::model::box int_box_type; @@ -212,6 +213,29 @@ void test_distance_linestring_multipolygon(Strategy const& strategy) //=========================================================================== +template +void test_distance_linestring_open_multipolygon(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "linestring/open multipolygon distance tests" << std::endl; +#endif + typedef test_distance_of_geometries + < + linestring_type, open_multipolygon_type + > tester; + + tester::apply("linestring(-5 1,-2 1)", + "multipolygon(((0 0,10 0,10 10,0 10)))", + 2, 4, strategy, true); + + tester::apply("linestring(-5 1,-3 1)", + "multipolygon(((20 20,21 20,21 21,20 21)),((0 0,10 0,10 10,0 10)))", + 3, 9, strategy, true); +} + +//=========================================================================== + template void test_distance_multilinestring_multipolygon(Strategy const& strategy) { @@ -883,6 +907,7 @@ BOOST_AUTO_TEST_CASE( test_all_segment_multipolygon ) BOOST_AUTO_TEST_CASE( test_all_linestring_multipolygon ) { test_distance_linestring_multipolygon(point_segment_strategy()); + test_distance_linestring_open_multipolygon(point_segment_strategy()); } BOOST_AUTO_TEST_CASE( test_all_multilinestring_multipolygon ) diff --git a/test/algorithms/for_each.cpp b/test/algorithms/for_each.cpp index 2efe10f2c..09e94fa04 100644 --- a/test/algorithms/for_each.cpp +++ b/test/algorithms/for_each.cpp @@ -54,6 +54,18 @@ void test_all() , 4 * 3.0 , "POLYGON((10 1,10 4,4 4,4 1,1 1))" ); + test_geometry > // open ring + ( + "POLYGON((1 1,1 4,4 4,4 1))" + + , 10 + , "POLYGON((101 1,101 4,104 4,104 1))" + , "POLYGON((101 100,101 400,104 400,104 100))" + + , "((1, 1), (1, 4)) ((1, 4), (4, 4)) ((4, 4), (4, 1)) ((4, 1), (1, 1))" + , 4 * 3.0 + , "POLYGON((10 1,10 4,4 4,4 1))" + ); test_geometry > ( "POLYGON((1 1,1 4,4 4,4 1,1 1),(2 2,3 2,3 3,2 3,2 2))" @@ -67,6 +79,19 @@ void test_all() , 4 * 3.0 + 4 * 1.0 , "POLYGON((10 1,10 4,4 4,4 1,1 1,10 1),(2 2,3 2,3 3,2 3,2 2))" ); + test_geometry > // open polygon + ( + "POLYGON((1 1,1 4,4 4,4 1),(2 2,3 2,3 3,2 3))" + + , 20 + , "POLYGON((101 1,101 4,104 4,104 1,101 1),(102 2,103 2,103 3,102 3,102 2))" + , "POLYGON((101 100,101 400,104 400,104 100,101 100),(102 200,103 200,103 300,102 300,102 200))" + + , "((1, 1), (1, 4)) ((1, 4), (4, 4)) ((4, 4), (4, 1)) ((4, 1), (1, 1)) " + "((2, 2), (3, 2)) ((3, 2), (3, 3)) ((3, 3), (2, 3)) ((2, 3), (2, 2))" + , 4 * 3.0 + 4 * 1.0 + , "POLYGON((10 1,10 4,4 4,4 1,10 1),(2 2,3 2,3 3,2 3,2 2))" + ); } int test_main(int, char* []) diff --git a/test/algorithms/point_on_surface.cpp b/test/algorithms/point_on_surface.cpp index b393a35b8..0af85c7a4 100644 --- a/test/algorithms/point_on_surface.cpp +++ b/test/algorithms/point_on_surface.cpp @@ -6,6 +6,11 @@ // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -51,15 +56,11 @@ #endif template -void test_geometry(std::string const& case_id, std::string const& wkt, double expected_x, double expected_y) +void test_geometry(std::string const& case_id, Geometry const& geometry, double /*expected_x*/ = 0, double /*expected_y*/ = 0) { //std::cout << case_id << std::endl; typedef typename bg::point_type::type point_type; - Geometry geometry; - bg::read_wkt(wkt, geometry); - bg::correct(geometry); - point_type point; bg::point_on_surface(geometry, point); @@ -125,6 +126,15 @@ void test_geometry(std::string const& case_id, std::string const& wkt, double ex } +template +void test_geometry(std::string const& case_id, std::string const& wkt, double expected_x = 0, double expected_y = 0) +{ + Geometry geometry; + bg::read_wkt(wkt, geometry); + bg::correct(geometry); + test_geometry(case_id, geometry, expected_x, expected_y); +} + template void test_all() { @@ -152,6 +162,9 @@ void test_all() test_geometry("disjoint_simplex0", disjoint_simplex[0], 0, 0); test_geometry("disjoint_simplex1", disjoint_simplex[1], 0, 0); + test_geometry("ticket_10643", "POLYGON((1074699.93 703064.65, 1074703.90 703064.58, 1074704.53 703061.40, 1074702.10 703054.62, 1074699.93 703064.65))"); + test_geometry("ticket_10643_2", "POLYGON((699.93 64.65, 703.90 64.58, 704.53 61.40, 702.10 54.62, 699.93 64.65))"); + #if defined(BOOST_GEOMETRY_UNIT_TEST_MULTI) { typedef bg::model::multi_polygon multi_polygon; @@ -303,12 +316,33 @@ void test_all() test_geometry("ticket_8254", ticket_8254[0], 0, 0); } +template +void test_dense(std::string const& case_id, double size) +{ + typedef bg::model::polygon polygon; + polygon poly; + + bg::append(poly, Point(-size, 0)); + + double thres = 3.14158 / 8; + for ( double a = thres ; a > -thres ; a -= 0.01 ) + { + bg::append(poly, Point(size * ::cos(a), size * ::sin(a))); + } + + bg::append(poly, Point(-size, 0)); + + test_geometry(case_id, poly); +} int test_main(int, char* []) { test_all >(); + test_dense >("dense1", 100); + test_dense >("dense2", 1000000); + return 0; } diff --git a/test/algorithms/test_get_turns_ll_invariance.hpp b/test/algorithms/test_get_turns_ll_invariance.hpp index 1492df4c8..c0a59c1c4 100644 --- a/test/algorithms/test_get_turns_ll_invariance.hpp +++ b/test/algorithms/test_get_turns_ll_invariance.hpp @@ -128,10 +128,10 @@ public: bg_turns::less_seg_fraction_other_op<>()); std::sort(boost::begin(rturns_all), boost::end(rturns_all), - bg_turns::less_seg_fraction_other_op >()); + bg_turns::less_seg_fraction_other_op >()); std::sort(boost::begin(rturns_wo_cont), boost::end(rturns_wo_cont), - bg_turns::less_seg_fraction_other_op >()); + bg_turns::less_seg_fraction_other_op >()); remove_duplicate_turns::apply(turns_all); remove_duplicate_turns::apply(turns_wo_cont); diff --git a/test/algorithms/test_intersection.hpp b/test/algorithms/test_intersection.hpp index 36c4c1154..4a7cc645c 100644 --- a/test/algorithms/test_intersection.hpp +++ b/test/algorithms/test_intersection.hpp @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -47,10 +46,6 @@ check_result( { bool const is_line = bg::geometry_id::type::value == 2; - typedef typename bg::coordinate_type::type coordinate_type; - typedef typename bg::point_type::type point_type; - boost::ignore_unused(); - typename bg::default_area_result::type length_or_area = 0; int n = 0; for (typename std::vector::const_iterator it = intersection_output.begin(); @@ -100,50 +95,6 @@ check_result( BOOST_CHECK_CLOSE(detected_length_or_area, expected_length_or_area, percentage); #endif -#if defined(TEST_WITH_SVG) - { - bool const ccw = - bg::point_order::value == bg::counterclockwise - || bg::point_order::value == bg::counterclockwise; - bool const open = - bg::closure::value == bg::open - || bg::closure::value == bg::open; - - std::ostringstream filename; - filename << "intersection_" - << caseid << "_" - << string_from_type::name() - << string_from_type::name() - << (ccw ? "_ccw" : "") - << (open ? "_open" : "") -#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS) - << "_no_rob" -#endif - << ".svg"; - - std::ofstream svg(filename.str().c_str()); - - bg::svg_mapper mapper(svg, 500, 500); - - mapper.add(g1); - mapper.add(g2); - - mapper.map(g1, is_line - ? "opacity:0.6;stroke:rgb(0,255,0);stroke-width:5" - : "fill-opacity:0.5;fill:rgb(153,204,0);" - "stroke:rgb(153,204,0);stroke-width:3"); - mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);" - "stroke:rgb(51,51,153);stroke-width:3"); - - for (typename std::vector::const_iterator it = intersection_output.begin(); - it != intersection_output.end(); ++it) - { - mapper.map(*it, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);" - "stroke:rgb(255,0,255);stroke-width:8"); - } - } -#endif - return length_or_area; } @@ -207,6 +158,54 @@ typename bg::default_area_result::type test_intersection(std::string const& check_result(intersection_output, caseid, expected_count, expected_point_count, expected_length_or_area, percentage, debug); +#if defined(TEST_WITH_SVG) + { + bool const is_line = bg::geometry_id::type::value == 2; + typedef typename bg::coordinate_type::type coordinate_type; + + bool const ccw = + bg::point_order::value == bg::counterclockwise + || bg::point_order::value == bg::counterclockwise; + bool const open = + bg::closure::value == bg::open + || bg::closure::value == bg::open; + + std::ostringstream filename; + filename << "intersection_" + << caseid << "_" + << string_from_type::name() + << string_from_type::name() + << (ccw ? "_ccw" : "") + << (open ? "_open" : "") +#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS) + << "_no_rob" +#endif + << ".svg"; + + std::ofstream svg(filename.str().c_str()); + + bg::svg_mapper mapper(svg, 500, 500); + + mapper.add(g1); + mapper.add(g2); + + mapper.map(g1, is_line + ? "opacity:0.6;stroke:rgb(0,255,0);stroke-width:5" + : "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); + mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);" + "stroke:rgb(51,51,153);stroke-width:3"); + + for (typename std::vector::const_iterator it = intersection_output.begin(); + it != intersection_output.end(); ++it) + { + mapper.map(*it, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);" + "stroke:rgb(255,0,255);stroke-width:8"); + } + } +#endif + + if (debug) { std::cout << "end case " << caseid << std::endl; diff --git a/test/multi/algorithms/multi_for_each.cpp b/test/multi/algorithms/multi_for_each.cpp index b16930dba..70165a44f 100644 --- a/test/multi/algorithms/multi_for_each.cpp +++ b/test/multi/algorithms/multi_for_each.cpp @@ -70,6 +70,21 @@ void test_all() , 4 * 3.0 , "MULTIPOLYGON(((10 1,10 4,4 4,4 1,1 1,10 1)))" ); + + // open multipolygon + typedef bg::model::multi_polygon > omp; + test_geometry + ( + "MULTIPOLYGON(((1 1,1 4,4 4,4 1)))" + + , 10 + , "MULTIPOLYGON(((101 1,101 4,104 4,104 1,101 1)))" + , "MULTIPOLYGON(((101 100,101 400,104 400,104 100,101 100)))" + + , "((1, 1), (1, 4)) ((1, 4), (4, 4)) ((4, 4), (4, 1)) ((4, 1), (1, 1))" + , 4 * 3.0 + , "MULTIPOLYGON(((10 1,10 4,4 4,4 1,10 1)))" + ); } int test_main( int , char* [] )