/Src/Dependencies/Boost/boost/multi_index/detail/iter_adaptor.hpp

http://hadesmem.googlecode.com/ · C++ Header · 325 lines · 256 code · 52 blank · 17 comment · 0 complexity · 50263d03f3c839da2ae0435c96250f46 MD5 · raw file

  1. /* Copyright 2003-2008 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
  10. #if defined(_MSC_VER)&&(_MSC_VER>=1200)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <boost/mpl/apply.hpp>
  15. #include <boost/multi_index/detail/prevent_eti.hpp>
  16. #include <boost/operators.hpp>
  17. namespace boost{
  18. namespace multi_index{
  19. namespace detail{
  20. /* Poor man's version of boost::iterator_adaptor. Used instead of the
  21. * original as compile times for the latter are significantly higher.
  22. * The interface is not replicated exactly, only to the extent necessary
  23. * for internal consumption.
  24. */
  25. /* NB. The purpose of the (non-inclass) global operators ==, < and - defined
  26. * above is to partially alleviate a problem of MSVC++ 6.0 by * which
  27. * friend-injected operators on T are not visible if T is instantiated only
  28. * in template code where T is a dependent type.
  29. */
  30. class iter_adaptor_access
  31. {
  32. public:
  33. template<class Class>
  34. static typename Class::reference dereference(const Class& x)
  35. {
  36. return x.dereference();
  37. }
  38. template<class Class>
  39. static bool equal(const Class& x,const Class& y)
  40. {
  41. return x.equal(y);
  42. }
  43. template<class Class>
  44. static void increment(Class& x)
  45. {
  46. x.increment();
  47. }
  48. template<class Class>
  49. static void decrement(Class& x)
  50. {
  51. x.decrement();
  52. }
  53. template<class Class>
  54. static void advance(Class& x,typename Class::difference_type n)
  55. {
  56. x.advance(n);
  57. }
  58. template<class Class>
  59. static typename Class::difference_type distance_to(
  60. const Class& x,const Class& y)
  61. {
  62. return x.distance_to(y);
  63. }
  64. };
  65. template<typename Category>
  66. struct iter_adaptor_selector;
  67. template<class Derived,class Base>
  68. class forward_iter_adaptor_base:
  69. public forward_iterator_helper<
  70. Derived,
  71. typename Base::value_type,
  72. typename Base::difference_type,
  73. typename Base::pointer,
  74. typename Base::reference>
  75. {
  76. public:
  77. typedef typename Base::reference reference;
  78. reference operator*()const
  79. {
  80. return iter_adaptor_access::dereference(final());
  81. }
  82. friend bool operator==(const Derived& x,const Derived& y)
  83. {
  84. return iter_adaptor_access::equal(x,y);
  85. }
  86. Derived& operator++()
  87. {
  88. iter_adaptor_access::increment(final());
  89. return final();
  90. }
  91. private:
  92. Derived& final(){return *static_cast<Derived*>(this);}
  93. const Derived& final()const{return *static_cast<const Derived*>(this);}
  94. };
  95. template<class Derived,class Base>
  96. bool operator==(
  97. const forward_iter_adaptor_base<Derived,Base>& x,
  98. const forward_iter_adaptor_base<Derived,Base>& y)
  99. {
  100. return iter_adaptor_access::equal(
  101. static_cast<const Derived&>(x),static_cast<const Derived&>(y));
  102. }
  103. template<>
  104. struct iter_adaptor_selector<std::forward_iterator_tag>
  105. {
  106. template<class Derived,class Base>
  107. struct apply
  108. {
  109. typedef forward_iter_adaptor_base<Derived,Base> type;
  110. };
  111. };
  112. template<class Derived,class Base>
  113. class bidirectional_iter_adaptor_base:
  114. public bidirectional_iterator_helper<
  115. Derived,
  116. typename Base::value_type,
  117. typename Base::difference_type,
  118. typename Base::pointer,
  119. typename Base::reference>
  120. {
  121. public:
  122. typedef typename Base::reference reference;
  123. reference operator*()const
  124. {
  125. return iter_adaptor_access::dereference(final());
  126. }
  127. friend bool operator==(const Derived& x,const Derived& y)
  128. {
  129. return iter_adaptor_access::equal(x,y);
  130. }
  131. Derived& operator++()
  132. {
  133. iter_adaptor_access::increment(final());
  134. return final();
  135. }
  136. Derived& operator--()
  137. {
  138. iter_adaptor_access::decrement(final());
  139. return final();
  140. }
  141. private:
  142. Derived& final(){return *static_cast<Derived*>(this);}
  143. const Derived& final()const{return *static_cast<const Derived*>(this);}
  144. };
  145. template<class Derived,class Base>
  146. bool operator==(
  147. const bidirectional_iter_adaptor_base<Derived,Base>& x,
  148. const bidirectional_iter_adaptor_base<Derived,Base>& y)
  149. {
  150. return iter_adaptor_access::equal(
  151. static_cast<const Derived&>(x),static_cast<const Derived&>(y));
  152. }
  153. template<>
  154. struct iter_adaptor_selector<std::bidirectional_iterator_tag>
  155. {
  156. template<class Derived,class Base>
  157. struct apply
  158. {
  159. typedef bidirectional_iter_adaptor_base<Derived,Base> type;
  160. };
  161. };
  162. template<class Derived,class Base>
  163. class random_access_iter_adaptor_base:
  164. public random_access_iterator_helper<
  165. Derived,
  166. typename Base::value_type,
  167. typename Base::difference_type,
  168. typename Base::pointer,
  169. typename Base::reference>
  170. {
  171. public:
  172. typedef typename Base::reference reference;
  173. typedef typename Base::difference_type difference_type;
  174. reference operator*()const
  175. {
  176. return iter_adaptor_access::dereference(final());
  177. }
  178. friend bool operator==(const Derived& x,const Derived& y)
  179. {
  180. return iter_adaptor_access::equal(x,y);
  181. }
  182. friend bool operator<(const Derived& x,const Derived& y)
  183. {
  184. return iter_adaptor_access::distance_to(x,y)>0;
  185. }
  186. Derived& operator++()
  187. {
  188. iter_adaptor_access::increment(final());
  189. return final();
  190. }
  191. Derived& operator--()
  192. {
  193. iter_adaptor_access::decrement(final());
  194. return final();
  195. }
  196. Derived& operator+=(difference_type n)
  197. {
  198. iter_adaptor_access::advance(final(),n);
  199. return final();
  200. }
  201. Derived& operator-=(difference_type n)
  202. {
  203. iter_adaptor_access::advance(final(),-n);
  204. return final();
  205. }
  206. friend difference_type operator-(const Derived& x,const Derived& y)
  207. {
  208. return iter_adaptor_access::distance_to(y,x);
  209. }
  210. private:
  211. Derived& final(){return *static_cast<Derived*>(this);}
  212. const Derived& final()const{return *static_cast<const Derived*>(this);}
  213. };
  214. template<class Derived,class Base>
  215. bool operator==(
  216. const random_access_iter_adaptor_base<Derived,Base>& x,
  217. const random_access_iter_adaptor_base<Derived,Base>& y)
  218. {
  219. return iter_adaptor_access::equal(
  220. static_cast<const Derived&>(x),static_cast<const Derived&>(y));
  221. }
  222. template<class Derived,class Base>
  223. bool operator<(
  224. const random_access_iter_adaptor_base<Derived,Base>& x,
  225. const random_access_iter_adaptor_base<Derived,Base>& y)
  226. {
  227. return iter_adaptor_access::distance_to(
  228. static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
  229. }
  230. template<class Derived,class Base>
  231. typename random_access_iter_adaptor_base<Derived,Base>::difference_type
  232. operator-(
  233. const random_access_iter_adaptor_base<Derived,Base>& x,
  234. const random_access_iter_adaptor_base<Derived,Base>& y)
  235. {
  236. return iter_adaptor_access::distance_to(
  237. static_cast<const Derived&>(y),static_cast<const Derived&>(x));
  238. }
  239. template<>
  240. struct iter_adaptor_selector<std::random_access_iterator_tag>
  241. {
  242. template<class Derived,class Base>
  243. struct apply
  244. {
  245. typedef random_access_iter_adaptor_base<Derived,Base> type;
  246. };
  247. };
  248. template<class Derived,class Base>
  249. struct iter_adaptor_base
  250. {
  251. typedef iter_adaptor_selector<
  252. typename Base::iterator_category> selector;
  253. typedef typename prevent_eti<
  254. selector,
  255. typename mpl::apply2<
  256. selector,Derived,Base>::type
  257. >::type type;
  258. };
  259. template<class Derived,class Base>
  260. class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
  261. {
  262. protected:
  263. iter_adaptor(){}
  264. explicit iter_adaptor(const Base& b_):b(b_){}
  265. const Base& base_reference()const{return b;}
  266. Base& base_reference(){return b;}
  267. private:
  268. Base b;
  269. };
  270. } /* namespace multi_index::detail */
  271. } /* namespace multi_index */
  272. } /* namespace boost */
  273. #endif