views:

118

answers:

2

I'll often represent and process polylines like so:

typedef std::vector< Point_t > Polyline_t;

double PolylineLength(const Polyline_t& line)
{
    double len = 0.0;
    for( size_t i = 0; i < line.size()-1; ++i )
        len += (line[i+1]-line[i+0]).length();
    return len;
}

The most straightforward conversion to bidirectional iterators that I came up with is:

typedef std::list< Point_t > Polyline_t;
typedef Polyline_t::const_iterator Polyline_t_cit;

double PolylineLength(const Polyline_t& line)
{
    double len = 0.0;
    Polyline_t_cit last = line.end();
    last--;
    for( Polyline_t_cit i = line.begin(); i != last; ++i )
    {
        const Point_t& beg = *i;
        const Point_T& end = *(++i);
        len += (end - beg).length();
        --i;
    }
    return len;
}

Is there a more succinct way to express this sort of two-at-time processing with iterators?

+7  A: 

I would keep two iterators, and then check whether the second iterator has reached end. This will make it not require bidirectional iterators anymore:

typedef std::list< Point_t > Polyline_t;
typedef Polyline_t::const_iterator Polyline_t_cit;

double PolylineLength(const Polyline_t& line)
{
    double len = 0.0;
    Polyline_t_cit f = line.begin(), s(f), end = line.end();
    for(++s; s != end; ++f, ++s) {
        len += (*s - *f).length();
    }
    return len;
}
Johannes Schaub - litb
I think you need to test if line is empty else you'll have problems.
jon hanson
The original code has the same problem. So I assumed that the polygon object cannot be empty. But I agree with you that it's probably a good idea to handle empty line containers too.
Johannes Schaub - litb
+1  A: 

--i immediately before ++i - both are needless.

typedef std::list< Point_t > Polyline_t;
typedef Polyline_t::const_iterator Polyline_t_cit;

double PolylineLength(const Polyline_t& line)
{
    double len = 0.0;
    Polyline_t_cit last = line.end();
    last--;
    for( Polyline_t_cit i = line.begin(); i != last; )
    {
        const Point_t& beg = *i;
        const Point_T& end = *(++i);
        len += (end - beg).length();
    }
    return len;
}
pingw33n