#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <typeinfo>
template <typename Iterator>
class const_iterator
{
public:
typedef Iterator iterator_type;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
// note: trying to add const to ...:reference or ..:pointer doesn't work,
// as it's like saying T* const rather than T const* aka const T*.
typedef const typename std::iterator_traits<Iterator>::value_type& reference;
typedef const typename std::iterator_traits<Iterator>::value_type* pointer;
const_iterator(const Iterator& i) : i_(i) { }
reference operator*() const { return *i_; }
pointer operator->() const { return i_; }
bool operator==(const const_iterator& rhs) const { return i_ == rhs.i_; }
bool operator!=(const const_iterator& rhs) const { return i_ != rhs.i_; }
const_iterator& operator++() { ++i_; return *this; }
const_iterator operator++(int) const { Iterator i = i_; ++i_; return i; }
private:
Iterator i_;
};
template <typename Const_Iterator>
void f(const Const_Iterator& b__, const Const_Iterator& e__)
{
::const_iterator<Const_Iterator> b{b__}, e{e__};
// *b = 2; // if uncommented, compile-time error....
for ( ; b != e; ++b)
std::cout << *b << '\n';
}
int main()
{
std::vector<int> v { 11, 22, 33 };
f(v.begin(), v.end());
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bGlzdD4KI2luY2x1ZGUgPGl0ZXJhdG9yPgojaW5jbHVkZSA8dHlwZWluZm8+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcmF0b3I+CmNsYXNzIGNvbnN0X2l0ZXJhdG9yCnsKICBwdWJsaWM6CiAgICB0eXBlZGVmIEl0ZXJhdG9yICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXJhdG9yX3R5cGU7CiAgICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6aXRlcmF0b3JfdHJhaXRzPEl0ZXJhdG9yPjo6ZGlmZmVyZW5jZV90eXBlIGRpZmZlcmVuY2VfdHlwZTsKICAgIC8vIG5vdGU6IHRyeWluZyB0byBhZGQgY29uc3QgdG8gLi4uOnJlZmVyZW5jZSBvciAuLjpwb2ludGVyIGRvZXNuJ3Qgd29yaywKICAgIC8vICAgICAgIGFzIGl0J3MgbGlrZSBzYXlpbmcgVCogY29uc3QgcmF0aGVyIHRoYW4gVCBjb25zdCogYWthIGNvbnN0IFQqLgogICAgdHlwZWRlZiBjb25zdCB0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czxJdGVyYXRvcj46OnZhbHVlX3R5cGUmIHJlZmVyZW5jZTsKICAgIHR5cGVkZWYgY29uc3QgdHlwZW5hbWUgc3RkOjppdGVyYXRvcl90cmFpdHM8SXRlcmF0b3I+Ojp2YWx1ZV90eXBlKiBwb2ludGVyOwogICAgCiAgICBjb25zdF9pdGVyYXRvcihjb25zdCBJdGVyYXRvciYgaSkgOiBpXyhpKSB7IH0KICAgIHJlZmVyZW5jZSBvcGVyYXRvciooKSBjb25zdCB7IHJldHVybiAqaV87IH0KICAgIHBvaW50ZXIgb3BlcmF0b3ItPigpIGNvbnN0IHsgcmV0dXJuIGlfOyB9ICAgIAogICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGNvbnN0X2l0ZXJhdG9yJiByaHMpIGNvbnN0IHsgcmV0dXJuIGlfID09IHJocy5pXzsgfQogICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGNvbnN0X2l0ZXJhdG9yJiByaHMpIGNvbnN0IHsgcmV0dXJuIGlfICE9IHJocy5pXzsgfSAgICAKICAgIGNvbnN0X2l0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeyArK2lfOyByZXR1cm4gKnRoaXM7IH0KICAgIGNvbnN0X2l0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSBjb25zdCB7IEl0ZXJhdG9yIGkgPSBpXzsgKytpXzsgcmV0dXJuIGk7IH0KICBwcml2YXRlOgogICAgSXRlcmF0b3IgaV87Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQ29uc3RfSXRlcmF0b3I+CnZvaWQgZihjb25zdCBDb25zdF9JdGVyYXRvciYgYl9fLCBjb25zdCBDb25zdF9JdGVyYXRvciYgZV9fKQp7Cgk6OmNvbnN0X2l0ZXJhdG9yPENvbnN0X0l0ZXJhdG9yPiBie2JfX30sIGV7ZV9ffTsKCS8vICpiID0gMjsgIC8vIGlmIHVuY29tbWVudGVkLCBjb21waWxlLXRpbWUgZXJyb3IuLi4uCiAgICBmb3IgKCA7IGIgIT0gZTsgKytiKQogICAgICAgIHN0ZDo6Y291dCA8PCAqYiA8PCAnXG4nOwp9CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6dmVjdG9yPGludD4gdiB7IDExLCAyMiwgMzMgfTsKICAgIGYodi5iZWdpbigpLCB2LmVuZCgpKTsKfQ==