mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-09 11:12:21 +00:00
[overlay][range] Replace the explicit call to Range::erase() with version using std::copy() and traits::resize<>
This commit is contained in:
@@ -15,6 +15,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 +110,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 const bool 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 +131,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, *boost::begin(range));
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
|
||||
@@ -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,110 @@ 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(). It requires mutable iterator as parameter.
|
||||
\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 a range of elements from a mutable range.
|
||||
It uses std::copy() and resize(). It requires mutable iterators as parameters.
|
||||
\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;
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::range
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_RANGE_HPP
|
||||
|
||||
Reference in New Issue
Block a user