Subject: [Boost-bugs] [Boost C++ Libraries] #11287: adaptors: strided does not support input iterators
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-05-12 08:08:18
#11287: adaptors: strided does not support input iterators
---------------------------------------------+------------------------
Reporter: Akim Demaille <akim.demaille@â¦> | Owner: neilgroves
Type: Bugs | Status: new
Milestone: To Be Determined | Component: range
Version: Boost 1.58.0 | Severity: Problem
Keywords: |
---------------------------------------------+------------------------
Hi,
Despite what the documentation says, the stride adaptor does not support
input iterators. This is a pity, since for instance its applicability to
iterators to coroutines: see #11274.
Oliver Kowalke tracked down the issue, and built a small scale example
that shows the problem: see http://lists.boost.org/boost-
users/2015/05/84277.php. The example is repeated below:
{{{
#include <iostream>
#include <iterator>
#include <vector>
#include <boost/range.hpp>
#include <boost/range/adaptor/strided.hpp>
namespace foo {
template< typename T >
class X {
private:
typedef std::vector< T > vec_t;
vec_t vec_;
public:
X( vec_t const& vec) :
vec_( vec) {
}
class iterator : public std::iterator< std::input_iterator_tag, T >
{
private:
X * x_;
typename vec_t::iterator i_;
public:
typedef typename iterator::pointer pointer_t;
typedef typename iterator::reference reference_t;
iterator() :
x_( 0), i_()
{}
explicit iterator( X * x) :
x_( x), i_( x_->vec_.begin() )
{}
iterator( iterator const& other) :
x_( other.x_), i_( other.i_)
{}
iterator & operator=( iterator const& other) {
if ( this == & other) return * this;
x_ = other.x_;
i_ = other.i_;
return * this;
}
bool operator==( iterator const& other) const
{ return other.x_ == x_ && other.i_ == i_; }
bool operator!=( iterator const& other) const
{ return other.x_ != x_ || other.i_ != i_; }
iterator & operator++() {
++i_;
return * this;
}
iterator operator++( int) {
i_++;
return * this;
}
reference_t operator*() const
{ return * i_; }
pointer_t operator->() const
{ return & ( * i_); }
};
class const_iterator : public std::iterator< std::input_iterator_tag,
const T >
{
private:
X * x_;
typename vec_t::const_iterator i_;
public:
typedef typename iterator::pointer pointer_t;
typedef typename iterator::reference reference_t;
const_iterator() :
x_( 0), i_()
{}
explicit const_iterator( X * x) :
x_( x), i_( x_->vec_.begin() )
{}
const_iterator( const_iterator const& other) :
x_( other.x_), i_( other.i_)
{}
const_iterator & operator=( const_iterator const& other) {
if ( this == & other) return * this;
x_ = other.x_;
i_ = other.i_;
return * this;
}
bool operator==( const_iterator const& other) const
{ return other.x_ == x_ && other.i_ == i_; }
bool operator!=( const_iterator const& other) const
{ return other.x_ != x_ || other.i_ != i_; }
const_iterator & operator++() {
++i_;
return * this;
}
const_iterator operator++( int) {
i_++;
return * this;
}
reference_t operator*() const
{ return * i_; }
pointer_t operator->() const
{ return & ( * i_); }
};
friend class iterator;
friend class const_iterator;
};
template< typename T >
typename X< T >::iterator
range_begin( X< T > & c)
{ return typename X< T >::iterator( & c); }
template< typename T >
typename X< T >::const_iterator
range_begin( X< T > const& c)
{ return typename X< T >::const_iterator( & c); }
template< typename T >
typename X< T >::iterator
range_end( X< T > &)
{ return typename X< T >::iterator(); }
template< typename T >
typename X< T >::const_iterator
range_end( X< T > const&)
{ return typename X< T >::const_iterator(); }
template< typename T >
typename X< T >::iterator
begin( X< T > & c)
{ return boost::begin( c); }
template< typename T >
typename X< T >::const_iterator
begin( X< T > const& c)
{ return boost::begin( c); }
template< typename T >
typename X< T >::iterator
end( X< T > & c)
{ return boost::end( c); }
template< typename T >
typename X< T >::const_iterator
end( X< T > const& c)
{ return boost::end( c); }
}
namespace boost {
template< typename T >
struct range_mutable_iterator< foo::X< T > >
{ typedef typename foo::X< T >::iterator type; };
template< typename T >
struct range_const_iterator< foo::X< T > >
{ typedef typename foo::X< T >::const_iterator type; };
}
int main()
{
std::vector< int > vec = { 1,2,3,4,5,6,7,8,9,10 };
auto x = foo::X< int >( vec);
for (auto i : x | boost::adaptors::strided( 2) )
std::cout << i << " ";
std::cout << '\n';
}
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11287> 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:18 UTC