mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-15 01:02:09 +00:00
Added ever_circling_range_iterator (range version)
Small adaptions to get_turns [SVN r62180]
This commit is contained in:
@@ -111,6 +111,12 @@ public :
|
||||
typename geometry::range_type<Geometry2>::type const
|
||||
>::type range2_iterator;
|
||||
|
||||
range1_iterator begin_range_1, end_range_1;
|
||||
get_full_section(geometry1, sec1, begin_range_1, end_range_1);
|
||||
|
||||
range2_iterator begin_range_2, end_range_2;
|
||||
get_full_section(geometry2, sec2, begin_range_2, end_range_2);
|
||||
|
||||
int const dir1 = sec1.directions[0];
|
||||
int const dir2 = sec2.directions[0];
|
||||
int index1 = sec1.begin_index;
|
||||
@@ -122,13 +128,18 @@ public :
|
||||
&& sec1.ring_index == sec2.ring_index;
|
||||
|
||||
range1_iterator prev1, it1, end1;
|
||||
range1_iterator begin_range_1, end_range_1;
|
||||
|
||||
ever_circling_iterator<range1_iterator> next1
|
||||
= start_at_section(sec1, prev1, it1, end1, begin_range_1, end_range_1,
|
||||
get_start_point_iterator(sec1, prev1, it1, end1,
|
||||
index1, ndi1, geometry1, dir1, sec2.bounding_box);
|
||||
|
||||
// We need a circular iterator because it might run through the closing point.
|
||||
// One circle is actually enough but this one is just convenient.
|
||||
ever_circling_iterator<range1_iterator> next1(begin_range_1, end_range_1, it1, true);
|
||||
next1++;
|
||||
|
||||
// Walk through section and stop if we exceed the other box
|
||||
// section 2: [--------------]
|
||||
// section 1: |----|---|---|---|---|
|
||||
for (prev1 = it1++, next1++;
|
||||
it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box);
|
||||
prev1 = it1++, index1++, next1++, ndi1++)
|
||||
@@ -141,11 +152,11 @@ public :
|
||||
int ndi2 = sec2.non_duplicate_index;
|
||||
|
||||
range2_iterator prev2, it2, end2;
|
||||
range2_iterator begin_range_2, end_range_2;
|
||||
|
||||
ever_circling_iterator<range2_iterator> next2 =
|
||||
start_at_section(sec2, prev2, it2, end2, begin_range_2, end_range_2,
|
||||
get_start_point_iterator(sec2, prev2, it2, end2,
|
||||
index2, ndi2, geometry2, dir2, sec1.bounding_box);
|
||||
ever_circling_iterator<range2_iterator> next2(begin_range_2, end_range_2, it2, true);
|
||||
next2++;
|
||||
|
||||
for (prev2 = it2++, next2++;
|
||||
it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box);
|
||||
@@ -264,9 +275,8 @@ private :
|
||||
// skips to the begin-point, we loose the index or have to recalculate it)
|
||||
// So we mimic it here
|
||||
template <typename RangeIterator, typename Section, typename Geometry, typename Box>
|
||||
static inline ever_circling_iterator<RangeIterator> start_at_section(Section & section,
|
||||
static inline RangeIterator get_start_point_iterator(Section & section,
|
||||
RangeIterator& it, RangeIterator& prev, RangeIterator& end,
|
||||
RangeIterator& begin_range_it, RangeIterator& end_range_it,
|
||||
int& index, int& ndi,
|
||||
Geometry const& geometry,
|
||||
int dir, Box const& other_bounding_box)
|
||||
@@ -281,12 +291,7 @@ private :
|
||||
{}
|
||||
// Go back one step because we want to start completely preceding
|
||||
it = prev;
|
||||
|
||||
get_full_section(geometry, section, begin_range_it, end_range_it);
|
||||
|
||||
ever_circling_iterator<RangeIterator> next(begin_range_it, end_range_it, it, true);
|
||||
next++;
|
||||
return next;
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
@@ -90,6 +91,69 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Range>
|
||||
class ever_circling_range_iterator
|
||||
: public boost::iterator_adaptor
|
||||
<
|
||||
ever_circling_range_iterator<Range>,
|
||||
typename boost::range_iterator<Range>::type
|
||||
>
|
||||
{
|
||||
public :
|
||||
typedef typename boost::range_iterator<Range>::type iterator_type;
|
||||
|
||||
explicit inline ever_circling_range_iterator(Range& range,
|
||||
bool skip_first = false)
|
||||
: m_range(range)
|
||||
, m_skip_first(skip_first)
|
||||
{
|
||||
this->base_reference() = boost::begin(m_range);
|
||||
}
|
||||
|
||||
explicit inline ever_circling_range_iterator(Range& range, iterator_type start,
|
||||
bool skip_first = false)
|
||||
: m_range(range)
|
||||
, m_skip_first(skip_first)
|
||||
{
|
||||
this->base_reference() = start;
|
||||
}
|
||||
|
||||
/// Navigate to a certain position, should be in [start .. end], if at end
|
||||
/// it will circle again.
|
||||
inline void moveto(iterator_type it)
|
||||
{
|
||||
this->base_reference() = it;
|
||||
check_end();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
inline void increment(bool possibly_skip = true)
|
||||
{
|
||||
(this->base_reference())++;
|
||||
check_end(possibly_skip);
|
||||
}
|
||||
|
||||
inline void check_end(bool possibly_skip = true)
|
||||
{
|
||||
if (this->base_reference() == boost::end(m_range))
|
||||
{
|
||||
this->base_reference() = boost::begin(m_range);
|
||||
if (m_skip_first && possibly_skip)
|
||||
{
|
||||
increment(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Range& m_range;
|
||||
bool m_skip_first;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
|
||||
|
||||
Reference in New Issue
Block a user