iterator_archetypes.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. // (C) Copyright Jeremy Siek 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_ITERATOR_ARCHETYPES_HPP
  6. #define BOOST_ITERATOR_ARCHETYPES_HPP
  7. #include <boost/iterator/iterator_categories.hpp>
  8. #include <boost/operators.hpp>
  9. #include <boost/static_assert.hpp>
  10. #include <boost/iterator/detail/facade_iterator_category.hpp>
  11. #include <boost/type_traits/is_const.hpp>
  12. #include <boost/type_traits/add_const.hpp>
  13. #include <boost/type_traits/remove_const.hpp>
  14. #include <boost/type_traits/remove_cv.hpp>
  15. #include <boost/concept_archetype.hpp>
  16. #include <boost/mpl/bitand.hpp>
  17. #include <boost/mpl/int.hpp>
  18. #include <boost/mpl/equal_to.hpp>
  19. #include <boost/mpl/if.hpp>
  20. #include <boost/mpl/eval_if.hpp>
  21. #include <boost/mpl/and.hpp>
  22. #include <boost/mpl/identity.hpp>
  23. #include <cstddef>
  24. namespace boost {
  25. namespace iterators {
  26. template <class Value, class AccessCategory>
  27. struct access_archetype;
  28. template <class Derived, class Value, class AccessCategory, class TraversalCategory>
  29. struct traversal_archetype;
  30. namespace archetypes
  31. {
  32. enum {
  33. readable_iterator_bit = 1
  34. , writable_iterator_bit = 2
  35. , swappable_iterator_bit = 4
  36. , lvalue_iterator_bit = 8
  37. };
  38. // Not quite tags, since dispatching wouldn't work.
  39. typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
  40. typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
  41. typedef mpl::int_<
  42. (readable_iterator_bit|writable_iterator_bit)
  43. >::type readable_writable_iterator_t;
  44. typedef mpl::int_<
  45. (readable_iterator_bit|lvalue_iterator_bit)
  46. >::type readable_lvalue_iterator_t;
  47. typedef mpl::int_<
  48. (lvalue_iterator_bit|writable_iterator_bit)
  49. >::type writable_lvalue_iterator_t;
  50. typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
  51. typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
  52. template <class Derived, class Base>
  53. struct has_access
  54. : mpl::equal_to<
  55. mpl::bitand_<Derived,Base>
  56. , Base
  57. >
  58. {};
  59. }
  60. namespace detail
  61. {
  62. template <class T>
  63. struct assign_proxy
  64. {
  65. assign_proxy& operator=(T) { return *this; }
  66. };
  67. template <class T>
  68. struct read_proxy
  69. {
  70. operator T() { return static_object<T>::get(); }
  71. };
  72. template <class T>
  73. struct read_write_proxy
  74. : read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
  75. {
  76. read_write_proxy& operator=(T) { return *this; }
  77. };
  78. template <class T>
  79. struct arrow_proxy
  80. {
  81. T const* operator->() const { return 0; }
  82. };
  83. struct no_operator_brackets {};
  84. template <class ValueType>
  85. struct readable_operator_brackets
  86. {
  87. read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
  88. };
  89. template <class ValueType>
  90. struct writable_operator_brackets
  91. {
  92. read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
  93. };
  94. template <class Value, class AccessCategory, class TraversalCategory>
  95. struct operator_brackets
  96. : mpl::eval_if<
  97. is_convertible<TraversalCategory, random_access_traversal_tag>
  98. , mpl::eval_if<
  99. archetypes::has_access<
  100. AccessCategory
  101. , archetypes::writable_iterator_t
  102. >
  103. , mpl::identity<writable_operator_brackets<Value> >
  104. , mpl::if_<
  105. archetypes::has_access<
  106. AccessCategory
  107. , archetypes::readable_iterator_t
  108. >
  109. , readable_operator_brackets<Value>
  110. , no_operator_brackets
  111. >
  112. >
  113. , mpl::identity<no_operator_brackets>
  114. >::type
  115. {};
  116. template <class TraversalCategory>
  117. struct traversal_archetype_impl
  118. {
  119. template <class Derived,class Value> struct archetype;
  120. };
  121. // Constructor argument for those iterators that
  122. // are not default constructible
  123. struct ctor_arg {};
  124. template <class Derived, class Value, class TraversalCategory>
  125. struct traversal_archetype_
  126. : traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
  127. {
  128. typedef typename
  129. traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
  130. base;
  131. traversal_archetype_() {}
  132. traversal_archetype_(ctor_arg arg)
  133. : base(arg)
  134. {}
  135. };
  136. template <>
  137. struct traversal_archetype_impl<incrementable_traversal_tag>
  138. {
  139. template<class Derived, class Value>
  140. struct archetype
  141. {
  142. explicit archetype(ctor_arg) {}
  143. struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
  144. typedef bogus difference_type;
  145. Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
  146. Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
  147. };
  148. };
  149. template <>
  150. struct traversal_archetype_impl<single_pass_traversal_tag>
  151. {
  152. template<class Derived, class Value>
  153. struct archetype
  154. : public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
  155. public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
  156. {
  157. explicit archetype(ctor_arg arg)
  158. : traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
  159. {}
  160. typedef std::ptrdiff_t difference_type;
  161. };
  162. };
  163. template <class Derived, class Value>
  164. bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
  165. traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
  166. template <>
  167. struct traversal_archetype_impl<forward_traversal_tag>
  168. {
  169. template<class Derived, class Value>
  170. struct archetype
  171. : public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
  172. {
  173. archetype()
  174. : traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
  175. {}
  176. };
  177. };
  178. template <>
  179. struct traversal_archetype_impl<bidirectional_traversal_tag>
  180. {
  181. template<class Derived, class Value>
  182. struct archetype
  183. : public traversal_archetype_<Derived, Value, forward_traversal_tag>
  184. {
  185. Derived& operator--() { return static_object<Derived>::get(); }
  186. Derived operator--(int) const { return static_object<Derived>::get(); }
  187. };
  188. };
  189. template <>
  190. struct traversal_archetype_impl<random_access_traversal_tag>
  191. {
  192. template<class Derived, class Value>
  193. struct archetype
  194. : public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
  195. {
  196. Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
  197. Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
  198. };
  199. };
  200. template <class Derived, class Value>
  201. Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
  202. std::ptrdiff_t) { return static_object<Derived>::get(); }
  203. template <class Derived, class Value>
  204. Derived& operator+(std::ptrdiff_t,
  205. traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
  206. { return static_object<Derived>::get(); }
  207. template <class Derived, class Value>
  208. Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
  209. std::ptrdiff_t)
  210. { return static_object<Derived>::get(); }
  211. template <class Derived, class Value>
  212. std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
  213. traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
  214. { return 0; }
  215. template <class Derived, class Value>
  216. bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
  217. traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
  218. { return true; }
  219. template <class Derived, class Value>
  220. bool operator>(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
  221. traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
  222. { return true; }
  223. template <class Derived, class Value>
  224. bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
  225. traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
  226. { return true; }
  227. template <class Derived, class Value>
  228. bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
  229. traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
  230. { return true; }
  231. struct bogus_type;
  232. template <class Value>
  233. struct convertible_type
  234. : mpl::if_< is_const<Value>,
  235. typename remove_const<Value>::type,
  236. bogus_type >
  237. {};
  238. } // namespace detail
  239. template <class> struct undefined;
  240. template <class AccessCategory>
  241. struct iterator_access_archetype_impl
  242. {
  243. template <class Value> struct archetype;
  244. };
  245. template <class Value, class AccessCategory>
  246. struct iterator_access_archetype
  247. : iterator_access_archetype_impl<
  248. AccessCategory
  249. >::template archetype<Value>
  250. {
  251. };
  252. template <>
  253. struct iterator_access_archetype_impl<
  254. archetypes::readable_iterator_t
  255. >
  256. {
  257. template <class Value>
  258. struct archetype
  259. {
  260. typedef typename remove_cv<Value>::type value_type;
  261. typedef Value reference;
  262. typedef Value* pointer;
  263. value_type operator*() const { return static_object<value_type>::get(); }
  264. detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
  265. };
  266. };
  267. template <>
  268. struct iterator_access_archetype_impl<
  269. archetypes::writable_iterator_t
  270. >
  271. {
  272. template <class Value>
  273. struct archetype
  274. {
  275. BOOST_STATIC_ASSERT(!is_const<Value>::value);
  276. typedef void value_type;
  277. typedef void reference;
  278. typedef void pointer;
  279. detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
  280. };
  281. };
  282. template <>
  283. struct iterator_access_archetype_impl<
  284. archetypes::readable_writable_iterator_t
  285. >
  286. {
  287. template <class Value>
  288. struct archetype
  289. : public virtual iterator_access_archetype<
  290. Value, archetypes::readable_iterator_t
  291. >
  292. {
  293. typedef detail::read_write_proxy<Value> reference;
  294. detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
  295. };
  296. };
  297. template <>
  298. struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
  299. {
  300. template <class Value>
  301. struct archetype
  302. : public virtual iterator_access_archetype<
  303. Value, archetypes::readable_iterator_t
  304. >
  305. {
  306. typedef Value& reference;
  307. Value& operator*() const { return static_object<Value>::get(); }
  308. Value* operator->() const { return 0; }
  309. };
  310. };
  311. template <>
  312. struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
  313. {
  314. template <class Value>
  315. struct archetype
  316. : public virtual iterator_access_archetype<
  317. Value, archetypes::readable_lvalue_iterator_t
  318. >
  319. {
  320. BOOST_STATIC_ASSERT((!is_const<Value>::value));
  321. };
  322. };
  323. template <class Value, class AccessCategory, class TraversalCategory>
  324. struct iterator_archetype;
  325. template <class Value, class AccessCategory, class TraversalCategory>
  326. struct traversal_archetype_base
  327. : detail::operator_brackets<
  328. typename remove_cv<Value>::type
  329. , AccessCategory
  330. , TraversalCategory
  331. >
  332. , detail::traversal_archetype_<
  333. iterator_archetype<Value, AccessCategory, TraversalCategory>
  334. , Value
  335. , TraversalCategory
  336. >
  337. {
  338. };
  339. namespace detail
  340. {
  341. template <class Value, class AccessCategory, class TraversalCategory>
  342. struct iterator_archetype_base
  343. : iterator_access_archetype<Value, AccessCategory>
  344. , traversal_archetype_base<Value, AccessCategory, TraversalCategory>
  345. {
  346. typedef iterator_access_archetype<Value, AccessCategory> access;
  347. typedef typename detail::facade_iterator_category<
  348. TraversalCategory
  349. , typename mpl::eval_if<
  350. archetypes::has_access<
  351. AccessCategory, archetypes::writable_iterator_t
  352. >
  353. , remove_const<Value>
  354. , add_const<Value>
  355. >::type
  356. , typename access::reference
  357. >::type iterator_category;
  358. // Needed for some broken libraries (see below)
  359. struct workaround_iterator_base
  360. {
  361. typedef typename iterator_archetype_base::iterator_category iterator_category;
  362. typedef Value value_type;
  363. typedef typename traversal_archetype_base<
  364. Value, AccessCategory, TraversalCategory
  365. >::difference_type difference_type;
  366. typedef typename access::pointer pointer;
  367. typedef typename access::reference reference;
  368. };
  369. };
  370. }
  371. template <class Value, class AccessCategory, class TraversalCategory>
  372. struct iterator_archetype
  373. : public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
  374. // These broken libraries require derivation from std::iterator
  375. // (or related magic) in order to handle iter_swap and other
  376. // iterator operations
  377. # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
  378. || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
  379. , public detail::iterator_archetype_base<
  380. Value, AccessCategory, TraversalCategory
  381. >::workaround_iterator_base
  382. # endif
  383. {
  384. // Derivation from std::iterator above caused references to nested
  385. // types to be ambiguous, so now we have to redeclare them all
  386. // here.
  387. # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
  388. || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
  389. typedef detail::iterator_archetype_base<
  390. Value,AccessCategory,TraversalCategory
  391. > base;
  392. typedef typename base::value_type value_type;
  393. typedef typename base::reference reference;
  394. typedef typename base::pointer pointer;
  395. typedef typename base::difference_type difference_type;
  396. typedef typename base::iterator_category iterator_category;
  397. # endif
  398. iterator_archetype() { }
  399. iterator_archetype(iterator_archetype const& x)
  400. : detail::iterator_archetype_base<
  401. Value
  402. , AccessCategory
  403. , TraversalCategory
  404. >(x)
  405. {}
  406. iterator_archetype& operator=(iterator_archetype const&)
  407. { return *this; }
  408. # if 0
  409. // Optional conversion from mutable
  410. iterator_archetype(
  411. iterator_archetype<
  412. typename detail::convertible_type<Value>::type
  413. , AccessCategory
  414. , TraversalCategory> const&
  415. );
  416. # endif
  417. };
  418. } // namespace iterators
  419. // Backward compatibility names
  420. namespace iterator_archetypes = iterators::archetypes;
  421. using iterators::access_archetype;
  422. using iterators::traversal_archetype;
  423. using iterators::iterator_archetype;
  424. using iterators::undefined;
  425. using iterators::iterator_access_archetype_impl;
  426. using iterators::traversal_archetype_base;
  427. } // namespace boost
  428. #endif // BOOST_ITERATOR_ARCHETYPES_HPP