iterator.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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/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. using namespace boost::placeholders;
  38. return objects::make_iterator_function<Target>(
  39. boost::protect(boost::bind(get_start, _1))
  40. , boost::protect(boost::bind(get_finish, _1))
  41. , next_policies
  42. );
  43. }
  44. // Guts of template class iterators<>, below.
  45. template <bool const_ = false>
  46. struct iterators_impl
  47. {
  48. template <class T>
  49. struct apply
  50. {
  51. typedef typename T::iterator iterator;
  52. static iterator begin(T& x) { return x.begin(); }
  53. static iterator end(T& x) { return x.end(); }
  54. };
  55. };
  56. template <>
  57. struct iterators_impl<true>
  58. {
  59. template <class T>
  60. struct apply
  61. {
  62. typedef typename T::const_iterator iterator;
  63. static iterator begin(T& x) { return x.begin(); }
  64. static iterator end(T& x) { return x.end(); }
  65. };
  66. };
  67. }
  68. // An "ordinary function generator" which contains static begin(x) and
  69. // end(x) functions that invoke T::begin() and T::end(), respectively.
  70. template <class T>
  71. struct iterators
  72. : detail::iterators_impl<
  73. detail::is_const<T>::value
  74. >::template apply<T>
  75. {
  76. };
  77. // Create an iterator-building function which uses the given
  78. // accessors. Deduce the Target type from the accessors. The iterator
  79. // returns copies of the inderlying elements.
  80. template <class Accessor1, class Accessor2>
  81. object range(Accessor1 start, Accessor2 finish)
  82. {
  83. return detail::make_iterator(
  84. start, finish
  85. , objects::default_iterator_call_policies()
  86. , detail::target(start)
  87. );
  88. }
  89. // Create an iterator-building function which uses the given accessors
  90. // and next() policies. Deduce the Target type.
  91. template <class NextPolicies, class Accessor1, class Accessor2>
  92. object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0)
  93. {
  94. return detail::make_iterator(start, finish, NextPolicies(), detail::target(start));
  95. }
  96. // Create an iterator-building function which uses the given accessors
  97. // and next() policies, operating on the given Target type
  98. template <class NextPolicies, class Target, class Accessor1, class Accessor2>
  99. object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type<Target>* = 0)
  100. {
  101. // typedef typename add_reference<Target>::type target;
  102. return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0);
  103. }
  104. // A Python callable object which produces an iterator traversing
  105. // [x.begin(), x.end()), where x is an instance of the Container
  106. // type. NextPolicies are used as the CallPolicies for the iterator's
  107. // next() function.
  108. template <class Container
  109. , class NextPolicies = objects::default_iterator_call_policies>
  110. struct iterator : object
  111. {
  112. iterator()
  113. : object(
  114. python::range<NextPolicies>(
  115. &iterators<Container>::begin, &iterators<Container>::end
  116. ))
  117. {
  118. }
  119. };
  120. }} // namespace boost::python
  121. #endif // ITERATOR_DWA2002512_HPP