Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <deque>
- #include <iostream>
- #include <string>
- #include <memory>
- using namespace std; // bad form, but for simplicity
- // Forward decl's
- template <typename C, typename SubC,
- typename cSubC, bool isConst> class Wrapper;
- template <typename C, typename SubC>
- struct w_iterator
- {
- typedef w_iterator _Self;
- typedef SubC & _Ref;
- typedef SubC * _Ptr;
- typedef typename C::iterator internal_iter;
- // Default c-tors
- w_iterator() = delete;
- w_iterator(const internal_iter & i) : internal(i) { }
- // Copy c-tor
- w_iterator(const w_iterator & i) : internal(i.internal) { }
- // D-tor
- ~w_iterator() { }
- // Dereference
- _Ref operator * () const
- { proxy.reset(new SubC(*internal)); return *proxy; }
- _Ptr operator -> () const
- { proxy.reset(new SubC(*internal)); return proxy.get(); }
- // Comparison
- bool operator == (const _Self & i)
- { return (internal == i.internal); }
- bool operator != (const _Self & i)
- { return (internal != i.internal); }
- // Manipulation
- _Self & operator ++ () { ++internal; return *this; }
- mutable std::unique_ptr<SubC> proxy;
- internal_iter internal;
- };
- template <typename C, typename SubC>
- struct const_w_iterator
- {
- typedef w_iterator<C,SubC> _nonConstSelf;
- typedef const_w_iterator _Self;
- typedef const SubC & _Ref;
- typedef const SubC * _Ptr;
- typedef typename C::iterator nonconst_internal_iter;
- typedef typename C::const_iterator internal_iter;
- // Default c-tors
- const_w_iterator() = delete;
- const_w_iterator(const nonconst_internal_iter & i) : internal(i) { }
- const_w_iterator(const internal_iter & i) : internal(i) { }
- // Dereference
- _Ref operator * () const
- { proxy.reset(new SubC(*internal)); return *proxy; }
- _Ptr operator -> () const
- { proxy.reset(new SubC(*internal)); return proxy.get(); }
- // Comparison
- bool operator == (const _Self & i)
- { return (internal == i.internal); }
- bool operator == (const _nonConstSelf & i)
- { return (internal == i.internal); }
- bool operator != (const _Self & i)
- { return (internal != i.internal); }
- bool operator != (const _nonConstSelf & i)
- { return (internal != i.internal); }
- // Manipulation
- _Self & operator ++ () { ++internal; return *this; }
- mutable std::unique_ptr<const SubC> proxy;
- internal_iter internal;
- };
- template <typename C, typename SubC,
- typename cSubC = const SubC, bool isConst = false>
- class Wrapper
- {
- public:
- // Typedefs - shared btw here & const_Wrapper
- typedef w_iterator<C, SubC> iterator;
- typedef const_w_iterator<C, cSubC> const_iterator;
- // Default construction - only allow construction with an underlying
- // container
- Wrapper() = delete;
- Wrapper(C & c) : container(&c) { }
- Wrapper(const C & c)
- : container(const_cast<C*>(&c))
- { static_assert(isConst, "ZZZ"); }
- // Copy constructor XXX - is there a better way of expressing all of this?
- // Do we need to delete a pass-by-value c-tor as well?
- Wrapper(const Wrapper<C, SubC, cSubC, true> & c)
- : container(const_cast<C*>(&c.container))
- { static_assert(isConst, "YYY"); }
- Wrapper(const Wrapper<C, SubC, cSubC, false> & c)
- : container(const_cast<C*>(&c.container))
- { static_assert(isConst, "XXX"); }
- Wrapper(Wrapper & c) : container(c.container) { }
- // Iterator access
- iterator begin()
- { static_assert(!isConst, "Access of non-const function");
- return iterator(container->begin()); }
- iterator end()
- { static_assert(!isConst, "Access of non-const function");
- return iterator(container->end()); }
- const_iterator cbegin() const
- { return const_iterator(container->cbegin()); }
- const_iterator cend() const
- { return const_iterator(container->cend()); }
- // Accessor functions
- size_t length() const { return container->size(); }
- protected:
- C * container;
- };
- int main(int argc, char ** argv)
- {
- deque<string> d = { "one", "two", "three" };
- deque<decltype(d)> dd = { d };
- deque<decltype(dd)> ddd { dd };
- cout << d.size() << " " << dd.size() << " " << ddd.size() << endl;
- Wrapper<decltype(d), string> w(d);
- Wrapper<decltype(dd),
- decltype(w),
- Wrapper<decltype(d), string, const string, true>,
- false> ww(dd);
- Wrapper<decltype(ddd),
- decltype(ww),
- Wrapper<decltype(dd),
- decltype(w),
- Wrapper<decltype(d), string, const string, true>,
- true>,
- false> www(ddd);
- for (auto i = www.cbegin(); i != www.cend(); ++i)
- {
- cout << "www: " << i->length() << endl;
- for (auto j = i->cbegin(); j != i->cend(); ++j)
- {
- cout << "ww: " << j->length() << endl;
- for (auto k = j->cbegin(); k != j->cend(); ++k)
- cout << *k << endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement