Reputation: 647
I need to implement a class which is able iterator over container in the direction specified by parameter to class' constructor. Say that parameter is called direction.
My class will have method which will sometimes increment iterator depending on additional conditions not related to this question.
So my idea is to declare member field of type X which can contain return value of container's begin() or rbegin() method. That member filed will be initialized in the constructor.
But the question is what is type of X. I think I can implement wrapper classes providing common interface via virtual functions. But maybe there is standard implementation in standard library or in Boost?
Update: my setup is very well matches the code provided by @Rabbid76 in his answer. I cannot alter interface of struct Iterator
or remove this class. So my question is if it is possible to replace IteratorBase
/IteratorImpl
with something from standard libraries.
Upvotes: 2
Views: 157
Reputation: 211219
What about that:
template < typename T >
struct IteratorBase
{
using value_type = typename T::value_type;
virtual value_type& val() = 0;
virtual void next() = 0;
virtual bool end( T &container ) = 0;
};
template < typename T, bool reverse = false >
struct IteratorTempl : IteratorBase< T >
{
IteratorTempl( T &container ) : m_it( container.begin() ) {}
value_type& val() override { return *m_it; }
void next() override { m_it ++; }
bool end( T &container ) override { return m_it == container.end(); }
typename T::iterator m_it;
};
template < typename T >
struct IteratorTempl< T, true > : IteratorBase< T >
{
IteratorTempl( T &container ) : m_it( container.rbegin() ) {}
value_type& val() override { return *m_it; }
void next() override { m_it ++; }
bool end( T &container ) override { return m_it == container.rend(); }
typename T::reverse_iterator m_it;
};
template < typename T >
struct Iterator
{
using value_type = typename T::value_type;
Iterator( T &container, bool reverse )
{
if ( reverse )
m_it = new IteratorTempl<T, true>( container );
else
m_it = new IteratorTempl<T, false>( container );
}
~Iterator(){ delete m_it; }
value_type& val() { return m_it->val(); }
void next() { m_it->next(); }
bool end( T &container ) { return m_it->end( container ); }
IteratorBase<T> *m_it;
};
#include <vector>
int main()
{
std::vector<int> v{ 1,2,3,4,5 };
for ( int i = 0; i < 2; i ++ )
{
Iterator< std::vector<int> > it( v, i!=0 );
while ( !it.end(v) )
{
cout << it.val() << " ";
it.next();
}
}
return 0;
}
Upvotes: 2