#include <vector>
#include <string>
#include <list>
#include <type_traits>
#include <iostream>
#include <iterator>
using T = std::string;
using VectT = std::vector<T>;
using ListT = std::list<VectT>;
using value_type = T;
class const_iterator :
public std::iterator<std::bidirectional_iterator_tag , value_type const> {
public:
using ListIt = typename ListT::const_iterator;
using VectIt = typename VectT::const_iterator;
explicit const_iterator(ListIt itHigh, VectIt itLow) :
itHigh_{itHigh}, itLow_{itLow} {
}
const_iterator(const const_iterator &it) :
itHigh_{it.itHigh_}, itLow_{it.itLow_} {
}
const_iterator & operator ++ () {
std::cout << "increment" << std::endl;
itLow_++;
if (itLow_ == itHigh_->end()) {
itHigh_++;
itLow_ = itHigh_->begin();
}
return *this;
}
const_iterator operator ++ (int) {
const_iterator retval = *this;
++(*this);
return retval;
}
const_iterator & operator -- () {
std::cout << "decrement" << std::endl;
itLow_--;
if (itLow_ == --itHigh_->begin()) {
itHigh_--;
itLow_ = --(itHigh_->end());
}
return *this;
}
const_iterator operator -- (int) {
const_iterator retval = *this;
--(*this);
return retval;
}
bool operator == (const_iterator other) const {
return other.itHigh_ == itHigh_&& other.itLow_ == itLow_;
}
bool operator != (const_iterator other) const {
return !(other == *this);
}
const value_type & operator * () const {
return *itLow_;
}
const value_type * operator -> () const {
return &(operator *());
}
private:
ListIt itHigh_;
VectIt itLow_;
};
int main() {
std::cout
<< std::is_same<typename std::iterator_traits<const_iterator>::value_type, std::string const>::value
<< std::endl;
ListT items = {{"First", "Second"}, {"Third", "Fourth"}, {"Fifth", "Sixth", "Seventh"}};
const_iterator it{items.begin(), items.begin()->begin()};
const_iterator end{items.end(), items.end()->begin()};
for (; it != end; it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
const_reverse_iterator rit{const_iterator{(--items.end()), --items.rbegin()->rbegin().base()}};
const_reverse_iterator rend{const_iterator{items.begin(), --items.rend()->end()}};
/*for (; rit != rend; rit++) {
std::cout << *rit << " ";
}*/
rit--;
--rit;
rit++;
++rit;
std::cout << *rit << std::endl;
*rit;
*rit;
std::cout << std::endl;
}