Advertisement
Guest User

Untitled

a guest
Mar 8th, 2013
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.79 KB | None | 0 0
  1. #include <deque>
  2. #include <iostream>
  3. #include <string>
  4. #include <memory>
  5.  
  6. using namespace std; // bad form, but for simplicity
  7.  
  8.  
  9.  
  10. // Forward decl's
  11. template <typename C, typename SubC,
  12.           typename cSubC, bool isConst> class Wrapper;
  13.  
  14. template <typename C, typename SubC>
  15. struct w_iterator
  16. {
  17.     typedef w_iterator           _Self;
  18.     typedef SubC &               _Ref;
  19.     typedef SubC *               _Ptr;
  20.     typedef typename C::iterator internal_iter;
  21.  
  22.     // Default c-tors
  23.     w_iterator() = delete;
  24.     w_iterator(const internal_iter & i) : internal(i) { }
  25.  
  26.     // Copy c-tor
  27.     w_iterator(const w_iterator & i) : internal(i.internal) { }
  28.  
  29.     // D-tor
  30.     ~w_iterator() { }
  31.  
  32.     // Dereference
  33.     _Ref operator * () const
  34.         { proxy.reset(new SubC(*internal)); return *proxy; }
  35.     _Ptr operator -> () const
  36.         { proxy.reset(new SubC(*internal)); return proxy.get(); }
  37.    
  38.     // Comparison
  39.     bool operator == (const _Self & i)
  40.         { return (internal == i.internal); }
  41.     bool operator != (const _Self & i)
  42.         { return (internal != i.internal); }
  43.  
  44.     // Manipulation
  45.     _Self & operator ++ () { ++internal; return *this; }
  46.  
  47.     mutable std::unique_ptr<SubC> proxy;
  48.     internal_iter internal;
  49. };
  50.  
  51. template <typename C, typename SubC>
  52. struct const_w_iterator
  53. {
  54.     typedef w_iterator<C,SubC>         _nonConstSelf;
  55.     typedef const_w_iterator           _Self;
  56.     typedef const SubC &               _Ref;
  57.     typedef const SubC *               _Ptr;
  58.     typedef typename C::iterator       nonconst_internal_iter;
  59.     typedef typename C::const_iterator internal_iter;
  60.  
  61.     // Default c-tors
  62.     const_w_iterator() = delete;
  63.     const_w_iterator(const nonconst_internal_iter & i) : internal(i) { }
  64.     const_w_iterator(const internal_iter & i) : internal(i) { }
  65.  
  66.     // Dereference
  67.     _Ref operator * () const
  68.         { proxy.reset(new SubC(*internal)); return *proxy; }
  69.     _Ptr operator -> () const
  70.         { proxy.reset(new SubC(*internal)); return proxy.get(); }
  71.  
  72.     // Comparison
  73.     bool operator == (const _Self & i)
  74.         { return (internal == i.internal); }
  75.     bool operator == (const _nonConstSelf & i)
  76.         { return (internal == i.internal); }
  77.     bool operator != (const _Self & i)
  78.         { return (internal != i.internal); }
  79.     bool operator != (const _nonConstSelf & i)
  80.         { return (internal != i.internal); }
  81.  
  82.     // Manipulation
  83.     _Self & operator ++ () { ++internal; return *this; }
  84.  
  85.     mutable std::unique_ptr<const SubC> proxy;
  86.     internal_iter internal;
  87. };
  88.  
  89. template <typename C, typename SubC,
  90.           typename cSubC = const SubC, bool isConst = false>
  91. class Wrapper
  92. {
  93.  public:
  94.     // Typedefs - shared btw here & const_Wrapper
  95.     typedef w_iterator<C, SubC>       iterator;
  96.     typedef const_w_iterator<C, cSubC> const_iterator;
  97.  
  98.     // Default construction - only allow construction with an underlying
  99.     // container
  100.     Wrapper() = delete;
  101.     Wrapper(C & c) : container(&c) { }
  102.  
  103.     Wrapper(const C & c)
  104.       : container(const_cast<C*>(&c))
  105.         { static_assert(isConst, "ZZZ"); }
  106.  
  107.     // Copy constructor XXX - is there a better way of expressing all of this?
  108.     // Do we need to delete a pass-by-value c-tor as well?
  109.     Wrapper(const Wrapper<C, SubC, cSubC, true> & c)
  110.       : container(const_cast<C*>(&c.container))
  111.         { static_assert(isConst, "YYY"); }
  112.  
  113.     Wrapper(const Wrapper<C, SubC, cSubC, false> & c)
  114.       : container(const_cast<C*>(&c.container))
  115.         { static_assert(isConst, "XXX"); }
  116.  
  117.     Wrapper(Wrapper & c) : container(c.container) { }
  118.    
  119.     // Iterator access
  120.     iterator begin()
  121.         {   static_assert(!isConst, "Access of non-const function");
  122.             return iterator(container->begin()); }
  123.  
  124.     iterator end()
  125.         {   static_assert(!isConst, "Access of non-const function");
  126.             return iterator(container->end()); }
  127.  
  128.     const_iterator cbegin() const
  129.         { return const_iterator(container->cbegin()); }
  130.     const_iterator cend() const
  131.         { return const_iterator(container->cend()); }
  132.  
  133.     // Accessor functions
  134.     size_t length() const { return container->size(); }
  135.  
  136.  protected:
  137.     C * container;
  138. };
  139.  
  140.  
  141. int main(int argc, char ** argv)
  142. {
  143.     deque<string> d = { "one", "two", "three" };
  144.     deque<decltype(d)> dd = { d };
  145.     deque<decltype(dd)> ddd { dd };
  146.  
  147.     cout << d.size() << " " << dd.size() << " " << ddd.size() << endl;
  148.  
  149.     Wrapper<decltype(d), string> w(d);
  150.     Wrapper<decltype(dd),
  151.             decltype(w),
  152.             Wrapper<decltype(d), string, const string, true>,
  153.             false> ww(dd);
  154.     Wrapper<decltype(ddd),
  155.             decltype(ww),
  156.             Wrapper<decltype(dd),
  157.                     decltype(w),
  158.                     Wrapper<decltype(d), string, const string, true>,
  159.                     true>,
  160.             false> www(ddd);
  161.  
  162.     for (auto i = www.cbegin(); i != www.cend(); ++i)
  163.     {
  164.         cout << "www: " << i->length() << endl;
  165.         for (auto j = i->cbegin(); j != i->cend(); ++j)
  166.         {
  167.             cout << "ww: " << j->length() << endl;
  168.             for (auto k = j->cbegin(); k != j->cend(); ++k)
  169.                 cout << *k << endl;
  170.         }
  171.     }
  172.  
  173.     return 0;
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement