#include <boost/stl_interfaces/iterator_interface.hpp>
#include <algorithm>
#include <list>
#include <vector>
#include <cassert>
template<typename BidiIter>
struct reverse_iterator
: boost::stl_interfaces::iterator_interface<
reverse_iterator<BidiIter>,
#if 201703L < __cplusplus && defined(__cpp_lib_ranges)
typename std::iterator_traits<BidiIter>::iterator_concept,
#else
typename std::iterator_traits<BidiIter>::iterator_category,
#endif
typename std::iterator_traits<BidiIter>::value_type>
{
reverse_iterator() : it_() {}
reverse_iterator(BidiIter it) : it_(it) {}
using ref_t = typename std::iterator_traits<BidiIter>::reference;
using diff_t = typename std::iterator_traits<BidiIter>::difference_type;
ref_t operator*() const { return *std::prev(it_); }
bool operator==(reverse_iterator other) const { return it_ == other.it_; }
diff_t operator-(reverse_iterator other) const
{
return -std::distance(other.it_, it_);
}
reverse_iterator & operator+=(diff_t n)
{
std::advance(it_, -n);
return *this;
}
private:
BidiIter it_;
};
using rev_bidi_iter = reverse_iterator<std::list<int>::iterator>;
using rev_ra_iter = reverse_iterator<std::vector<int>::iterator>;
int main()
{
{
std::list<int> ints = {4, 3, 2};
std::list<int> ints_copy;
std::copy(
rev_bidi_iter(ints.end()),
rev_bidi_iter(ints.begin()),
std::back_inserter(ints_copy));
std::reverse(ints.begin(), ints.end());
assert(ints_copy == ints);
}
{
std::vector<int> ints = {4, 3, 2};
std::vector<int> ints_copy(ints.size());
std::copy(
rev_ra_iter(ints.end()),
rev_ra_iter(ints.begin()),
ints_copy.begin());
std::reverse(ints.begin(), ints.end());
assert(ints_copy == ints);
}
{
using rev_ptr_iter = reverse_iterator<int *>;
int ints[3] = {4, 3, 2};
int ints_copy[3];
std::copy(
rev_ptr_iter(std::end(ints)),
rev_ptr_iter(std::begin(ints)),
std::begin(ints_copy));
std::reverse(std::begin(ints), std::end(ints));
assert(std::equal(
std::begin(ints_copy),
std::end(ints_copy),
std::begin(ints),
std::end(ints)));
}
}