#include <iostream>
#include <vector>
#include <memory>
template <class ApparentElemType> class readonly_vector_view_base;
template <class ApparentElemType>
class readonly_vector_view
{
public:
readonly_vector_view(const readonly_vector_view& other) : pimpl(other.pimpl) {}
readonly_vector_view(std::shared_ptr<readonly_vector_view_base<ApparentElemType>> pimpl_) : pimpl(pimpl_) {}
typedef typename readonly_vector_view_base<ApparentElemType>::iter iter_base;
class iter
{
public:
iter(std::unique_ptr<iter_base> it_) : it(it_->clone()) {}
iter(const iter& other) : it(other.it->clone()) {}
iter& operator=(iter& other) { it = other.it->clone(); return *this; }
ApparentElemType operator*() const { return **it; }
iter& operator++() { ++*it; return *this; }
iter& operator--() { --*it; return *this; }
iter operator++(int) { iter n(*this); ++*it; return n; }
iter operator--(int) { iter n(*this); --*it; return n; }
bool operator== (const iter& other) const { return *it == *other.it; }
bool operator!= (const iter& other) const { return *it != *other.it; }
private:
std::unique_ptr<iter_base> it;
};
iter begin() { return iter(pimpl->begin()); }
iter end() { return iter(pimpl->end()); }
private:
std::shared_ptr<readonly_vector_view_base<ApparentElemType>> pimpl;
};
template <class ApparentElemType>
struct readonly_vector_view_base
{
struct iter
{
virtual std::unique_ptr<iter> clone() const = 0;
virtual ApparentElemType operator*() const = 0;
virtual iter& operator++() = 0;
virtual iter& operator--() = 0;
virtual bool operator== (const iter& other) const = 0;
virtual bool operator!= (const iter& other) const = 0;
virtual ~iter(){}
};
virtual std::unique_ptr<iter> begin() = 0;
virtual std::unique_ptr<iter> end() = 0;
virtual ~readonly_vector_view_base() {}
};
template <class ElemType, class ApparentElemType>
struct readonly_vector_view_impl : readonly_vector_view_base<ApparentElemType>
{
typedef typename readonly_vector_view_base<ApparentElemType>::iter iter_base;
readonly_vector_view_impl(std::shared_ptr<std::vector<ElemType>> vec_) : vec(vec_) {}
struct iter : iter_base
{
std::unique_ptr<iter_base> clone() const { std::unique_ptr<iter_base> x(new iter(it)); return x; }
iter(typename std::vector<ElemType>::iterator it_) : it(it_) {}
ApparentElemType operator*() const { return *it; }
iter& operator++() { ++it; return *this; }
iter& operator--() { ++it; return *this; }
bool operator== (const iter_base& other) const {
const iter* real_other = dynamic_cast<const iter*>(&other);
return (real_other && it == real_other->it);
}
bool operator!= (const iter_base& other) const { return ! (*this == other); }
typename std::vector<ElemType>::iterator it;
};
std::unique_ptr<iter_base> begin() {
iter* x (new iter(vec->begin()));
std::unique_ptr<iter_base> y(x);
return y;
}
std::unique_ptr<iter_base> end() {
iter* x (new iter(vec->end()));;
std::unique_ptr<iter_base> y(x);
return y;
}
std::shared_ptr<std::vector<ElemType>> vec;
};
struct A
{
A(int x_) : x(x_) {};
readonly_vector_view<A*> test() { return test_A(); }
virtual readonly_vector_view<A*> test_A() = 0;
int x;
};
struct B : A
{
B (int y_, int x_) : y(y_), A(x_) {}
B() : A(0), bvec(std::make_shared<std::vector<B*>>())
{
bvec->push_back (new B(2,3));
bvec->push_back (new B(4,5));
bvec->push_back (new B(6,7));
}
std::shared_ptr<std::vector<B*>> bvec;
readonly_vector_view<B*> test() { return test_B(); }
virtual readonly_vector_view<A*> test_A() {
return readonly_vector_view<A*>(std::make_shared<readonly_vector_view_impl<B*, A*>>(bvec));
}
virtual readonly_vector_view<B*> test_B() {
return readonly_vector_view<B*>(std::make_shared<readonly_vector_view_impl<B*, B*>>(bvec));
}
int y;
};
int main ()
{
B b;
A& a (b);
readonly_vector_view<A*>va = a.test();
readonly_vector_view<B*>vb = b.test();
for (readonly_vector_view<A*>::iter pa = va.begin(); pa != va.end(); ++pa)
{
std::cout << (*pa)->x << " ";
}
std::cout << std::endl;
for (readonly_vector_view<B*>::iter pb = vb.begin(); pb != vb.end(); ++pb)
{
std::cout << (*pb)->x << ":" << (*pb)->y << " ";
}
std::cout << std::endl;
}