|
Boost : |
From: nbecker_at_[hidden]
Date: 2002-01-29 14:56:32
Interesting. Here's what I came up with. So far, it is an iterator
adaptor, that adapts a container's iterator. Typically, the container
would be vector or plain old array.
#include <boost/iterator_adaptors.hpp>
using namespace boost;
struct circ_iterator_policies : public default_iterator_policies {
circ_iterator_policies (int _size, int _offset = 0) :
size (_size), offset (_offset) {}
template <class IteratorAdaptor>
typename IteratorAdaptor::reference
dereference(const IteratorAdaptor& iter) const
{ return *(iter.base() + iter.policies().index (offset)); }
template <class IteratorAdaptor>
void increment(IteratorAdaptor& x)
{ ++x.policies().offset; }
template <class IteratorAdaptor>
void decrement(IteratorAdaptor& x)
{ --x.policies().offset; }
template <class IteratorAdaptor, class DifferenceType>
void advance(IteratorAdaptor& x, DifferenceType n)
{ x.policies().offset += n; }
template <class IteratorAdaptor1, class IteratorAdaptor2>
typename IteratorAdaptor1::difference_type
distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
{
typedef typename IteratorAdaptor1::difference_type ret_t;
ret_t ret = (y.base() + y.policies().offset) - (x.base() + x.policies().offset);
if (ret < 0)
ret += x.policies().size;
return ret;
}
template <class IteratorAdaptor1, class IteratorAdaptor2>
bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
{ return x.base() + x.policies().index (x.policies().offset) ==
y.base() + y.policies().index (y.policies().offset); }
int size;
int offset;
int index (int offset) const {
int x = (offset) % int(size);
if (x >= 0)
return x;
else
return x + size;
}
};
template<typename Iterator>
struct circ_iterator_generator {
typedef typename Iterator::value_type value_t;
typedef iterator_adaptor<
Iterator,
circ_iterator_policies,
value_t, value_t&, value_t*, std::random_access_iterator_tag>
type;
};
template <typename Iterator>
typename circ_iterator_generator<Iterator>::type
make_circ_iterator(Iterator i, int size, int offset)
{
typedef typename circ_iterator_generator<Iterator>::type result_t;
return result_t (i, circ_iterator_policies (size, offset));
}
Here's a test:
#include "fifo.H"
#include <vector>
#include <iostream>
int main () {
const int size = 10;
std::vector<int> v (size+1);
for (int i = 0; i < v.size(); i++)
v[i] = i;
std::cout << "make_circ_iterator (v.begin(), size, 2)-make_circ_iterator (v.begin(), size, 1)=" << make_circ_iterator (v.begin(), size, 2) - make_circ_iterator (v.begin(), size, 1) << '\n'
<< "make_circ_iterator (v.begin(), size, 1)-make_circ_iterator (v.begin(), size, 2)=" << make_circ_iterator (v.begin(), size, 1) - make_circ_iterator (v.begin(), size, 2) << '\n';
std::copy (make_circ_iterator (v.begin(), size, 2), make_circ_iterator (v.begin(), size, 1), std::ostream_iterator<int> (std::cout, "\n"));
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk