mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-14 00:42:09 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into feature/is_simple
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
143
test/util/range.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user