Merge branch 'develop' into feature/buffer

This commit is contained in:
Barend Gehrels
2014-10-15 13:08:39 +02:00
81 changed files with 1634 additions and 1072 deletions

View File

@@ -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]

View File

@@ -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<Box, int> __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<Box, int>` from a container of Boxes on the fly.
RTree rt6(boxes | boost::adaptors::indexed()
| boost::adaptors::transformed(pair_maker()));
[h4 Insert iterator]

View File

@@ -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]

View File

@@ -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 ;

View File

@@ -22,7 +22,7 @@
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
int main(void)
int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef point value;

View File

@@ -26,7 +26,7 @@
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
int main(void)
int main()
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;

View File

@@ -25,7 +25,7 @@
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
int main(void)
int main()
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;

View File

@@ -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<float, 2, bg::cs::cartesian> 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));
}

View File

@@ -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 <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>
// Boost.Range
#include <boost/range.hpp>
// adaptors
#include <boost/range/adaptor/indexed.hpp>
#include <boost/range/adaptor/transformed.hpp>
// a container
#include <vector>
// just for output
#include <iostream>
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 <typename First, typename Second>
struct pair_maker
{
typedef std::pair<First, Second> result_type;
template<typename T>
inline result_type operator()(T const& v) const
{
return result_type(v.value(), v.index());
}
};
int main()
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;
typedef std::vector<box> container;
typedef container::size_type size_type;
typedef std::pair<box, size_type> 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<box, size_type>()));
// print the number of values using boxes[0] as indexable
std::cout << rtree.count(boxes[0]) << std::endl;
return 0;
}
//]

View File

@@ -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

View File

@@ -37,7 +37,7 @@ public:
result_type operator()(size_t i) const { return container[i]; }
};
int main(void)
int main()
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> 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

View File

@@ -38,7 +38,7 @@ struct indexable< boost::shared_ptr<Box> >
}}} // namespace boost::geometry::index
int main(void)
int main()
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> 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<box>(*b) << std::endl;

View File

@@ -65,7 +65,7 @@ struct envelope_visitor : public boost::static_visitor<box>
};
int main(void)
int main()
{
// geometries container
map geometries;

View File

@@ -733,10 +733,10 @@
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.swap_rtree___">swap(rtree &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.insert_value_type_const___">insert(value_type const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.insert_iterator__iterator_">insert(Iterator, Iterator)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.insert_range_const___">insert(Range const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.insert_convertibleorrange_const___">insert(ConvertibleOrRange const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.remove_value_type_const___">remove(value_type const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.remove_iterator__iterator_">remove(Iterator, Iterator)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.remove_range_const___">remove(Range const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.remove_convertibleorrange_const___">remove(ConvertibleOrRange const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.query_predicates_const____outiter_">query(Predicates const &amp;, OutIter)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.qbegin_predicates_const___">qbegin(Predicates const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.boost__geometry__index__rtree.qend__">qend()</link></member>
@@ -756,10 +756,10 @@
<simplelist type="vert" columns="1">
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.insert_rtree_________value_const___">insert(rtree&lt;...&gt; &amp;, Value const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.insert_rtree_________iterator__iterator_">insert(rtree&lt;...&gt; &amp;, Iterator, Iterator)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.insert_rtree_________range_const___">insert(rtree&lt;...&gt; &amp;, Range const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.insert_rtree_________convertibleorrange_const___">insert(rtree&lt;...&gt; &amp;, ConvertibleOrRange const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.remove_rtree_________value_const___">remove(rtree&lt;...&gt; &amp;, Value const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.remove_rtree_________iterator__iterator_">remove(rtree&lt;...&gt; &amp;, Iterator, Iterator)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.remove_rtree_________range_const___">remove(rtree&lt;...&gt; &amp;, Range const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.remove_rtree_________convertibleorrange_const___">remove(rtree&lt;...&gt; &amp;, ConvertibleOrRange const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.query_rtree______const____predicates_const____outiter_">query(rtree&lt;...&gt; const &amp;, Predicates const &amp;, OutIter)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.qbegin_rtree______const____predicates_const___">qbegin(rtree&lt;...&gt; const &amp;, Predicates const &amp;)</link></member>
<member><link linkend="geometry.reference.spatial_indexes.group__rtree__functions.qend_rtree______const___">qend(rtree&lt;...&gt; const &amp;)</link></member>

View File

@@ -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

View File

@@ -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.

View File

@@ -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)

View File

@@ -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<bool> m_visited;
std::vector<int> m_parent_id;
std::vector<signed_index_type> m_parent_id;
};
@@ -145,7 +145,7 @@ private:
= m_neighbors[v->id()].begin();
nit != m_neighbors[v->id()].end(); ++nit)
{
if ( static_cast<int>((*nit)->id()) != data.parent_id(v) )
if ( static_cast<signed_index_type>((*nit)->id()) != data.parent_id(v) )
{
if ( data.visited(*nit) )
{
@@ -153,7 +153,7 @@ private:
}
else
{
data.set_parent_id(*nit, static_cast<int>(v->id()));
data.set_parent_id(*nit, static_cast<signed_index_type>(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<std::size_t>(id))).first;
}

View File

@@ -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)
<< "]";

View File

@@ -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);
}

View File

@@ -76,16 +76,16 @@ private:
TurnIterator turns_beyond)
{
// collect all polygons that have turns
std::set<int> multi_indices;
std::set<signed_index_type> 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<PolygonIterator> 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)
{

View File

@@ -175,22 +175,22 @@ protected:
{
// collect the interior ring indices that have turns with the
// exterior ring
std::set<int> ring_indices;
std::set<signed_index_type> 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);

View File

@@ -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++;

View File

@@ -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<signed_index_type>(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<Ring>::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<signed_index_type>(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<int>(boost::size(ls)) )
|| to_index >= static_cast<signed_index_type>(boost::size(ls)) )
{
return;
}
typedef typename boost::range_difference<LineString>::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<LineString const>::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<bool, RemoveSpikes>());
@@ -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)
{

View File

@@ -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;

View File

@@ -163,7 +163,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
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<overlay_intersection, RemoveSpikes>
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<overlay_intersection, RemoveSpikes>
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<overlay_difference, RemoveSpikes>
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<overlay_difference, RemoveSpikes>
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<overlay_difference, RemoveSpikes>
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<int>(boost::size(linestring) - 1),
static_cast<signed_index_type>(boost::size(linestring) - 1),
robust_policy,
current_piece);
}

View File

@@ -265,7 +265,7 @@ protected:
false, false // do not reverse; do not remove spikes
>::apply(linestring,
current_segment_id,
static_cast<int>(boost::size(linestring) - 1),
static_cast<signed_index_type>(boost::size(linestring) - 1),
robust_policy,
current_piece);
}
@@ -380,7 +380,7 @@ protected:
};
template <typename TurnIterator>
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 <typename Turn>
@@ -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 )
{

View File

@@ -278,13 +278,12 @@ public :
typedef typename boost::range_value<Turns>::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,

View File

@@ -74,19 +74,17 @@ inline void map_turns(Map& map, TurnPoints const& turn_points)
typedef typename boost::range_value<TurnPoints>::type turn_point_type;
typedef typename turn_point_type::container_type container_type;
int index = 0;
for (typename boost::range_iterator<TurnPoints const>::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<container_type const>::type
op_it = boost::begin(it->operations);
op_it != boost::end(it->operations);
++op_it, ++op_index)
++op_it)
{
ring_identifier ring_id
(

View File

@@ -14,19 +14,19 @@
# define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
#endif
#include <vector>
#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER)
#include <iostream>
#endif
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
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;
};

View File

@@ -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<Turns>::type i = 0;
while (current_iit != iit && state.good())
{

View File

@@ -59,7 +59,6 @@ struct turn_operation
{
operation_type operation;
segment_identifier seg_id;
segment_identifier other_id;
SegmentRatio fraction;
inline turn_operation()

View File

@@ -230,7 +230,7 @@ struct areal_areal
|| may_update<exterior, interior, '2'>(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<interior, exterior, '2'>(result)
@@ -269,7 +269,7 @@ struct areal_areal
|| may_update<exterior, interior, '2', true>(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<interior, exterior, '2', true>(result)

View File

@@ -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<turn_type> 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

View File

@@ -161,7 +161,7 @@ struct linear_linear
|| may_update<boundary, boundary, '0'>(result)
|| may_update<boundary, exterior, '0'>(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<turn_type, 0> analyser;
@@ -181,7 +181,7 @@ struct linear_linear
|| may_update<boundary, boundary, '0', true>(result)
|| may_update<boundary, exterior, '0', true>(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<turn_type, 1> analyser;
@@ -626,7 +626,7 @@ struct linear_linear
typename detail::single_geometry_return_type<Geometry const>::type
ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id);
typename detail::single_geometry_return_type<OtherGeometry const>::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:

View File

@@ -92,8 +92,8 @@ struct get_turns
template <int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0>
struct op_to_int
{
template <typename Op>
inline int operator()(Op const& op) const
template <typename SegmentRatio>
inline int operator()(detail::overlay::turn_operation<SegmentRatio> const& op) const
{
switch(op.operation)
{
@@ -108,85 +108,111 @@ struct op_to_int
}
};
template <typename OpToInt>
template <std::size_t OpId, typename OpToInt>
struct less_op_xxx_linear
{
template <typename Op>
inline bool operator()(Op const& left, Op const& right)
template <typename Turn>
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 <std::size_t OpId>
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 <std::size_t OpId>
struct less_op_linear_areal
{
template <typename Op>
inline bool operator()(Op const& left, Op const& right)
template <typename Turn>
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 <std::size_t OpId>
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 <std::size_t OpId>
struct less_op_areal_areal
{
template <typename Op>
inline bool operator()(Op const& left, Op const& right)
template <typename Turn>
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 <std::size_t OpId = 0,
typename LessOp = less_op_xxx_linear< op_to_int<> > >
typename LessOp = less_op_xxx_linear< OpId, op_to_int<> > >
struct less
{
BOOST_STATIC_ASSERT(OpId < 2);
template <typename Op> static inline
bool use_fraction(Op const& left, Op const& right)
template <typename Turn>
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 <typename Turn>
@@ -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) );
}
};

View File

@@ -10,6 +10,14 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
#if defined(BOOST_GEOMETRY_DEBUG_IDENTIFIER)
#include <iostream>
#endif
#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
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;
};

View File

@@ -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 <cstddef>
#include <boost/type_traits/make_signed.hpp>
namespace boost { namespace geometry
{
typedef boost::make_signed<std::size_t>::type signed_index_type;
//typedef std::ptrdiff_t signed_index_type;
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP

View File

@@ -30,13 +30,14 @@ namespace detail { namespace turns
// seg_id -> fraction -> other_id -> operation
template
<
typename IdLess = std::less<int>,
typename IdLess = std::less<signed_index_type>,
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 <typename Op>
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 <typename Op>
static inline bool use_other_id(Op const& left, Op const& right)
template <typename Turn>
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 <typename Op>
static inline bool use_fraction(Op const& left, Op const& right)
template <typename Turn>
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) );
}
};

View File

@@ -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) << ' ';

View File

@@ -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;
}
};

View File

@@ -41,8 +41,7 @@
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/util/add_const_if_c.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -95,30 +94,23 @@ struct fe_range_per_point
};
struct fe_range_per_segment
template <closure_selector Closure>
struct fe_range_per_segment_with_closure
{
template <typename Range, typename Functor>
static inline void apply(Range& range, Functor& f)
{
typedef typename closeable_view
<
Range, closure<Range>::value
>::type view_type;
typedef typename add_const_if_c
<
is_const<Range>::value,
typename point_type<Range>::type
>::type point_type;
typedef typename boost::range_iterator<view_type>::type
iterator_type;
typedef typename boost::range_iterator<Range>::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<point_type> s(*previous, *it);
f(s);
@@ -128,6 +120,41 @@ struct fe_range_per_segment
};
template <>
struct fe_range_per_segment_with_closure<open>
{
template <typename Range, typename Functor>
static inline void apply(Range& range, Functor& f)
{
fe_range_per_segment_with_closure<closed>::apply(range, f);
model::referring_segment
<
typename add_const_if_c
<
is_const<Range>::value,
typename point_type<Range>::type
>::type
> s(range::back(range), range::front(range));
f(s);
}
};
struct fe_range_per_segment
{
template <typename Range, typename Functor>
static inline void apply(Range& range, Functor& f)
{
fe_range_per_segment_with_closure
<
closure<Range>::value
>::apply(range, f);
}
};
struct fe_polygon_per_point
{
template <typename Polygon, typename Functor>

View File

@@ -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 <typename Point, typename Segments>
inline void calculate_centroid(Point& point, Segments const& segments)
template <typename Point, typename P>
inline void calculate_average(Point& point, std::vector<P> 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<Point>::type coordinate_type;
typedef typename std::vector<P>::const_iterator iterator_type;
typedef typename std::vector<P>::size_type size_type;
typedef typename geometry::coordinate_type<Point>::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<Point>::type,
areal_tag,
dimension<Point>::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<Segments const>::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 <int Dimension, typename Extremes, typename Intruders, typename CoordinateType>
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;
}

View File

@@ -58,7 +58,15 @@ template <typename T, typename G>
struct dimension : dimension<point_tag, typename point_type<T, G>::type> {};
template <typename P>
struct dimension<point_tag, P> : traits::dimension<typename geometry::util::bare_type<P>::type> {};
struct dimension<point_tag, P>
: traits::dimension<typename geometry::util::bare_type<P>::type>
{
BOOST_MPL_ASSERT_MSG(
(traits::dimension<typename geometry::util::bare_type<P>::type>::value > 0),
INVALID_DIMENSION_VALUE,
(traits::dimension<typename geometry::util::bare_type<P>::type>)
);
};
} // namespace core_dispatch
#endif

View File

@@ -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 <typename Box, size_t CurrentDimension>
template <typename Box,
std::size_t CurrentDimension = dimension<Box>::value>
struct content_box
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
//BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
@@ -66,7 +66,7 @@ struct content<Indexable, box_tag>
{
static typename default_content_result<Indexable>::type apply(Indexable const& b)
{
return dispatch::content_box<Indexable, dimension<Indexable>::value>::apply(b);
return dispatch::content_box<Indexable>::apply(b);
}
};
@@ -75,9 +75,11 @@ struct content<Indexable, box_tag>
template <typename Indexable>
typename default_content_result<Indexable>::type content(Indexable const& b)
{
return dispatch::content<Indexable,
typename tag<Indexable>::type
>::apply(b);
return dispatch::content
<
Indexable,
typename tag<Indexable>::type
>::apply(b);
}
}}}} // namespace boost::geometry::index::detail

View File

@@ -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 <cstddef>
#include <boost/geometry/core/access.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
template <typename Box, size_t Dimension>
template <typename Box,
std::size_t Dimension = geometry::dimension<Box>::value>
struct is_valid_box
{
BOOST_MPL_ASSERT_MSG(
(0 < dimension<Box>::value &&
0 < Dimension &&
Dimension <= static_cast<size_t>(dimension<Box>::value)),
INVALID_DIMENSION_PARAMETER,
(is_valid_box));
static inline bool apply(Box const& b)
{
return is_valid_box<Box, Dimension - 1>::apply(b) &&
@@ -41,7 +38,8 @@ struct is_valid_box<Box, 1>
}
};
template <typename Indexable, typename Tag>
template <typename Indexable,
typename Tag = typename geometry::tag<Indexable>::type>
struct is_valid
{
BOOST_MPL_ASSERT_MSG(
@@ -64,7 +62,7 @@ struct is_valid<Indexable, box_tag>
{
static inline bool apply(Indexable const& b)
{
return dispatch::is_valid_box<Indexable, dimension<Indexable>::value>::apply(b);
return dispatch::is_valid_box<Indexable>::apply(b);
}
};
@@ -82,7 +80,7 @@ struct is_valid<Indexable, segment_tag>
template <typename Indexable>
inline bool is_valid(Indexable const& b)
{
return dispatch::is_valid<Indexable, typename tag<Indexable>::type>::apply(b);
return dispatch::is_valid<Indexable>::apply(b);
}
}}}} // namespace boost::geometry::index::detail

View File

@@ -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 <typename Box, size_t CurrentDimension, size_t EdgeDimension>
//template <typename Box,
// std::size_t CurrentDimension,
// std::size_t EdgeDimension = dimension<Box>::value>
//struct margin_for_each_edge
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
@@ -38,7 +40,7 @@ struct default_margin_result
// }
//};
//
//template <typename Box, size_t CurrentDimension>
//template <typename Box, std::size_t CurrentDimension>
//struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
@@ -49,7 +51,7 @@ struct default_margin_result
// }
//};
//
//template <typename Box, size_t CurrentDimension>
//template <typename Box, std::size_t CurrentDimension>
//struct margin_for_each_edge<Box, CurrentDimension, 1>
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
@@ -69,16 +71,16 @@ struct default_margin_result
// }
//};
//
//template <typename Box, size_t CurrentDimension>
//template <typename Box,
// std::size_t CurrentDimension = dimension<Box>::value>
//struct margin_for_each_dimension
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
// BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value);
//
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
// margin_for_each_edge<Box, CurrentDimension, detail::traits::dimension<Box>::value>::apply(b);
// margin_for_each_edge<Box, CurrentDimension>::apply(b);
// }
//};
//
@@ -87,7 +89,7 @@ struct default_margin_result
//{
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return margin_for_each_edge<Box, 1, detail::traits::dimension<Box>::value>::apply(b);
// return margin_for_each_edge<Box, 1>::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 <typename Box, size_t CurrentDimension>
template <typename Box,
std::size_t CurrentDimension = dimension<Box>::value>
struct simple_margin_for_each_dimension
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
//BOOST_STATIC_ASSERT(CurrentDimension <= dimension<Box>::value);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
@@ -140,8 +142,8 @@ struct comparable_margin<Box, box_tag>
static inline result_type apply(Box const& g)
{
//return detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
return detail::simple_margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
//return detail::margin_for_each_dimension<Box>::apply(g);
return detail::simple_margin_for_each_dimension<Box>::apply(g);
}
};
@@ -159,7 +161,7 @@ typename default_margin_result<Geometry>::type comparable_margin(Geometry const&
//template <typename Box>
//typename default_margin_result<Box>::type margin(Box const& b)
//{
// return 2 * detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(b);
// return 2 * detail::margin_for_each_dimension<Box>::apply(b);
//}
}}}} // namespace boost::geometry::index::detail

View File

@@ -222,7 +222,6 @@ struct pick_seeds_impl
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef find_greatest_normalized_separation<
Elements, Parameters, Translator,
@@ -282,26 +281,24 @@ struct pick_seeds_impl<Elements, Parameters, Translator, 1>
// from void linear_pick_seeds(node_pointer const& n, unsigned int &seed1, unsigned int &seed2) const
template <typename Elements, typename Parameters, typename Translator>
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<element_type, Translator>::type indexable_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
static const size_t dimension = geometry::dimension<indexable_type>::value;
typedef pick_seeds_impl<Elements, Parameters, Translator, dimension> impl;
typedef pick_seeds_impl
<
Elements, Parameters, Translator,
geometry::dimension<indexable_type>::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<Elements, Parameters, Translator, dimension>::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<Value, Options, Translator, Box, Allocators, linear
BOOST_GEOMETRY_INDEX_ASSERT(elements1.size() == elements1_count, "unexpected number of elements");
// copy original elements
// TODO: use container_from_elements_type for std::allocator
elements_type elements_copy(elements1); // MAY THROW, STRONG (alloc, copy)
// copy original elements - use in-memory storage (std::allocator)
// TODO: move if noexcept
typedef typename rtree::container_from_elements_type<elements_type, element_type>::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();

View File

@@ -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 <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag, bool IsVisitableConst>
struct dynamic_visitor;
struct weak_visitor {};
// node
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct dynamic_node
{
virtual ~dynamic_node() {}
virtual void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, Tag, false> &) = 0;
virtual void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, Tag, true> &) const = 0;
};
struct weak_node {};
// nodes variants forward declarations
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct dynamic_internal_node;
struct weak_internal_node;
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct dynamic_leaf;
// visitor
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct dynamic_visitor<Value, Parameters, Box, Allocators, Tag, true>
{
typedef dynamic_internal_node<Value, Parameters, Box, Allocators, Tag> internal_node;
typedef dynamic_leaf<Value, Parameters, Box, Allocators, Tag> leaf;
virtual ~dynamic_visitor() {}
virtual void operator()(internal_node const&) = 0;
virtual void operator()(leaf const&) = 0;
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct dynamic_visitor<Value, Parameters, Box, Allocators, Tag, false>
{
typedef dynamic_internal_node<Value, Parameters, Box, Allocators, Tag> internal_node;
typedef dynamic_leaf<Value, Parameters, Box, Allocators, Tag> leaf;
virtual ~dynamic_visitor() {}
virtual void operator()(internal_node &) = 0;
virtual void operator()(leaf &) = 0;
};
struct weak_leaf;
// nodes conversion
template <typename Derived, typename Parameters, typename Value, typename Box, typename Allocators, typename Tag>
inline Derived & get(dynamic_node<Value, Parameters, Box, Allocators, Tag> & n)
template <typename Derived, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline Derived & get(weak_node<Value, Parameters, Box, Allocators, Tag> & n)
{
BOOST_GEOMETRY_INDEX_ASSERT(dynamic_cast<Derived*>(&n), "can't cast to a Derived type");
return static_cast<Derived&>(n);
}
// apply visitor
template <typename Visitor, typename Visitable>
inline void apply_visitor(Visitor & v, Visitable & n)
template <typename Visitor, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline void apply_visitor(Visitor & v,
raw_node<Value, Parameters, Box, Allocators, Tag> & n,
bool is_internal_node)
{
BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr");
n.apply_visitor(v);
if ( is_internal_node )
{
typedef raw_internal_node<Value, Parameters, Box, Allocators, Tag> internal_node;
v(get<internal_node>(n));
}
else
{
typedef raw_leaf<Value, Parameters, Box, Allocators, Tag> leaf;
v(get<leaf>(n));
}
}
}} // namespace detail::rtree

View File

@@ -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 <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/rtree/node/auto_deallocator.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp>
#include <boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp>
//#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
//#include <boost/geometry/index/detail/rtree/node/weak_dynamic.hpp>
//#include <boost/geometry/index/detail/rtree/node/weak_static.hpp>
#include <boost/geometry/index/detail/rtree/node/static_visitor.hpp>
#include <boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
#include <boost/geometry/index/detail/rtree/node/node_auto_ptr.hpp>
@@ -84,29 +85,31 @@ struct destroy_element
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct destroy_elements
{
typedef typename Options::parameters_type parameters_type;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
inline static void apply(typename internal_node::elements_type & elements, Allocators & allocators)
template <typename Range>
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 <typename It>
inline static void apply(It first, It last, Allocators & allocators)
{
typedef boost::mpl::bool_<
boost::is_same<
Value, typename std::iterator_traits<It>::value_type
>::value
> is_range_of_values;
apply_dispatch(first, last, allocators, is_range_of_values());
}
private:
template <typename It>
inline static void apply_dispatch(It first, It last, Allocators & allocators,
boost::mpl::bool_<false> const& /*is_range_of_values*/)
{
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> 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 <typename It>
inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/,
boost::mpl::bool_<true> const& /*is_range_of_values*/)
{}
};

View File

@@ -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 <boost/container/vector.hpp>
#include <boost/geometry/index/detail/varray.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// element's indexable type
template <typename Element, typename Translator>
struct element_indexable_type
{
typedef typename indexable_type<Translator>::type type;
};
template <typename First, typename Pointer, typename Translator>
struct element_indexable_type<
rtree::ptr_pair<First, Pointer>,
Translator
>
{
typedef First type;
};
// element's indexable getter
template <typename Element, typename Translator>
typename result_type<Translator>::type
element_indexable(Element const& el, Translator const& tr)
{
return tr(el);
}
template <typename First, typename Pointer, typename Translator>
First const&
element_indexable(rtree::ptr_pair<First, Pointer> const& el, Translator const& /*tr*/)
{
return el.first;
}
// nodes elements
template <typename Node>
struct elements_type
{
typedef typename Node::elements_type type;
};
template <typename Node>
inline typename elements_type<Node>::type &
elements(Node & n)
{
return n.elements;
}
template <typename Node>
inline typename elements_type<Node>::type const&
elements(Node const& n)
{
return n.elements;
}
// elements derived type
template <typename Elements, typename NewValue>
struct container_from_elements_type
{
typedef boost::container::vector<NewValue> type;
};
template <typename OldValue, size_t N, typename NewValue>
struct container_from_elements_type<detail::varray<OldValue, N>, NewValue>
{
typedef detail::varray<NewValue, N> type;
};
}} // namespace detail::rtree
}}} // namespace boost::geometry::index
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP

View File

@@ -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 <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct static_internal_node
struct variant_internal_node
{
typedef typename Allocators::node_allocator_type::template rebind<
rtree::ptr_pair<Box, typename Allocators::node_pointer>
>::other elements_allocator_type;
typedef boost::container::vector<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
elements_allocator_type
> elements_type;
typedef boost::container::vector
<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
typename Allocators::node_allocator_type::template rebind
<
rtree::ptr_pair<Box, typename Allocators::node_pointer>
>::other
> elements_type;
template <typename Al>
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 <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
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 <typename Al>
inline static_leaf(Al const& al)
inline variant_leaf(Al const& al)
: elements(al)
{}
@@ -60,30 +60,30 @@ struct static_leaf
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
struct node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
{
typedef boost::variant<
static_leaf<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>,
static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
variant_leaf<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>,
variant_internal_node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct internal_node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
struct internal_node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
{
typedef static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag> type;
typedef variant_internal_node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct leaf<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
struct leaf<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
{
typedef static_leaf<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag> type;
typedef variant_leaf<Value, Parameters, Box, Allocators, node_variant_dynamic_tag> type;
};
// visitor traits
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag, IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_variant_dynamic_tag, IsVisitableConst>
{
typedef static_visitor<> type;
};
@@ -91,9 +91,12 @@ struct visitor<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag, IsVis
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
class allocators<Allocator, Value, Parameters, Box, node_s_mem_dynamic_tag>
class allocators<Allocator, Value, Parameters, Box, node_variant_dynamic_tag>
: public Allocator::template rebind<
typename node<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_s_mem_dynamic_tag>, node_s_mem_dynamic_tag>::type
typename node<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_variant_dynamic_tag>,
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<Value, Parameters, Box, allocators, node_s_mem_dynamic_tag>::type
typename node<Value, Parameters, Box, allocators, node_variant_dynamic_tag>::type
>::other::pointer node_pointer;
// typedef typename Allocator::template rebind<
// typename internal_node<Value, Parameters, Box, allocators, node_s_mem_dynamic_tag>::type
// >::other::pointer internal_node_pointer;
typedef typename Allocator::template rebind<
typename node<Value, Parameters, Box, allocators, node_s_mem_dynamic_tag>::type
typename node<Value, Parameters, Box, allocators, node_variant_dynamic_tag>::type
>::other node_allocator_type;
inline allocators()
@@ -168,7 +167,7 @@ public:
// create_node_variant
template <typename VariantPtr, typename Node>
struct create_static_node
struct create_variant_node
{
template <typename AllocNode>
static inline VariantPtr apply(AllocNode & alloc_node)
@@ -193,7 +192,7 @@ struct create_static_node
// destroy_node_variant
template <typename Node>
struct destroy_static_node
struct destroy_variant_node
{
template <typename AllocNode, typename VariantPtr>
static inline void apply(AllocNode & alloc_node, VariantPtr n)
@@ -210,15 +209,15 @@ struct destroy_static_node
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
static_internal_node<Value, Parameters, Box, Allocators, Tag>
variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
return create_static_node<
return create_variant_node<
typename Allocators::node_pointer,
static_internal_node<Value, Parameters, Box, Allocators, Tag>
variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.node_allocator());
}
};
@@ -226,15 +225,15 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
static_leaf<Value, Parameters, Box, Allocators, Tag>
variant_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
return create_static_node<
return create_variant_node<
typename Allocators::node_pointer,
static_leaf<Value, Parameters, Box, Allocators, Tag>
variant_leaf<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.node_allocator());
}
};
@@ -244,13 +243,13 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
static_internal_node<Value, Parameters, Box, Allocators, Tag>
variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
destroy_static_node<
static_internal_node<Value, Parameters, Box, Allocators, Tag>
destroy_variant_node<
variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.node_allocator(), n);
}
};
@@ -258,13 +257,13 @@ struct destroy_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
static_leaf<Value, Parameters, Box, Allocators, Tag>
variant_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
destroy_static_node<
static_leaf<Value, Parameters, Box, Allocators, Tag>
destroy_variant_node<
variant_leaf<Value, Parameters, Box, Allocators, Tag>
>::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

View File

@@ -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 <typename Value, typename Parameters, typename Box, typename Allocators>
struct static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
struct variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
typedef typename Allocators::node_allocator_type::template rebind<
rtree::ptr_pair<Box, typename Allocators::node_pointer>
>::other elements_allocator_type;
typedef detail::varray<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
inline static_internal_node(Alloc const&) {}
inline variant_internal_node(Alloc const&) {}
elements_type elements;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
struct variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
typedef typename Allocators::node_allocator_type::template rebind<
Value
>::other elements_allocator_type;
typedef detail::varray<
Value,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
inline static_leaf(Alloc const&) {}
inline variant_leaf(Alloc const&) {}
elements_type elements;
};
@@ -56,30 +48,30 @@ struct static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
struct node<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
typedef boost::variant<
static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>,
static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>,
variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
struct internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
typedef static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag> type;
typedef variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
struct leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
typedef static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag> type;
typedef variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag> type;
};
// visitor traits
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_s_mem_static_tag, IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_variant_static_tag, IsVisitableConst>
{
typedef static_visitor<> type;
};
@@ -87,9 +79,13 @@ struct visitor<Value, Parameters, Box, Allocators, node_s_mem_static_tag, IsVisi
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
struct allocators<Allocator, Value, Parameters, Box, node_s_mem_static_tag>
struct allocators<Allocator, Value, Parameters, Box, node_variant_static_tag>
: public Allocator::template rebind<
typename node<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_s_mem_static_tag>, node_s_mem_static_tag>::type
typename node<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_variant_static_tag>,
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<Value, Parameters, Box, allocators, node_s_mem_static_tag>::type
typename node<Value, Parameters, Box, allocators, node_variant_static_tag>::type
>::other::pointer node_pointer;
// typedef typename Allocator::template rebind<
// typename internal_node<Value, Parameters, Box, allocators, node_s_mem_static_tag>::type
// >::other::pointer internal_node_pointer;
typedef typename Allocator::template rebind<
typename node<Value, Parameters, Box, allocators, node_s_mem_static_tag>::type
typename node<Value, Parameters, Box, allocators, node_variant_static_tag>::type
>::other node_allocator_type;
inline allocators()
@@ -166,15 +158,15 @@ public:
template <typename Allocators, typename Value, typename Parameters, typename Box>
struct create_node<
Allocators,
static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
return create_static_node<
return create_variant_node<
typename Allocators::node_pointer,
static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
>::apply(allocators.node_allocator());
}
};
@@ -182,15 +174,15 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box>
struct create_node<
Allocators,
static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
return create_static_node<
return create_variant_node<
typename Allocators::node_pointer,
static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>
>::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

View File

@@ -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 <boost/variant.hpp>
@@ -20,18 +20,18 @@ namespace detail { namespace rtree {
// nodes variants forward declarations
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct static_internal_node;
struct variant_internal_node;
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct static_leaf;
struct variant_leaf;
// nodes conversion
template <typename V, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline V & get(
boost::variant<
static_leaf<Value, Parameters, Box, Allocators, Tag>,
static_internal_node<Value, Parameters, Box, Allocators, Tag>
variant_leaf<Value, Parameters, Box, Allocators, Tag>,
variant_internal_node<Value, Parameters, Box, Allocators, Tag>
> & v)
{
return boost::get<V>(v);
@@ -42,8 +42,8 @@ inline V & get(
template <typename Visitor, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline void apply_visitor(Visitor & v,
boost::variant<
static_leaf<Value, Parameters, Box, Allocators, Tag>,
static_internal_node<Value, Parameters, Box, Allocators, Tag>
variant_leaf<Value, Parameters, Box, Allocators, Tag>,
variant_internal_node<Value, Parameters, Box, Allocators, Tag>
> & n)
{
boost::apply_visitor(v, n);
@@ -52,8 +52,8 @@ inline void apply_visitor(Visitor & v,
template <typename Visitor, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline void apply_visitor(Visitor & v,
boost::variant<
static_leaf<Value, Parameters, Box, Allocators, Tag>,
static_internal_node<Value, Parameters, Box, Allocators, Tag>
variant_leaf<Value, Parameters, Box, Allocators, Tag>,
variant_internal_node<Value, Parameters, Box, Allocators, Tag>
> 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

View File

@@ -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 <typename Value, typename Parameters, typename Box, typename Allocators>
struct dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
: public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct weak_internal_node
: public weak_node<Value, Parameters, Box, Allocators, Tag>
{
typedef typename Allocators::leaf_allocator_type::template rebind<
rtree::ptr_pair<Box, typename Allocators::node_pointer>
>::other elements_allocator_type;
typedef boost::container::vector<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
elements_allocator_type
> elements_type;
typedef boost::container::vector
<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
typename Allocators::internal_node_allocator_type::template rebind
<
rtree::ptr_pair<Box, typename Allocators::node_pointer>
>::other
> elements_type;
template <typename Al>
inline dynamic_internal_node(Al const& al)
inline weak_internal_node(Al const& al)
: elements(al)
{}
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, true> & v) const { v(*this); }
elements_type elements;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
: public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct weak_leaf
: public weak_node<Value, Parameters, Box, Allocators, Tag>
{
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 <typename Al>
inline dynamic_leaf(Al const& al)
inline weak_leaf(Al const& al)
: elements(al)
{}
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, true> & v) const { v(*this); }
elements_type elements;
};
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
struct node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag>
{
typedef dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag> type;
typedef weak_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct internal_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
struct internal_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag>
{
typedef dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag> type;
typedef weak_internal_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct leaf<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
struct leaf<Value, Parameters, Box, Allocators, node_weak_dynamic_tag>
{
typedef dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag> type;
typedef weak_leaf<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type;
};
// visitor traits
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisitableConst>
{
typedef dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, IsVisitableConst> type;
};
// element's indexable type
template <typename Element, typename Translator>
struct element_indexable_type
{
typedef typename indexable_type<Translator>::type type;
};
template <typename First, typename Pointer, typename Translator>
struct element_indexable_type<
rtree::ptr_pair<First, Pointer>,
Translator
>
{
typedef First type;
};
// element's indexable getter
template <typename Element, typename Translator>
typename result_type<Translator>::type
element_indexable(Element const& el, Translator const& tr)
{
return tr(el);
}
template <typename First, typename Pointer, typename Translator>
First const&
element_indexable(rtree::ptr_pair<First, Pointer> const& el, Translator const& /*tr*/)
{
return el.first;
}
// nodes elements
template <typename Node>
struct elements_type
{
typedef typename Node::elements_type type;
};
template <typename Node>
inline typename elements_type<Node>::type &
elements(Node & n)
{
return n.elements;
}
template <typename Node>
inline typename elements_type<Node>::type const&
elements(Node const& n)
{
return n.elements;
}
// elements derived type
template <typename Elements, typename NewValue>
struct container_from_elements_type
{
typedef boost::container::vector<NewValue> type;
typedef weak_visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisitableConst> type;
};
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
class allocators<Allocator, Value, Parameters, Box, node_d_mem_dynamic_tag>
class allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>
: public Allocator::template rebind<
typename internal_node<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_d_mem_dynamic_tag>, node_d_mem_dynamic_tag>::type
typename internal_node<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>,
node_weak_dynamic_tag
>::type
>::other
, public Allocator::template rebind<
typename leaf<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_d_mem_dynamic_tag>, node_d_mem_dynamic_tag>::type
typename leaf<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>,
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<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
typename node<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type
>::other::pointer node_pointer;
// typedef typename Allocator::template rebind<
// typename internal_node<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
// >::other::pointer internal_node_pointer;
typedef typename Allocator::template rebind<
typename internal_node<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
typename internal_node<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type
>::other internal_node_allocator_type;
typedef typename Allocator::template rebind<
typename leaf<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
typename leaf<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type
>::other leaf_allocator_type;
inline allocators()
@@ -248,7 +184,7 @@ public:
// create_node_impl
template <typename BaseNodePtr, typename Node>
struct create_dynamic_node
struct create_weak_node
{
template <typename AllocNode>
static inline BaseNodePtr apply(AllocNode & alloc_node)
@@ -273,7 +209,7 @@ struct create_dynamic_node
// destroy_node_impl
template <typename Node>
struct destroy_dynamic_node
struct destroy_weak_node
{
template <typename AllocNode, typename BaseNodePtr>
static inline void apply(AllocNode & alloc_node, BaseNodePtr n)
@@ -292,15 +228,15 @@ struct destroy_dynamic_node
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
return create_dynamic_node<
return create_weak_node<
typename Allocators::node_pointer,
dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.internal_node_allocator());
}
};
@@ -308,15 +244,15 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
weak_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
return create_dynamic_node<
return create_weak_node<
typename Allocators::node_pointer,
dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
weak_leaf<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.leaf_allocator());
}
};
@@ -326,13 +262,13 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
destroy_dynamic_node<
dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
destroy_weak_node<
weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.internal_node_allocator(), n);
}
};
@@ -340,13 +276,13 @@ struct destroy_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
weak_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
destroy_dynamic_node<
dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
destroy_weak_node<
weak_leaf<Value, Parameters, Box, Allocators, Tag>
>::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

View File

@@ -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 <typename Value, typename Parameters, typename Box, typename Allocators>
struct dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
: public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
struct weak_internal_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
: public weak_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
typedef typename Allocators::leaf_allocator_type::template rebind<
rtree::ptr_pair<Box, typename Allocators::node_pointer>
>::other elements_allocator_type;
typedef detail::varray<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
inline dynamic_internal_node(Alloc const&) {}
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, true> & v) const { v(*this); }
inline weak_internal_node(Alloc const&) {}
elements_type elements;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
: public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
struct weak_leaf<Value, Parameters, Box, Allocators, node_weak_static_tag>
: public weak_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
typedef typename Allocators::leaf_allocator_type::template rebind<
Value
>::other elements_allocator_type;
typedef detail::varray<
Value,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
inline dynamic_leaf(Alloc const&) {}
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, true> & v) const { v(*this); }
inline weak_leaf(Alloc const&) {}
elements_type elements;
};
@@ -62,52 +48,45 @@ struct dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
struct node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
typedef dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag> type;
typedef weak_node<Value, Parameters, Box, Allocators, node_weak_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct internal_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
struct internal_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
typedef dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag> type;
typedef weak_internal_node<Value, Parameters, Box, Allocators, node_weak_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
struct leaf<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
typedef dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag> type;
typedef weak_leaf<Value, Parameters, Box, Allocators, node_weak_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_weak_static_tag, IsVisitableConst>
{
typedef dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, IsVisitableConst> type;
};
// elements derived type
template <typename OldValue, size_t N, typename NewValue>
struct container_from_elements_type<detail::varray<OldValue, N>, NewValue>
{
typedef detail::varray<NewValue, N> type;
typedef weak_visitor<Value, Parameters, Box, Allocators, node_weak_static_tag, IsVisitableConst> type;
};
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
class allocators<Allocator, Value, Parameters, Box, node_d_mem_static_tag>
class allocators<Allocator, Value, Parameters, Box, node_weak_static_tag>
: public Allocator::template rebind<
typename internal_node<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_d_mem_static_tag>,
node_d_mem_static_tag
allocators<Allocator, Value, Parameters, Box, node_weak_static_tag>,
node_weak_static_tag
>::type
>::other
, public Allocator::template rebind<
typename leaf<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_d_mem_static_tag>,
node_d_mem_static_tag
allocators<Allocator, Value, Parameters, Box, node_weak_static_tag>,
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<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
typename node<Value, Parameters, Box, allocators, node_weak_static_tag>::type
>::other::pointer node_pointer;
// typedef typename Allocator::template rebind<
// typename internal_node<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
// >::other::pointer internal_node_pointer;
typedef typename Allocator::template rebind<
typename internal_node<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
typename internal_node<Value, Parameters, Box, allocators, node_weak_static_tag>::type
>::other internal_node_allocator_type;
typedef typename Allocator::template rebind<
typename leaf<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
typename leaf<Value, Parameters, Box, allocators, node_weak_static_tag>::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

View File

@@ -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 <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag, bool IsVisitableConst>
struct weak_visitor {};
// node
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct weak_node {};
// nodes variants forward declarations
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct weak_internal_node;
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct weak_leaf;
// nodes conversion
template <typename Derived, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline Derived & get(weak_node<Value, Parameters, Box, Allocators, Tag> & n)
{
return static_cast<Derived&>(n);
}
// apply visitor
template <typename Visitor, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline void apply_visitor(Visitor & v,
weak_node<Value, Parameters, Box, Allocators, Tag> & n,
bool is_internal_node)
{
BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr");
if ( is_internal_node )
{
typedef weak_internal_node<Value, Parameters, Box, Allocators, Tag> internal_node;
v(get<internal_node>(n));
}
else
{
typedef weak_leaf<Value, Parameters, Box, Allocators, Tag> leaf;
v(get<leaf>(n));
}
}
}} // namespace detail::rtree
}}} // namespace boost::geometry::index
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP

View File

@@ -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 <typename Parameters, typename InsertTag, typename ChooseNextNodeTag, typename SplitTag, typename RedistributeTag, typename NodeTag>
struct options
@@ -66,7 +66,7 @@ struct options_type< index::linear<MaxElements, MinElements> >
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<MaxElements, MinElements> >
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<MaxElements, MinElements, OverlapCostThreshold
choose_by_overlap_diff_tag,
split_default_tag,
rstar_tag,
node_s_mem_static_tag
node_variant_static_tag
> type;
};
@@ -105,7 +105,7 @@ struct options_type< index::rstar<MaxElements, MinElements, OverlapCostThreshold
// choose_by_content_diff_tag, // change it?
// split_kmeans_tag,
// int, // dummy tag - not used for now
// node_s_mem_static_tag
// node_variant_static_tag
// > 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;
};

View File

@@ -125,11 +125,11 @@ class pack
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef typename Allocators::size_type size_type;
typedef typename traits::point_type<Box>::type point_type;
typedef typename traits::coordinate_type<point_type>::type coordinate_type;
typedef typename geometry::point_type<Box>::type point_type;
typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
typedef typename detail::default_content_result<Box>::type content_type;
typedef typename Options::parameters_type parameters_type;
static const std::size_t dimension = traits::dimension<point_type>::value;
static const std::size_t dimension = geometry::dimension<point_type>::value;
typedef typename rtree::container_from_elements_type<
typename rtree::elements_type<leaf>::type,

View File

@@ -28,60 +28,56 @@ namespace detail { namespace rtree {
namespace quadratic {
template <typename Elements, typename Parameters, typename Translator, typename Box>
struct pick_seeds
template <typename Box, typename Elements, typename Parameters, typename Translator>
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<element_type, Translator>::type indexable_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef Box box_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
typedef index::detail::bounded_view<indexable_type, box_type> 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<Value, Options, Translator, Box, Allocators, quadra
BOOST_GEOMETRY_INDEX_ASSERT(elements1.size() == parameters.get_max_elements() + 1, "unexpected elements number");
// copy original elements
// TODO: use container_from_elements_type for std::allocator
elements_type elements_copy(elements1); // MAY THROW, STRONG (alloc, copy)
elements_type elements_backup(elements1); // MAY THROW, STRONG (alloc, copy)
// copy original elements - use in-memory storage (std::allocator)
// TODO: move if noexcept
typedef typename rtree::container_from_elements_type<elements_type, element_type>::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<Box>(elements_copy, parameters, translator, seed1, seed2);
// prepare nodes' elements containers
elements1.clear();
@@ -170,7 +163,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
// redistribute the rest of the elements
while ( !elements_copy.empty() )
{
typename elements_type::reverse_iterator el_it = elements_copy.rbegin();
typename container_type::reverse_iterator el_it = elements_copy.rbegin();
bool insert_into_group1 = false;
size_t elements1_count = elements1.size();
@@ -227,7 +220,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
}
BOOST_GEOMETRY_INDEX_ASSERT(!elements_copy.empty(), "expected more elements");
typename elements_type::iterator el_it_base = el_it.base();
typename container_type::iterator el_it_base = el_it.base();
rtree::move_from_back(elements_copy, --el_it_base); // MAY THROW, STRONG (copy)
elements_copy.pop_back();

View File

@@ -178,14 +178,15 @@ struct level_insert_base
typedef typename Options::parameters_type parameters_type;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
inline level_insert_base(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)
size_type relative_level)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
, result_relative_level(0)
{}
@@ -240,7 +241,7 @@ struct level_insert_base
}
}
size_t result_relative_level;
size_type result_relative_level;
result_elements_type result_elements;
};
@@ -256,14 +257,15 @@ struct level_insert
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,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
size_t relative_level)
size_type relative_level)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
{}
@@ -341,14 +343,15 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
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)
{}
@@ -396,14 +399,15 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
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<Element, Value, Options, Translator, Box, Allocators, insert_reinse
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::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;
};

View File

@@ -89,13 +89,13 @@ private:
Translator const& m_tr;
};
template <typename Parameters, typename Box, size_t Corner, size_t AxisIndex>
template <typename Box, size_t Corner, size_t AxisIndex>
struct choose_split_axis_and_index_for_corner
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
template <typename Elements, typename Translator>
template <typename Elements, typename Parameters, typename Translator>
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 <typename Parameters, typename Box, size_t AxisIndex, typename ElementIndexableTag>
//template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
//struct choose_split_axis_and_index_for_axis
//{
// BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
//};
template <typename Parameters, typename Box, size_t AxisIndex, typename ElementIndexableTag>
template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
struct choose_split_axis_and_index_for_axis
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
template <typename Elements, typename Translator>
template <typename Elements, typename Parameters, typename Translator>
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<content_type>::max)();
content_type con1 = (std::numeric_limits<content_type>::max)();
choose_split_axis_and_index_for_corner<Parameters, Box, min_corner, AxisIndex>::
apply(elements, index1,
som1, ovl1, con1,
parameters, translator); // MAY THROW, STRONG
choose_split_axis_and_index_for_corner<Box, min_corner, AxisIndex>
::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<content_type>::max)();
content_type con2 = (std::numeric_limits<content_type>::max)();
choose_split_axis_and_index_for_corner<Parameters, Box, max_corner, AxisIndex>::
apply(elements, index2,
som2, ovl2, con2,
parameters, translator); // MAY THROW, STRONG
choose_split_axis_and_index_for_corner<Box, max_corner, AxisIndex>
::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 <typename Parameters, typename Box, size_t AxisIndex>
struct choose_split_axis_and_index_for_axis<Parameters, Box, AxisIndex, point_tag>
template <typename Box, size_t AxisIndex>
struct choose_split_axis_and_index_for_axis<Box, AxisIndex, point_tag>
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
template <typename Elements, typename Translator>
template <typename Elements, typename Parameters, typename Translator>
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<Parameters, Box, AxisIndex, point_ta
Parameters const& parameters,
Translator const& translator)
{
choose_split_axis_and_index_for_corner<Parameters, Box, min_corner, AxisIndex>::
apply(elements, choosen_index,
sum_of_margins, smallest_overlap, smallest_content,
parameters, translator); // MAY THROW, STRONG
choose_split_axis_and_index_for_corner<Box, min_corner, AxisIndex>
::apply(elements, choosen_index,
sum_of_margins, smallest_overlap, smallest_content,
parameters, translator); // MAY THROW, STRONG
choosen_corner = min_corner;
}
};
template <typename Parameters, typename Box, size_t Dimension>
template <typename Box, size_t Dimension>
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<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
template <typename Elements, typename Translator>
template <typename Elements, typename Parameters, typename Translator>
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<typename Elements::value_type, Translator>::type element_indexable_type;
choose_split_axis_and_index<Parameters, Box, Dimension - 1>::
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<Box, Dimension - 1>
::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<content_type>::max)();
choose_split_axis_and_index_for_axis<
Parameters,
Box,
Dimension - 1,
typename tag<element_indexable_type>::type
@@ -299,13 +298,13 @@ struct choose_split_axis_and_index
}
};
template <typename Parameters, typename Box>
struct choose_split_axis_and_index<Parameters, Box, 1>
template <typename Box>
struct choose_split_axis_and_index<Box, 1>
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
template <typename Elements, typename Translator>
template <typename Elements, typename Parameters, typename Translator>
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<Parameters, Box, 1>
choosen_axis = 0;
choose_split_axis_and_index_for_axis<
Parameters,
Box,
0,
typename tag<element_indexable_type>::type
@@ -391,14 +389,17 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
Allocators & allocators)
{
typedef typename rtree::elements_type<Node>::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<elements_type, element_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<Value, Options, Translator, Box, Allocators, rstar_
// and again, the same below calling partial_sort/nth_element
// It would be even possible to not re-sort/find nth_element if the axis/corner
// was found for the last sorting - last combination of axis/corner
rstar::choose_split_axis_and_index<
typename Options::parameters_type,
Box,
dimension
>::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<Box, dimension>
::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");

View File

@@ -15,7 +15,37 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Indexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename Indexable, typename Value>
struct count_helper
{
template <typename Translator>
static inline typename Translator::result_type indexable(Indexable const& i, Translator const&)
{
return i;
}
template <typename Translator>
static inline bool equals(Indexable const& i, Value const& v, Translator const& tr)
{
return geometry::equals(i, tr(v));
}
};
template <typename Value>
struct count_helper<Value, Value>
{
template <typename Translator>
static inline typename Translator::result_type indexable(Value const& v, Translator const& tr)
{
return tr(v);
}
template <typename Translator>
static inline bool equals(Value const& v1, Value const& v2, Translator const& tr)
{
return tr.equals(v1, v2);
}
};
template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct count
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
{
@@ -23,8 +53,10 @@ struct count
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
inline count(Indexable const& i, Translator const& t)
: indexable(i), tr(t), found_count(0)
typedef count_helper<ValueOrIndexable, Value> 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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct count<Value, Value, Options, Translator, Box, Allocators>
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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<internal_node>::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<leaf>::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;
};

View File

@@ -178,17 +178,20 @@ public:
namespace visitors { namespace detail {
template <typename InternalNode, typename InternalNodePtr>
template <typename InternalNode, typename InternalNodePtr, typename SizeType>
struct insert_traverse_data
{
typedef typename rtree::elements_type<InternalNode>::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<Value, Options, Translator, Box, Allocators> 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<internal_node, internal_node_pointer> backup_traverse_data = m_traverse_data;
insert_traverse_data<internal_node, internal_node_pointer, size_type>
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<internal_node, internal_node_pointer> m_traverse_data;
insert_traverse_data<internal_node, internal_node_pointer, size_type> 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)
{}

View File

@@ -32,13 +32,16 @@ class remove
typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef typename rtree::elements_type<internal_node>::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<size_t, node_pointer> > UnderflowNodes;
typedef std::vector< std::pair<size_type, node_pointer> > 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<internal_node>::type & elements,
typename rtree::elements_type<internal_node>::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 <typename Node>
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<Node>::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;

View File

@@ -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<class Archive> 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 <typename P, size_t I = 0, size_t D = traits::dimension<P>::value>
template <typename P, size_t I = 0, size_t D = geometry::dimension<P>::value>
struct serialize_point
{
template <typename Archive>
@@ -239,7 +239,7 @@ struct serialize_point
template <typename Archive>
static inline void load(Archive & ar, P & p, unsigned int version)
{
typename traits::coordinate_type<P>::type c;
typename geometry::coordinate_type<P>::type c;
ar >> boost::serialization::make_nvp("c", c);
set<I>(p, c);
serialize_point<P, I+1, D>::load(ar, p, version);

View File

@@ -29,7 +29,11 @@ template <typename Indexable>
struct is_indexable
{
static const bool value =
is_indexable_impl<Indexable, typename geometry::traits::tag<Indexable>::type>::value;
is_indexable_impl
<
Indexable,
typename geometry::tag<Indexable>::type
>::value;
};
/*!

View File

@@ -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 <typename Range>
inline void insert(Range const& rng)
template <typename ConvertibleOrRange>
inline void insert(ConvertibleOrRange const& conv_or_rng)
{
BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
typedef boost::mpl::bool_
<
boost::is_convertible<ConvertibleOrRange, value_type>::value
> is_conv_t;
if ( !m_members.root )
this->raw_create();
typedef typename boost::range_const_iterator<Range>::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 <tt>std::map erase()</tt> 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 <typename Range>
inline size_type remove(Range const& rng)
template <typename ConvertibleOrRange>
inline size_type remove(ConvertibleOrRange const& conv_or_rng)
{
BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
typedef boost::mpl::bool_
<
boost::is_convertible<ConvertibleOrRange, value_type>::value
> is_conv_t;
size_type result = 0;
typedef typename boost::range_const_iterator<Range>::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 <typename ValueOrIndexable>
size_type count(ValueOrIndexable const& vori) const
{
enum { as_val = 0, as_ind, dont_know };
typedef boost::mpl::int_
<
boost::is_same<ValueOrIndexable, value_type>::value ?
as_val :
boost::is_same<ValueOrIndexable, indexable_type>::value ?
as_ind :
boost::is_convertible<ValueOrIndexable, indexable_type>::value ?
as_ind :
boost::is_convertible<ValueOrIndexable, value_type>::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<ValueOrIndexable, value_type, options_type, translator_type, box_type, allocators_type>
detail::rtree::visitors::count<value_or_indexable, value_type, options_type, translator_type, box_type, allocators_type>
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 <typename ValueConvertible>
inline void insert_dispatch(ValueConvertible const& val_conv,
boost::mpl::bool_<true> 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 <typename Range>
inline void insert_dispatch(Range const& rng,
boost::mpl::bool_<false> const& /*is_convertible*/)
{
BOOST_MPL_ASSERT_MSG((detail::is_range<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<Range>::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 <typename ValueConvertible>
inline size_type remove_dispatch(ValueConvertible const& val_conv,
boost::mpl::bool_<true> 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 <typename Range>
inline size_type remove_dispatch(Range const& rng,
boost::mpl::bool_<false> const& /*is_convertible*/)
{
BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value),
PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
(Range));
size_type result = 0;
typedef typename boost::range_const_iterator<Range>::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 <tt>rtree::insert(value_type const&)</tt>.
\param v The value which will be stored in the index.
*/
template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
Value const& v)
{
tree.insert(v);
}
@@ -1472,26 +1575,30 @@ It calls <tt>rtree::insert(Iterator, Iterator)</tt>.
\param first The beginning of the range of values.
\param last The end of the range of values.
*/
template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
typename Iterator>
inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & 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 <tt>rtree::insert(Range const&)</tt>.
It calls <tt>rtree::insert(ConvertibleOrRange const&)</tt>.
\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<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
typename ConvertibleOrRange>
inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
ConvertibleOrRange const& conv_or_rng)
{
tree.insert(rng);
tree.insert(conv_or_rng);
}
/*!
@@ -1511,7 +1618,8 @@ It calls <tt>rtree::remove(value_type const&)</tt>.
*/
template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
Value const& v)
{
return tree.remove(v);
}
@@ -1534,34 +1642,39 @@ It calls <tt>rtree::remove(Iterator, Iterator)</tt>.
\return The number of removed values.
*/
template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
typename Iterator>
inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & 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 <tt>std::map erase()</tt> 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 <tt>std::map erase()</tt> 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 <tt>rtree::remove(Range const&)</tt>.
It calls <tt>rtree::remove(ConvertibleOrRange const&)</tt>.
\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<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
typename ConvertibleOrRange>
inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
ConvertibleOrRange const& conv_or_rng)
{
return tree.remove(rng);
return tree.remove(conv_or_rng);
}
/*!

View File

@@ -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<Range> or "closing_iterator<Range const>
to get non-const / const behaviour
\note It's const iterator treating the Range as one containing non-mutable elements.
For both "closing_iterator<Range> and "closing_iterator<Range const>
const reference is always returned when dereferenced.
\note This class is normally used from "closeable_view" if Close==true
*/
template <typename Range>

View File

@@ -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 ]
;

View File

@@ -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 <typename It>
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 <typename OldValue, size_t N, typename NewValue>
struct container_from_elements_type<throwing_varray<OldValue, N>, NewValue>
{
typedef throwing_varray<NewValue, N> type;
};
}} // namespace detail::rtree
}}} // namespace boost::geometry::index
#endif // BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP

View File

@@ -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 <boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp>
#include <rtree/exceptions/test_throwing.hpp>
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 <size_t MaxElements, size_t MinElements>
struct options_type< linear_throwing<MaxElements, MinElements> >
@@ -49,7 +47,7 @@ struct options_type< linear_throwing<MaxElements, MinElements> >
typedef options<
linear_throwing<MaxElements, MinElements>,
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<MaxElements, MinElements> >
typedef options<
quadratic_throwing<MaxElements, MinElements>,
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<MaxElements, MinElements, OverlapCostThresho
typedef options<
rstar_throwing<MaxElements, MinElements, OverlapCostThreshold, ReinsertedElements>,
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<MaxElements, MinElements, OverlapCostThresho
namespace detail { namespace rtree {
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct dynamic_internal_node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
: public dynamic_node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
struct variant_internal_node<Value, Parameters, Box, Allocators, node_throwing_static_tag>
{
typedef throwing_varray<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
Parameters::max_elements + 1
> elements_type;
template <typename Dummy>
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 <typename Alloc>
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<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, true> & 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 <typename Value, typename Parameters, typename Box, typename Allocators>
struct dynamic_leaf<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
: public dynamic_node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
struct variant_leaf<Value, Parameters, Box, Allocators, node_throwing_static_tag>
{
typedef throwing_varray<Value, Parameters::max_elements + 1> elements_type;
template <typename Dummy>
inline dynamic_leaf(Dummy const&) { throwing_nodes_stats::get_leafs_counter_ref()++; }
inline ~dynamic_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; }
template <typename Alloc>
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<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, true> & 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 <typename OldValue, size_t N, typename NewValue>
struct container_from_elements_type<throwing_varray<OldValue, N>, NewValue>
{
typedef throwing_varray<NewValue, N> type;
variant_leaf & operator=(variant_leaf const& n);
};
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
struct node<Value, Parameters, Box, Allocators, node_throwing_static_tag>
{
typedef dynamic_node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag> type;
typedef boost::variant<
variant_leaf<Value, Parameters, Box, Allocators, node_throwing_static_tag>,
variant_internal_node<Value, Parameters, Box, Allocators, node_throwing_static_tag>
> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct internal_node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
struct internal_node<Value, Parameters, Box, Allocators, node_throwing_static_tag>
{
typedef dynamic_internal_node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag> type;
typedef variant_internal_node<Value, Parameters, Box, Allocators, node_throwing_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
struct leaf<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
struct leaf<Value, Parameters, Box, Allocators, node_throwing_static_tag>
{
typedef dynamic_leaf<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag> type;
typedef variant_leaf<Value, Parameters, Box, Allocators, node_throwing_static_tag> type;
};
// visitor traits
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, IsVisitableConst>
struct visitor<Value, Parameters, Box, Allocators, node_throwing_static_tag, IsVisitableConst>
{
typedef dynamic_visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, IsVisitableConst> type;
typedef static_visitor<> type;
};
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
class allocators<Allocator, Value, Parameters, Box, node_throwing_d_mem_static_tag>
struct allocators<Allocator, Value, Parameters, Box, node_throwing_static_tag>
: public Allocator::template rebind<
typename internal_node<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_throwing_d_mem_static_tag>,
node_throwing_d_mem_static_tag
>::type
>::other
, Allocator::template rebind<
typename leaf<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, node_throwing_d_mem_static_tag>,
node_throwing_d_mem_static_tag
>::type
typename node<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_throwing_static_tag>, 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<Value, Parameters, Box, allocators, node_throwing_d_mem_static_tag>::type
typename node<Value, Parameters, Box, allocators, node_throwing_static_tag>::type
>::other::pointer node_pointer;
typedef typename Allocator::template rebind<
typename internal_node<Value, Parameters, Box, allocators, node_throwing_d_mem_static_tag>::type
>::other::pointer internal_node_pointer;
// typedef typename Allocator::template rebind<
// typename internal_node<Value, Parameters, Box, allocators, node_throwing_static_tag>::type
// >::other::pointer internal_node_pointer;
typedef typename Allocator::template rebind<
typename internal_node<Value, Parameters, Box, allocators, node_throwing_d_mem_static_tag>::type
>::other internal_node_allocator_type;
typedef typename Allocator::template rebind<
typename leaf<Value, Parameters, Box, allocators, node_throwing_d_mem_static_tag>::type
>::other leaf_allocator_type;
typename node<Value, Parameters, Box, allocators, node_throwing_static_tag>::type
>::other node_allocator_type;
inline allocators()
: internal_node_allocator_type()
, leaf_allocator_type()
: node_allocator_type()
{}
template <typename Alloc>
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 <typename Alloc>
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 <typename Allocators, typename Value, typename Parameters, typename Box>
struct create_node<
Allocators,
dynamic_internal_node<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
variant_internal_node<Value, Parameters, Box, Allocators, node_throwing_static_tag>
>
{
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<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
>::apply(allocators.internal_node_allocator());
variant_internal_node<Value, Parameters, Box, Allocators, node_throwing_static_tag>
>::apply(allocators.node_allocator());
}
};
template <typename Allocators, typename Value, typename Parameters, typename Box>
struct create_node<
Allocators,
dynamic_leaf<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
variant_leaf<Value, Parameters, Box, Allocators, node_throwing_static_tag>
>
{
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<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag>
>::apply(allocators.leaf_allocator());
variant_leaf<Value, Parameters, Box, Allocators, node_throwing_static_tag>
>::apply(allocators.node_allocator());
}
};

View File

@@ -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 <rtree/test_rtree.hpp>
#include <boost/geometry/geometries/register/point.hpp>
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 <typename Box, typename Params>
void test_pair()
{
typedef std::pair<Box, std::size_t> Value;
typename boost::remove_const<Box>::type box;
bg::assign_zero(box);
Value val(box, 0);
// sanity check
std::vector<Value> 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<Value, Params> 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 <typename Params>
void test_point()
{
bgi::rtree<point, Params> 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<double, 2, bg::cs::cartesian> Pt;
typedef bg::model::box<Pt> 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;
}

View File

@@ -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 <rtree/test_rtree.hpp>
template <typename Point, typename Params>
void test_rtree()
{
bgi::rtree<Point, Params> 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<double, 1, bg::cs::cartesian> Pt;
test_rtree<Pt, bgi::linear<16> >();
test_rtree<Pt, bgi::quadratic<4> >();
test_rtree<Pt, bgi::rstar<4> >();
return 0;
}

View File

@@ -28,6 +28,7 @@ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
typedef bg::model::polygon<point_type, false> polygon_type;
typedef bg::model::polygon<point_type, false, false> open_polygon_type;
typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
typedef bg::model::multi_polygon<open_polygon_type> open_multipolygon_type;
typedef bg::model::ring<point_type, false> ring_type;
typedef bg::model::box<point_type> box_type;
typedef bg::model::box<int_point_type> int_box_type;
@@ -212,6 +213,29 @@ void test_distance_linestring_multipolygon(Strategy const& strategy)
//===========================================================================
template <typename Strategy>
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 <typename Strategy>
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 )

View File

@@ -54,6 +54,18 @@ void test_all()
, 4 * 3.0
, "POLYGON((10 1,10 4,4 4,4 1,1 1))"
);
test_geometry<bg::model::ring<P, true, false> > // 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<bg::model::polygon<P> >
(
"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<bg::model::polygon<P, true, false> > // 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* [])

View File

@@ -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 <typename Geometry>
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<Geometry>::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 <typename Geometry>
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 <typename Point>
void test_all()
{
@@ -152,6 +162,9 @@ void test_all()
test_geometry<polygon>("disjoint_simplex0", disjoint_simplex[0], 0, 0);
test_geometry<polygon>("disjoint_simplex1", disjoint_simplex[1], 0, 0);
test_geometry<polygon>("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<polygon>("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<polygon> multi_polygon;
@@ -303,12 +316,33 @@ void test_all()
test_geometry<polygon>("ticket_8254", ticket_8254[0], 0, 0);
}
template <typename Point>
void test_dense(std::string const& case_id, double size)
{
typedef bg::model::polygon<Point> 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<bg::model::d2::point_xy<double> >();
test_dense<bg::model::d2::point_xy<double> >("dense1", 100);
test_dense<bg::model::d2::point_xy<double> >("dense2", 1000000);
return 0;
}

View File

@@ -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<std::greater<int> >());
bg_turns::less_seg_fraction_other_op<std::greater<boost::geometry::signed_index_type> >());
std::sort(boost::begin(rturns_wo_cont), boost::end(rturns_wo_cont),
bg_turns::less_seg_fraction_other_op<std::greater<int> >());
bg_turns::less_seg_fraction_other_op<std::greater<boost::geometry::signed_index_type> >());
remove_duplicate_turns::apply(turns_all);
remove_duplicate_turns::apply(turns_wo_cont);

View File

@@ -12,7 +12,6 @@
#include <fstream>
#include <iomanip>
#include <boost/core/ignore_unused.hpp>
#include <boost/foreach.hpp>
#include <boost/variant/variant.hpp>
@@ -47,10 +46,6 @@ check_result(
{
bool const is_line = bg::geometry_id<OutputType>::type::value == 2;
typedef typename bg::coordinate_type<G1>::type coordinate_type;
typedef typename bg::point_type<G1>::type point_type;
boost::ignore_unused<coordinate_type, point_type>();
typename bg::default_area_result<G1>::type length_or_area = 0;
int n = 0;
for (typename std::vector<OutputType>::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<G1>::value == bg::counterclockwise
|| bg::point_order<G2>::value == bg::counterclockwise;
bool const open =
bg::closure<G1>::value == bg::open
|| bg::closure<G2>::value == bg::open;
std::ostringstream filename;
filename << "intersection_"
<< caseid << "_"
<< string_from_type<coordinate_type>::name()
<< string_from_type<CalculationType>::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<point_type> 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<OutputType>::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<G1>::type test_intersection(std::string const&
check_result<G1, G2>(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<OutputType>::type::value == 2;
typedef typename bg::coordinate_type<G1>::type coordinate_type;
bool const ccw =
bg::point_order<G1>::value == bg::counterclockwise
|| bg::point_order<G2>::value == bg::counterclockwise;
bool const open =
bg::closure<G1>::value == bg::open
|| bg::closure<G2>::value == bg::open;
std::ostringstream filename;
filename << "intersection_"
<< caseid << "_"
<< string_from_type<coordinate_type>::name()
<< string_from_type<CalculationType>::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<point_type> 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<OutputType>::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;

View File

@@ -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<bg::model::polygon<P, true, false> > omp;
test_geometry<omp>
(
"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* [] )