Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62180 - in sandbox/geometry: boost/geometry/algorithms/detail/overlay boost/geometry/iterators libs/geometry libs/geometry/test/iterators
From: barend.gehrels_at_[hidden]
Date: 2010-05-24 16:52:38


Author: barendgehrels
Date: 2010-05-24 16:52:33 EDT (Mon, 24 May 2010)
New Revision: 62180
URL: http://svn.boost.org/trac/boost/changeset/62180

Log:
Added ever_circling_range_iterator (range version)
Small adaptions to get_turns
Text files modified:
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_turns.hpp | 33 +++++++++++--------
   sandbox/geometry/boost/geometry/iterators/ever_circling_iterator.hpp | 64 ++++++++++++++++++++++++++++++++++++++++
   sandbox/geometry/libs/geometry/Jamroot | 1
   sandbox/geometry/libs/geometry/test/iterators/ever_circling_iterator.cpp | 12 ++++++
   4 files changed, 95 insertions(+), 15 deletions(-)

Modified: sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_turns.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_turns.hpp (original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/get_turns.hpp 2010-05-24 16:52:33 EDT (Mon, 24 May 2010)
@@ -111,6 +111,12 @@
                 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 @@
                     && 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 @@
             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 @@
     // 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 @@
         {}
         // 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;
     }
 };
 

Modified: sandbox/geometry/boost/geometry/iterators/ever_circling_iterator.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/iterators/ever_circling_iterator.hpp (original)
+++ sandbox/geometry/boost/geometry/iterators/ever_circling_iterator.hpp 2010-05-24 16:52:33 EDT (Mon, 24 May 2010)
@@ -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 @@
 };
 
 
+
+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

Modified: sandbox/geometry/libs/geometry/Jamroot
==============================================================================
--- sandbox/geometry/libs/geometry/Jamroot (original)
+++ sandbox/geometry/libs/geometry/Jamroot 2010-05-24 16:52:33 EDT (Mon, 24 May 2010)
@@ -13,4 +13,5 @@
         <include>../..
         <toolset>gcc:<cxxflags>"-pedantic -Wall -Wstrict-aliasing -fstrict-aliasing -Wno-long-long"
         <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE # For Ublas
+ <dependency>/boost//headers
     ;

Modified: sandbox/geometry/libs/geometry/test/iterators/ever_circling_iterator.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/iterators/ever_circling_iterator.cpp (original)
+++ sandbox/geometry/libs/geometry/test/iterators/ever_circling_iterator.cpp 2010-05-24 16:52:33 EDT (Mon, 24 May 2010)
@@ -22,7 +22,7 @@
 {
     G geo;
     boost::geometry::read_wkt(wkt, geo);
- typedef typename boost::range_const_iterator<G>::type iterator_type;
+ typedef typename boost::range_iterator<G const>::type iterator_type;
 
 
     // Run 3 times through the geometry
@@ -64,6 +64,16 @@
         BOOST_CHECK_EQUAL(out.str(), "543215432154321");
     }
 
+ // Check the range_iterator-one
+ {
+ std::ostringstream out;
+ boost::geometry::ever_circling_range_iterator<G> it(geo);
+ for (int i = 0; i < n; ++i, ++it)
+ {
+ out << boost::geometry::get<0>(*it);
+ }
+ BOOST_CHECK_EQUAL(out.str(), "123451234512345");
+ }
 }
 
 template <typename P>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk