iterator.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright David Abrahams 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 ITERATOR_DWA2002512_HPP
  6. # define ITERATOR_DWA2002512_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/detail/target.hpp>
  9. # include <boost/python/detail/type_traits.hpp>
  10. # include <boost/python/object/iterator.hpp>
  11. # include <boost/python/object_core.hpp>
  12. # if defined(BOOST_MSVC) && (BOOST_MSVC == 1400) /*
  13. > warning C4180: qualifier applied to function type has no meaning; ignored
  14. Peter Dimov wrote:
  15. This warning is caused by an overload resolution bug in VC8 that cannot be
  16. worked around and will probably not be fixed by MS in the VC8 line. The
  17. problematic overload is only instantiated and never called, and the code
  18. works correctly. */
  19. # pragma warning(disable: 4180)
  20. # endif
  21. # include <boost/bind.hpp>
  22. # include <boost/bind/protect.hpp>
  23. namespace boost { namespace python {
  24. namespace detail
  25. {
  26. // Adds an additional layer of binding to
  27. // objects::make_iterator(...), which allows us to pass member
  28. // function and member data pointers.
  29. template <class Target, class Accessor1, class Accessor2, class NextPolicies>
  30. inline object make_iterator(
  31. Accessor1 get_start
  32. , Accessor2 get_finish
  33. , NextPolicies next_policies
  34. , Target&(*)()
  35. )
  36. {
  37. return objects::make_iterator_function<Target>(
  38. boost::protect(boost::bind(get_start, _1))
  39. , boost::protect(boost::bind(get_finish, _1))
  40. , next_policies
  41. );
  42. }
  43. // Guts of template class iterators<>, below.
  44. template <bool const_ = false>
  45. struct iterators_impl
  46. {
  47. template <class T>
  48. struct apply
  49. {
  50. typedef typename T::iterator iterator;
  51. static iterator begin(T& x) { return x.begin(); }
  52. static iterator end(T& x) { return x.end(); }
  53. };
  54. };
  55. template <>
  56. struct iterators_impl<true>
  57. {
  58. template <class T>
  59. struct apply
  60. {
  61. typedef typename T::const_iterator iterator;
  62. static iterator begin(T& x) { return x.begin(); }
  63. static iterator end(T& x) { return x.end(); }
  64. };
  65. };
  66. }
  67. // An "ordinary function generator" which contains static begin(x) and
  68. // end(x) functions that invoke T::begin() and T::end(), respectively.
  69. template <class T>
  70. struct iterators
  71. : detail::iterators_impl<
  72. detail::is_const<T>::value
  73. >::template apply<T>
  74. {
  75. };
  76. // Create an iterator-building function which uses the given
  77. // accessors. Deduce the Target type from the accessors. The iterator
  78. // returns copies of the inderlying elements.
  79. template <class Accessor1, class Accessor2>
  80. object range(Accessor1 start, Accessor2 finish)
  81. {
  82. return detail::make_iterator(
  83. start, finish
  84. , objects::default_iterator_call_policies()
  85. , detail::target(start)
  86. );
  87. }
  88. // Create an iterator-building function which uses the given accessors
  89. // and next() policies. Deduce the Target type.
  90. template <class NextPolicies, class Accessor1, class Accessor2>
  91. object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0)
  92. {
  93. return detail::make_iterator(start, finish, NextPolicies(), detail::target(start));
  94. }
  95. // Create an iterator-building function which uses the given accessors
  96. // and next() policies, operating on the given Target type
  97. template <class NextPolicies, class Target, class Accessor1, class Accessor2>
  98. object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type<Target>* = 0)
  99. {
  100. // typedef typename add_reference<Target>::type target;
  101. return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0);
  102. }
  103. // A Python callable object which produces an iterator traversing
  104. // [x.begin(), x.end()), where x is an instance of the Container
  105. // type. NextPolicies are used as the CallPolicies for the iterator's
  106. // next() function.
  107. template <class Container
  108. , class NextPolicies = objects::default_iterator_call_policies>
  109. struct iterator : object
  110. {
  111. iterator()
  112. : object(
  113. python::range<NextPolicies>(
  114. &iterators<Container>::begin, &iterators<Container>::end
  115. ))
  116. {
  117. }
  118. };
  119. }} // namespace boost::python
  120. #endif // ITERATOR_DWA2002512_HPP