Guest User

A C++ iterator adapter which wraps and hides an inner iterator and converts the iterated type

a guest
Feb 26th, 2012
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.49 KB | None | 0 0
  1. MagicIterator
  2.  
  3. MagicIterator
  4.  
  5. MagicIterator
  6.  
  7. class cont_iter
  8. : public boost::iterator_adaptor<
  9. cont_iter // Derived
  10. , std::list<Container::Item>::iterator // Base
  11. , IInterface* // Value
  12. , boost::forward_traversal_tag // CategoryOrTraversal
  13. , IInterface* // Reference :)
  14. >
  15. {
  16. public:
  17. cont_iter()
  18. : cont_iter::iterator_adaptor_() {}
  19.  
  20. explicit cont_iter(const cont_iter::iterator_adaptor_::base_type& p)
  21. : cont_iter::iterator_adaptor_(p) {}
  22.  
  23. private:
  24. friend class boost::iterator_core_access;
  25. IInterface* dereference() { return this->base()->pObject->GetInterface(); }
  26. };
  27.  
  28. namespace detail {
  29. template<typename T, typename U>
  30. struct constify;
  31.  
  32. template<typename T, typename U>
  33. struct constify<T*, U*> {
  34. typedef T * type;
  35. };
  36.  
  37. template<typename T, typename U>
  38. struct constify<T*, U const*> {
  39. typedef T const * type;
  40. };
  41. }
  42.  
  43. template<typename DstType,
  44. typename Container,
  45. typename InputIterator>
  46. struct MagicIterator;
  47.  
  48. class Container
  49. {
  50. private:
  51. struct Item
  52. {
  53. Object* pObject;
  54. };
  55.  
  56. std::list<Item> m_items;
  57.  
  58. public:
  59.  
  60. // required by every Container for the iterator
  61. typedef std::list<Item> iterator;
  62. typedef std::list<Item> const_iterator;
  63.  
  64. // convenience declarations
  65. typedef MagicIterator< IInterface*, Container, iterator >
  66. item_iterator;
  67. typedef MagicIterator< IInterface*, Container, const_iterator >
  68. const_item_iterator;
  69.  
  70. item_iterator Begin();
  71. item_iterator End();
  72. };
  73.  
  74. template<typename DstType,
  75. typename Container = Container,
  76. typename InputIterator = typename Container::iterator>
  77. struct MagicIterator :
  78. // pick either const T or T, depending on whether it's a const_iterator.
  79. std::iterator<std::input_iterator_tag,
  80. typename detail::constify<
  81. DstType,
  82. typename InputIterator::value_type*>::type> {
  83. typedef std::iterator<std::input_iterator_tag,
  84. typename detail::constify<
  85. DstType,
  86. typename InputIterator::value_type*>::type> base;
  87. MagicIterator():wrapped() { }
  88. explicit MagicIterator(InputIterator const& it):wrapped(it) { }
  89. MagicIterator(MagicIterator const& that):wrapped(that.wrapped) { }
  90.  
  91. typename base::value_type operator*() {
  92. return (*wrapped).pObject->GetInterface();
  93. }
  94.  
  95. MagicIterator& operator++() {
  96. ++wrapped;
  97. return *this;
  98. }
  99.  
  100. MagicIterator operator++(int) {
  101. MagicIterator it(*this);
  102. wrapped++;
  103. return it;
  104. }
  105.  
  106. bool operator==(MagicIterator const& it) const {
  107. return it.wrapped == wrapped;
  108. }
  109.  
  110. bool operator!=(MagicIterator const& it) const {
  111. return !(*this == it);
  112. }
  113.  
  114. InputIterator wrapped;
  115. };
  116.  
  117. // now that the iterator adepter is defined, we can define Begin and End
  118. inline Container::item_iterator Container::Begin() {
  119. return item_iterator(m_items.begin());
  120. }
  121.  
  122. inline Container::item_iterator Container::End() {
  123. return item_iterator(m_items.end());
  124. }
  125.  
  126. for(MagicIterator<IInterface*> it = c.Begin(); it != c.End(); ++it) {
  127. // ...
  128. }
  129.  
  130. template<typename T>
  131. class IteratorImplementation
  132. {
  133. public:
  134. virtual ~IteratorImplementation() = 0;
  135.  
  136. virtual T &operator*() = 0;
  137. virtual const T &operator*() const = 0;
  138.  
  139. virtual Iterator<T> &operator++() = 0;
  140. virtual Iterator<T> &operator--() = 0;
  141. };
  142.  
  143. template<typename T>
  144. class Iterator
  145. {
  146. public:
  147. Iterator(IteratorImplementation<T> * = 0);
  148. ~Iterator();
  149.  
  150. T &operator*();
  151. const T &operator*() const;
  152.  
  153. Iterator<T> &operator++();
  154. Iterator<T> &operator--();
  155.  
  156. private:
  157. IteratorImplementation<T> *i;
  158. }
  159.  
  160. Iterator::Iterator(IteratorImplementation<T> *impl) :
  161. i(impl)
  162. {
  163. }
  164.  
  165. Iterator::~Iterator()
  166. {
  167. delete i;
  168. }
  169.  
  170. T &Iterator::operator*()
  171. {
  172. if(!impl)
  173. {
  174. // Throw exception if you please.
  175. return;
  176. }
  177.  
  178. return (*impl)();
  179. }
  180.  
  181. // etc.
  182.  
  183. class ObjectContainer
  184. {
  185. public:
  186. void insert(Object *o);
  187. // ...
  188.  
  189. Iterator<Object *> begin();
  190. Iterator<Object *> end();
  191.  
  192. private:
  193. class CustomIteratorImplementation :
  194. public IteratorImplementation<Object *>
  195. {
  196. public:
  197. // Re-implement stuff here.
  198. }
  199. };
  200.  
  201. Iterator<Object *> ObjectContainer::begin()
  202. {
  203. CustomIteratorImplementation *impl = new CustomIteratorImplementation(); // Wish we had C++0x's "var" here. ;P
  204.  
  205. return Iterator<Object *>(impl);
  206. }
  207.  
  208. template<typename T>
  209. class MagicIterator
  210. {
  211. public:
  212. MagicIterator(std::vector<T>::const_iterator i)
  213. {
  214. vector_const_iterator = i;
  215. }
  216.  
  217. // Reimplement similarly for more types.
  218. MagicIterator(std::vector<T>::iterator i);
  219. MagicIterator(std::list<T>::const_iterator i);
  220. MagicIterator(std::list<T>::iterator i);
  221.  
  222. // Reimplement operators here...
  223.  
  224. private:
  225. std::vector<T>::const_iterator vector_const_iterator;
  226. std::vector<T>::iterator vector_iterator;
  227. std::list<T>::const_iterator list_const_iterator;
  228. std::list<T>::iterator list_iterator;
  229. };
  230.  
  231. // C++0x
  232. template<typename T>
  233. class Iterator :
  234. public T::iterator
  235. {
  236. using T::iterator::iterator;
  237. };
  238.  
  239. for(Iterator<Container> i = c.begin(); i != c.end(); ++i)
  240. {
  241. // ...
  242. }
Add Comment
Please, Sign In to add comment