Merge branch 'develop' of https://github.com/boostorg/geometry into feature/is_simple

This commit is contained in:
Menelaos Karavelas
2014-06-20 12:30:18 +03:00
14 changed files with 372 additions and 249 deletions

View File

@@ -297,7 +297,7 @@ struct buffered_piece_collection
{
typename buffer_occupation_info::turn_vector_type const& turns = it->second.turns;
bool blocked = false;
for (int i = 0; i < turns.size(); i++)
for (std::size_t i = 0; i < turns.size(); i++)
{
if (m_turns[turns[i].turn_index].blocked())
{
@@ -307,7 +307,7 @@ struct buffered_piece_collection
}
if (blocked)
{
for (int i = 0; i < turns.size(); i++)
for (std::size_t i = 0; i < turns.size(); i++)
{
m_turns[turns[i].turn_index].count_on_occupied++;
}
@@ -320,7 +320,7 @@ struct buffered_piece_collection
it != occupation_map.end(); ++it)
{
typename buffer_occupation_info::turn_vector_type const& turns = it->second.turns;
for (int i = 0; i < turns.size(); i++)
for (std::size_t i = 0; i < turns.size(); i++)
{
m_turns[turns[i].turn_index].selectable_start = false;
}

View File

@@ -132,8 +132,8 @@ template<typename Pieces>
inline void move_index(Pieces const& pieces, int& index, int& piece_index, int direction)
{
BOOST_ASSERT(direction == 1 || direction == -1);
BOOST_ASSERT(piece_index >= 0 && piece_index < boost::size(pieces));
BOOST_ASSERT(index >= 0 && index < boost::size(pieces[piece_index].robust_ring));
BOOST_ASSERT(piece_index >= 0 && piece_index < static_cast<int>(boost::size(pieces)) );
BOOST_ASSERT(index >= 0 && index < static_cast<int>(boost::size(pieces[piece_index].robust_ring)));
index += direction;
if (direction == -1 && index < 0)
@@ -145,10 +145,11 @@ inline void move_index(Pieces const& pieces, int& index, int& piece_index, int d
}
index = boost::size(pieces[piece_index].robust_ring) - 1;
}
if (direction == 1 && index >= boost::size(pieces[piece_index].robust_ring))
if (direction == 1
&& index >= static_cast<int>(boost::size(pieces[piece_index].robust_ring)))
{
piece_index++;
if (piece_index >= boost::size(pieces))
if (piece_index >= static_cast<int>(boost::size(pieces)))
{
piece_index = 0;
}

View File

@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// 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)
@@ -15,6 +20,8 @@
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
{
@@ -108,7 +115,11 @@ inline void clean_closing_dups_and_spikes(Range& range,
}
typedef typename boost::range_iterator<Range>::type iterator_type;
const bool closed = geometry::closure<Range>::value == geometry::closed;
static bool const closed = geometry::closure<Range>::value == geometry::closed;
// TODO: the following algorithm could be rewritten to first look for spikes
// and then erase some number of points from the beginning of the Range
bool found = false;
do
{
@@ -125,13 +136,13 @@ inline void clean_closing_dups_and_spikes(Range& range,
// considered as a spike w.r.t. the last segment)
if (point_is_spike_or_equal(*second, *ultimate, *first, robust_policy))
{
range.erase(first);
range::erase(range, first);
if (closed)
{
// Remove closing last point
traits::resize<Range>::apply(range, boost::size(range) - 1);
range::resize(range, boost::size(range) - 1);
// Add new closing point
traits::push_back<Range>::apply(range, *boost::begin(range));
range::push_back(range, range::front(range));
}
found = true;
}

View File

@@ -29,7 +29,6 @@
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_relative_order.hpp>
#include <boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp>
#include <boost/geometry/algorithms/detail/zoom_to_robust.hpp>
#include <boost/geometry/policies/robustness/robust_type.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
# include <boost/geometry/algorithms/detail/overlay/check_enrich.hpp>
@@ -77,6 +76,7 @@ template
typename TurnPoints,
typename Indexed,
typename Geometry1, typename Geometry2,
typename RobustPolicy,
bool Reverse1, bool Reverse2,
typename Strategy
>
@@ -85,11 +85,13 @@ struct sort_on_segment_and_ratio
inline sort_on_segment_and_ratio(TurnPoints const& turn_points
, Geometry1 const& geometry1
, Geometry2 const& geometry2
, RobustPolicy const& robust_policy
, Strategy const& strategy
, bool* clustered)
: m_turn_points(turn_points)
, m_geometry1(geometry1)
, m_geometry2(geometry2)
, m_robust_policy(robust_policy)
, m_strategy(strategy)
, m_clustered(clustered)
{
@@ -100,25 +102,26 @@ private :
TurnPoints const& m_turn_points;
Geometry1 const& m_geometry1;
Geometry2 const& m_geometry2;
RobustPolicy const& m_robust_policy;
Strategy const& m_strategy;
mutable bool* m_clustered;
typedef model::point
<
typename detail::robust_type
<
typename select_coordinate_type<Geometry1, Geometry2>::type
>::type,
geometry::dimension<Geometry1>::value,
typename geometry::coordinate_system<Geometry1>::type
> robust_point_type;
typedef typename geometry::point_type<Geometry1>::type point_type;
typedef typename geometry::robust_point_type
<
point_type,
RobustPolicy
>::type robust_point_type;
// TODO: this function is shared with handle_tangencies
// The one in handle_tangencies will go as soon as we have
// reliable "cluster_info" (using occupation_map, get_left_turns)
inline void get_situation_map(Indexed const& left, Indexed const& right,
robust_point_type& pi_rob, robust_point_type& pj_rob,
robust_point_type& ri_rob, robust_point_type& rj_rob,
robust_point_type& si_rob, robust_point_type& sj_rob) const
{
typename geometry::point_type<Geometry1>::type pi, pj, ri, rj, si, sj;
point_type pi, pj, ri, rj, si, sj;
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
left.subject.seg_id,
@@ -129,8 +132,13 @@ private :
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
right.subject.other_id,
si, sj);
detail::zoom_to_robust(pi, pj, ri, rj, si, sj,
pi_rob, pj_rob, ri_rob, rj_rob, si_rob, sj_rob);
geometry::recalculate(pi_rob, pi, m_robust_policy);
geometry::recalculate(pj_rob, pj, m_robust_policy);
geometry::recalculate(ri_rob, ri, m_robust_policy);
geometry::recalculate(rj_rob, rj, m_robust_policy);
geometry::recalculate(si_rob, si, m_robust_policy);
geometry::recalculate(sj_rob, sj, m_robust_policy);
}
inline bool consider_relative_order(Indexed const& left,
@@ -162,6 +170,9 @@ public :
{
// First check "real" intersection (crosses)
// -> distance zero due to precision, solve it by sorting
// TODO: reconsider this. Using integer maths, this will
// ALWAYS return 0 because either fractions are different, or
// the (currently calculated) relative-order is identical
if (m_turn_points[left.index].method == method_crosses
&& m_turn_points[right.index].method == method_crosses)
{
@@ -171,8 +182,6 @@ public :
// If that is not the case, cluster it later on.
// Indicate that this is necessary.
*m_clustered = true;
return left.subject.fraction < right.subject.fraction;
}
}
return sl == sr
@@ -235,9 +244,10 @@ inline void enrich_sort(Container& operations,
TurnPoints,
IndexType,
Geometry1, Geometry2,
RobustPolicy,
Reverse1, Reverse2,
Strategy
>(turn_points, geometry1, geometry2, strategy, &clustered));
>(turn_points, geometry1, geometry2, robust_policy, strategy, &clustered));
// DONT'T discard xx / (for union) ix / ii / (for intersection) ux / uu here
// It would give way to "lonely" ui turn points, traveling all

View File

@@ -19,7 +19,6 @@
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#include <boost/geometry/policies/robustness/robust_type.hpp>
#include <boost/geometry/algorithms/detail/zoom_to_robust.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES)
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
@@ -71,16 +70,13 @@ private :
typedef typename Indexed::type turn_operation_type;
typedef typename geometry::point_type<Geometry1>::type point_type;
typedef model::point
typedef typename geometry::robust_point_type
<
typename detail::robust_type
<
typename select_coordinate_type<Geometry1, Geometry2>::type
>::type,
geometry::dimension<Geometry1>::value,
typename geometry::coordinate_system<Geometry1>::type
> robust_point_type;
point_type,
RobustPolicy
>::type robust_point_type;
// TODO: this function is shared with enrich_intersection_points
// Still called by #case_102_multi, #case_107_multi
// #case_recursive_boxes_3
inline void get_situation_map(Indexed const& left, Indexed const& right,
@@ -88,7 +84,6 @@ private :
robust_point_type& ri_rob, robust_point_type& rj_rob,
robust_point_type& si_rob, robust_point_type& sj_rob) const
{
typedef typename geometry::point_type<Geometry1>::type point_type;
point_type pi, pj, ri, rj, si, sj;
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,

View File

@@ -1,180 +0,0 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2013 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013 Bruno Lalande, Paris, France.
// Copyright (c) 2013 Mateusz Loskot, London, UK.
// Copyright (c) 2013 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_ALGORITHMS_DETAIL_ZOOM_TO_ROBUST_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ZOOM_TO_ROBUST_HPP
#include <cstddef>
#include <boost/type_traits.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/algorithms/detail/get_max_size.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/policies/robustness/rescale_policy.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename IsFloatingPoint>
struct zoom_to_robust
{
template
<
typename Geometry1, typename Geometry2, typename Geometry3,
typename Geometry4, typename Geometry5, typename Geometry6,
typename GeometryOut
>
static inline void apply(Geometry1 const& g1, Geometry2 const& g2, Geometry3 const& g3,
Geometry4 const& g4, Geometry5 const& g5, Geometry6 const& g6,
GeometryOut& og1, GeometryOut& og2, GeometryOut& og3,
GeometryOut& og4, GeometryOut& og5, GeometryOut& og6)
{
// By default, just convert these geometries (until now: points or maybe segments)
geometry::convert(g1, og1);
geometry::convert(g2, og2);
geometry::convert(g3, og3);
geometry::convert(g4, og4);
geometry::convert(g5, og5);
geometry::convert(g6, og6);
}
};
template <>
struct zoom_to_robust<boost::true_type>
{
template
<
typename Geometry1, typename Geometry2, typename Geometry3,
typename Geometry4, typename Geometry5, typename Geometry6,
typename GeometryOut
>
static inline void apply(Geometry1 const& g1, Geometry2 const& g2, Geometry3 const& g3,
Geometry4 const& g4, Geometry5 const& g5, Geometry6 const& g6,
GeometryOut& og1, GeometryOut& og2, GeometryOut& og3,
GeometryOut& og4, GeometryOut& og5, GeometryOut& og6)
{
typedef typename point_type<Geometry1>::type point1_type;
// Get the envelop of inputs
model::box<point1_type> env;
geometry::assign_inverse(env);
geometry::expand(env, g1);
geometry::expand(env, g2);
geometry::expand(env, g3);
geometry::expand(env, g4);
geometry::expand(env, g5);
geometry::expand(env, g6);
// Scale this to integer-range
typename geometry::coordinate_type<point1_type>::type diff = detail::get_max_size(env);
double range = 1000000000.0; // Define a large range to get precise integer coordinates
double factor = double(boost::long_long_type(range / double(diff)));
// Assign input/output minimal points
point1_type min_point1;
detail::assign_point_from_index<0>(env, min_point1);
typedef typename point_type<GeometryOut>::type point2_type;
point2_type min_point2;
assign_values(min_point2, boost::long_long_type(-range/2.0), boost::long_long_type(-range/2.0));
detail::robust_policy<point1_type, point2_type, double> strategy(min_point1, min_point2, factor);
geometry::recalculate(og1, g1, strategy);
geometry::recalculate(og2, g2, strategy);
geometry::recalculate(og3, g3, strategy);
geometry::recalculate(og4, g4, strategy);
geometry::recalculate(og5, g5, strategy);
geometry::recalculate(og6, g6, strategy);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename Geometry1, typename Geometry2>
inline void zoom_to_robust(Geometry1 const& g1a, Geometry1 const& g1b, Geometry2& g2a, Geometry2& g2b)
{
typedef typename point_type<Geometry1>::type point1_type;
typedef typename point_type<Geometry2>::type point2_type;
point1_type min_point1;
point2_type min_point2;
// Get the envelop of inputs
model::box<point1_type> env;
geometry::envelope(g1a, env);
geometry::expand(env, g1b);
// Scale this to integer-range
typename coordinate_type<point1_type>::type diff = detail::get_max_size(env);
double range = 1000000000.0; // Define a large range to get precise integer coordinates
double factor = range / diff;
// Assign input/output minimal points
detail::assign_point_from_index<0>(env, min_point1);
assign_values(min_point2, boost::long_long_type(-range/2.0), boost::long_long_type(-range/2.0));
detail::robust_policy<point1_type, point2_type, double> strategy(min_point1, min_point2, factor);
geometry::recalculate(g2a, g1a, strategy);
geometry::recalculate(g2b, g1b, strategy);
}
template
<
typename Geometry1, typename Geometry2, typename Geometry3,
typename Geometry4, typename Geometry5, typename Geometry6,
typename GeometryOut
>
void zoom_to_robust(Geometry1 const& g1, Geometry2 const& g2, Geometry3 const& g3,
Geometry4 const& g4, Geometry5 const& g5, Geometry6 const& g6,
GeometryOut& og1, GeometryOut& og2, GeometryOut& og3,
GeometryOut& og4, GeometryOut& og5, GeometryOut& og6)
{
// Make FP robust (so dispatch to true), so float and double
// Other types as int, boost::rational, or ttmath are considered to be already robust
dispatch::zoom_to_robust
<
typename boost::is_floating_point
<
typename geometry::coordinate_type<Geometry1>::type
>::type
>::apply(g1, g2, g3, g4, g5, g6, og1, og2, og3, og4, og5, og6);
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ZOOM_TO_ROBUST_HPP

View File

@@ -12,14 +12,16 @@
#ifndef BOOST_GEOMETRY_POLICIES_ROBUSTNESS_ROBUST_POINT_TYPE_HPP
#define BOOST_GEOMETRY_POLICIES_ROBUSTNESS_ROBUST_POINT_TYPE_HPP
#include <boost/geometry/algorithms/not_implemented.hpp>
namespace boost { namespace geometry
{
// Meta-function to typedef a robust point type for a policy
template <typename Point, typename Policy>
struct robust_point_type {}; //: not_implemented<> {};
struct robust_point_type
{
// By default, the point itself is the robust type
typedef Point type;
};
}} // namespace boost::geometry

View File

@@ -29,7 +29,7 @@ public :
template <typename Point>
inline CoordinateType apply(Point const& , Point const& ,
buffer_side_selector side) const
buffer_side_selector ) const
{
return m_distance;
}

View File

@@ -14,6 +14,9 @@
#ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
#include <algorithm>
#include <boost/assert.hpp>
#include <boost/concept_check.hpp>
#include <boost/range/concepts.hpp>
#include <boost/range/begin.hpp>
@@ -21,6 +24,8 @@
#include <boost/range/empty.hpp>
#include <boost/range/size.hpp>
#include <boost/geometry/core/mutable_range.hpp>
namespace boost { namespace geometry { namespace range {
// NOTE: For SinglePassRanges at could iterate over all elements until the i-th element is met.
@@ -105,6 +110,158 @@ back(BidirectionalRange & rng)
return *(--boost::end(rng));
}
/*!
\brief Short utility to conveniently clear a mutable range.
It uses traits::clear<>.
\ingroup utility
*/
template <typename Range>
inline void clear(Range & rng)
{
// NOTE: this trait is probably not needed since it could be implemented using resize()
geometry::traits::clear<Range>::apply(rng);
}
/*!
\brief Short utility to conveniently insert a new element at the end of a mutable range.
It uses boost::geometry::traits::push_back<>.
\ingroup utility
*/
template <typename Range>
inline void push_back(Range & rng,
typename boost::range_value<Range>::type const& value)
{
geometry::traits::push_back<Range>::apply(rng, value);
}
/*!
\brief Short utility to conveniently resize a mutable range.
It uses boost::geometry::traits::resize<>.
\ingroup utility
*/
template <typename Range>
inline void resize(Range & rng,
typename boost::range_size<Range>::type new_size)
{
geometry::traits::resize<Range>::apply(rng, new_size);
}
/*!
\brief Short utility to conveniently remove an element from the back of a mutable range.
It uses resize().
\ingroup utility
*/
template <typename Range>
inline void pop_back(Range & rng)
{
BOOST_ASSERT(!boost::empty(rng));
range::resize(rng, boost::size(rng) - 1);
}
/*!
\brief Short utility to conveniently remove an element from a mutable range.
It uses std::copy() and resize(). Version taking mutable iterators.
\ingroup utility
*/
template <typename Range>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
typename boost::range_iterator<Range>::type it)
{
BOOST_ASSERT(!boost::empty(rng));
BOOST_ASSERT(it != boost::end(rng));
typename boost::range_iterator<Range>::type
next = it;
++next;
std::copy(next, boost::end(rng), it);
range::resize(rng, boost::size(rng) - 1);
// NOTE: assuming that resize() doesn't invalidate the iterators
return it;
}
/*!
\brief Short utility to conveniently remove an element from a mutable range.
It uses std::copy() and resize(). Version taking non-mutable iterators.
\ingroup utility
*/
template <typename Range>
inline typename boost::range_iterator<Range const>::type
erase(Range & rng,
typename boost::range_iterator<Range const>::type cit)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
typename boost::range_iterator<Range>::type
it = boost::begin(rng)
+ std::distance(boost::const_begin(rng), cit);
erase(rng, it);
// NOTE: assuming that resize() doesn't invalidate the iterators
return cit;
}
/*!
\brief Short utility to conveniently remove a range of elements from a mutable range.
It uses std::copy() and resize(). Version taking mutable iterators.
\ingroup utility
*/
template <typename Range>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
typename boost::range_iterator<Range>::type first,
typename boost::range_iterator<Range>::type last)
{
typename std::iterator_traits
<
typename boost::range_iterator<Range>::type
>::difference_type const diff = std::distance(first, last);
BOOST_ASSERT(diff >= 0);
std::size_t const count = static_cast<std::size_t>(diff);
BOOST_ASSERT(count <= boost::size(rng));
if ( count > 0 )
{
std::copy(last, boost::end(rng), first);
range::resize(rng, boost::size(rng) - count);
}
// NOTE: assuming that resize() doesn't invalidate the iterators
return first;
}
/*!
\brief Short utility to conveniently remove a range of elements from a mutable range.
It uses std::copy() and resize(). Version taking non-mutable iterators.
\ingroup utility
*/
template <typename Range>
inline typename boost::range_iterator<Range const>::type
erase(Range & rng,
typename boost::range_iterator<Range const>::type cfirst,
typename boost::range_iterator<Range const>::type clast)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
typename boost::range_iterator<Range>::type
first = boost::begin(rng)
+ std::distance(boost::const_begin(rng), cfirst);
typename boost::range_iterator<Range>::type
last = boost::begin(rng)
+ std::distance(boost::const_begin(rng), clast);
erase(rng, first, last);
// NOTE: assuming that resize() doesn't invalidate the iterators
return cfirst;
}
}}} // namespace boost::geometry::range
#endif // BOOST_GEOMETRY_UTIL_RANGE_HPP

View File

@@ -311,9 +311,7 @@ void test_all()
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p6", rt_p6, 18.4853, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p7", rt_p7, 26.2279, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p8", rt_p8, 29.0563, 1.0);
#if !defined(_MSC_VER)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p9", rt_p9, 26.1421, 1.0);
#endif
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p10", rt_p10, 23.3995, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p11", rt_p11, 28.7426, 1.0);

View File

@@ -323,9 +323,6 @@ void test_buffer(std::string const& caseid, Geometry const& geometry,
typedef typename bg::coordinate_type<Geometry>::type coordinate_type;
typedef typename bg::point_type<Geometry>::type point_type;
typedef bg::strategy::buffer::distance_asymmetric<coordinate_type> distance;
typedef typename bg::ring_type<GeometryOut>::type ring_type;
typedef typename bg::tag<Geometry>::type tag;
// TODO use something different here:
@@ -509,8 +506,6 @@ void test_one(std::string const& caseid, std::string const& wkt,
Geometry g;
bg::read_wkt(wkt, g);
typedef typename bg::point_type<Geometry>::type point_type;
#ifdef BOOST_GEOMETRY_CHECK_WITH_POSTGIS
std::cout

View File

@@ -98,7 +98,6 @@ void test_all()
test_areal_linear<polygon, linestring>();
test_one<polygon, polygon, polygon>("simplex_normal",
simplex_normal[0], simplex_normal[1],
3, 12, 2.52636706856656,
@@ -327,29 +326,20 @@ void test_all()
1, 11, 3370866.2295081965,
1, 5, 384.2295081964694, 0.01);
#ifdef _MSC_VER
// 2011-07-02
// 2011-07-02 / 2014-06-19
// Interesting FP-precision case.
// sql server gives: 6.62295817619452E-05
// PostGIS gives: 0.0 (no output)
// Boost.Geometry gives results depending on FP-type, and compiler, and operating system.
// For double, it is zero (skipped). On gcc/Linux, for float either.
// Because we cannot predict this, we only test for MSVC
if (boost::is_same<ct, double>::value
#if defined(HAVE_TTMATH)
|| boost::is_same<ct, ttmath_big>::value
#endif
)
{
test_one<polygon, polygon, polygon>("ggl_list_20110627_phillip",
ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
if_typed_tt<ct>(1, 0), -1,
if_typed_tt<ct>(0.0000000000001105367, 0.0),
1, -1, 3577.40960816756,
0.01
);
}
#endif
// Boost.Geometry gave results depending on FP-type, and compiler, and operating system.
// Since rescaling to integer results are equal w.r.t. compiler/FP type,
// however, some long spikes are still generated in the resulting difference
test_one<polygon, polygon, polygon>("ggl_list_20110627_phillip",
ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
1, -1,
if_typed_tt<ct>(0.0000000000001105367, 0.00021401892),
1, -1, 3577.40960816756,
0.01
);
// Ticket 8310, one should be completely subtracted from the other.
test_one<polygon, polygon, polygon>("ticket_8310a",

View File

@@ -18,6 +18,7 @@ test-suite boost-geometry-util
[ run calculation_type.cpp ]
[ run for_each_coordinate.cpp ]
[ run math_sqrt.cpp ]
[ run range.cpp ]
[ run rational.cpp ]
[ run select_most_precise.cpp ]
[ run write_dsv.cpp ]

143
test/util/range.cpp Normal file
View File

@@ -0,0 +1,143 @@
// Boost.Geometry
// Unit Test
// 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)
#include <geometry_test_common.hpp>
#include <vector>
#include <boost/geometry/util/range.hpp>
namespace bgt {
template <bool MutableIterator>
struct beginner
{
template <typename Range>
typename boost::range_iterator<Range>::type
operator()(Range & rng)
{
return boost::begin(rng);
}
};
template <>
struct beginner<false>
{
template <typename Range>
typename boost::range_iterator<Range const>::type
operator()(Range & rng)
{
return boost::const_begin(rng);
}
};
template <bool MutableIterator>
struct ender
{
template <typename Range>
typename boost::range_iterator<Range>::type
operator()(Range & rng)
{
return boost::end(rng);
}
};
template <>
struct ender<false>
{
template <typename Range>
typename boost::range_iterator<Range const>::type
operator()(Range & rng)
{
return boost::const_end(rng);
}
};
} // namespace bgt
template <bool MutableIterator>
void test_all()
{
namespace bgr = bg::range;
bgt::beginner<MutableIterator> begin;
bgt::ender<MutableIterator> end;
std::vector<int> v;
for (int i = 0 ; i < 20 ; ++i)
{
bgr::push_back(v, i);
}
for (int i = 0 ; i < 20 ; ++i)
{
BOOST_CHECK(bgr::at(v, i) == i);
}
BOOST_CHECK(bgr::front(v) == 0);
BOOST_CHECK(bgr::back(v) == 19);
BOOST_CHECK(boost::size(v) == 20); // [0,19]
bgr::resize(v, 15);
BOOST_CHECK(boost::size(v) == 15); // [0,14]
BOOST_CHECK(bgr::back(v) == 14);
bgr::pop_back(v);
BOOST_CHECK(boost::size(v) == 14); // [0,13]
BOOST_CHECK(bgr::back(v) == 13);
bgr::erase(v, end(v) - 1);
BOOST_CHECK(boost::size(v) == 13); // [0,12]
BOOST_CHECK(bgr::back(v) == 12);
bgr::erase(v, end(v) - 3, end(v));
BOOST_CHECK(boost::size(v) == 10); // [0,9]
BOOST_CHECK(bgr::back(v) == 9);
bgr::erase(v, begin(v) + 2);
BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9}
BOOST_CHECK(bgr::at(v, 1) == 1);
BOOST_CHECK(bgr::at(v, 2) == 3);
BOOST_CHECK(bgr::back(v) == 9);
bgr::erase(v, begin(v) + 2, begin(v) + 2);
BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9}
BOOST_CHECK(bgr::at(v, 1) == 1);
BOOST_CHECK(bgr::at(v, 2) == 3);
BOOST_CHECK(bgr::back(v) == 9);
bgr::erase(v, begin(v) + 2, begin(v) + 5);
BOOST_CHECK(boost::size(v) == 6); // {0,1,6..9}
BOOST_CHECK(bgr::at(v, 1) == 1);
BOOST_CHECK(bgr::at(v, 2) == 6);
BOOST_CHECK(bgr::back(v) == 9);
bgr::erase(v, begin(v));
BOOST_CHECK(boost::size(v) == 5); // {1,6..9}
BOOST_CHECK(bgr::at(v, 0) == 1);
BOOST_CHECK(bgr::at(v, 1) == 6);
BOOST_CHECK(bgr::back(v) == 9);
bgr::erase(v, begin(v), begin(v) + 3);
BOOST_CHECK(boost::size(v) == 2); // {8,9}
BOOST_CHECK(bgr::at(v, 0) == 8);
BOOST_CHECK(bgr::at(v, 1) == 9);
BOOST_CHECK(bgr::back(v) == 9);
bgr::erase(v, begin(v), end(v));
BOOST_CHECK(boost::size(v) == 0);
}
int test_main(int, char* [])
{
test_all<true>();
test_all<false>();
return 0;
}