[Boost-bugs] [Boost C++ Libraries] #10646: polygon::iterator_compact_to_points returns wrong equality for the (last & penultimate) iterators

Subject: [Boost-bugs] [Boost C++ Libraries] #10646: polygon::iterator_compact_to_points returns wrong equality for the (last & penultimate) iterators
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-10-10 21:33:32


#10646: polygon::iterator_compact_to_points returns wrong equality for the (last &
penultimate) iterators
---------------------------------------------------+----------------------
 Reporter: Vadim Sukhorukov <vadim.sukhorukov@…> | Owner: ljsimons
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: polygon
  Version: Boost 1.49.0 | Severity: Problem
 Keywords: |
---------------------------------------------------+----------------------
 ''iterator_compact_to_points'' is the part of ''polygon_90'' concept.

 ''polygon_90_data'' class exposes 2 iterators: ''compact_iterator_type''
 and ''iterator_type''. ''iterator_type'' extracts the complete point on-
 the-fly. And for the penultimate iterator it makes the wromg comparison
 with the last iterator.

 The reason of this bug is the specific implementation of operator++().
 This is the same in boost versions 1.49 .. 1.56.

 At the moment I can propose the following workaround:

 {{{
 typedef gtl::polygon_90_data<int> Polygon90;
 typedef gtl::polygon_traits_90<Polygon90>::point_type Point;
 typedef Polygon90::iterator_type Polygon90Iterator;

 bool equalIterators(const Polygon90Iterator& left, const
 Polygon90Iterator& right)
 {
   if (left == right)
   {
     return ((*left) == (*right));
   }
   else
   {
     return false;
   }
 }
 }}}

 The implementation of operator++() [taken from boost sources]:
 {{{
 inline iterator_compact_to_points& operator++() {
     iterator_type prev_iter = iter_;
     ++iter_;
     if(iter_ == iter_end_) {
       if(x(pt_) != firstX_) {
         iter_ = prev_iter; // this line produces the issue
         x(pt_, firstX_);
       } // it changes the cached point, but rolls back the iterator
     } else {
       set(pt_, orient_, *iter_);
       orient_.turn_90();
     }
     return *this;
   }
 }}}

 The testing code:
 {{{
 #include <boost/polygon/polygon.hpp>
 namespace gtl = boost::polygon;

 #include <vector>

 typedef gtl::polygon_90_data<int> Polygon90;
 typedef gtl::polygon_traits_90<Polygon90>::point_type Point;
 typedef Polygon90::iterator_type Polygon90Iterator;

   std::vector<Point> polygonData;
   polygonData.push_back(Point(15, 07)); // 1
   polygonData.push_back(Point(20, 07)); // 2
   polygonData.push_back(Point(20, 05)); // 3
   polygonData.push_back(Point(16, 05)); // 4
   polygonData.push_back(Point(16, 01)); // 5
   polygonData.push_back(Point(01, 01)); // 6
   polygonData.push_back(Point(01, 06)); // 7
   polygonData.push_back(Point(03, 06)); // 8
   polygonData.push_back(Point(03, 10)); // 9
   polygonData.push_back(Point(05, 10)); // 10

   Polygon90 polygon90;
   polygon90.set(polygonData.begin(), polygonData.end());

   Polygon90Iterator it = polygon90.begin();
   for (int i = 0; i < 8; i++)
   {
     it++;
   }

   Polygon90Iterator it_9th = it;

   it++; // this one points to 10th element

   bool bug = (it == it_9th);
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/10646>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:17 UTC