source: NonGTP/Boost/boost/python/iterator.hpp @ 857

Revision 857, 4.0 KB checked in by igarcia, 19 years ago (diff)
RevLine 
[857]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
8# include <boost/python/detail/prefix.hpp>
9
10# include <boost/python/detail/target.hpp>
11# include <boost/python/object/iterator.hpp>
12# include <boost/python/object_core.hpp>
13
14# include <boost/type_traits/cv_traits.hpp>
15# include <boost/type_traits/transform_traits.hpp>
16
17# include <boost/bind.hpp>
18# include <boost/bind/protect.hpp>
19
20namespace boost { namespace python {
21
22namespace detail
23{
24  // Adds an additional layer of binding to
25  // objects::make_iterator(...), which allows us to pass member
26  // function and member data pointers.
27  template <class Target, class Accessor1, class Accessor2, class NextPolicies>
28  inline object make_iterator(
29      Accessor1 get_start
30    , Accessor2 get_finish
31    , NextPolicies next_policies
32    , Target&(*)()
33  )
34  {
35      return objects::make_iterator_function<Target>(
36          boost::protect(boost::bind(get_start, _1))
37        , boost::protect(boost::bind(get_finish, _1))
38        , next_policies
39      );
40  }
41
42  // Guts of template class iterators<>, below.
43  template <bool const_ = false>
44  struct iterators_impl
45  {
46      template <class T>
47      struct apply
48      {
49          typedef typename T::iterator iterator;
50          static iterator begin(T& x) { return x.begin(); }
51          static iterator end(T& x) { return x.end(); }
52      };
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
68// An "ordinary function generator" which contains static begin(x) and
69// end(x) functions that invoke T::begin() and T::end(), respectively.
70template <class T>
71struct iterators
72    : detail::iterators_impl<
73        boost::is_const<T>::value
74      >::template apply<T>
75{
76};
77
78// Create an iterator-building function which uses the given
79// accessors. Deduce the Target type from the accessors. The iterator
80// returns copies of the inderlying elements.
81template <class Accessor1, class Accessor2>
82object range(Accessor1 start, Accessor2 finish)
83{
84    return detail::make_iterator(
85        start, finish
86      , objects::default_iterator_call_policies()
87      , detail::target(start)
88    );
89}
90
91// Create an iterator-building function which uses the given accessors
92// and next() policies. Deduce the Target type.
93template <class NextPolicies, class Accessor1, class Accessor2>
94object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0)
95{
96    return detail::make_iterator(start, finish, NextPolicies(), detail::target(start));
97}
98
99// Create an iterator-building function which uses the given accessors
100// and next() policies, operating on the given Target type
101template <class NextPolicies, class Target, class Accessor1, class Accessor2>
102object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type<Target>* = 0)
103{
104    // typedef typename add_reference<Target>::type target;
105    return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0);
106}
107
108// A Python callable object which produces an iterator traversing
109// [x.begin(), x.end()), where x is an instance of the Container
110// type. NextPolicies are used as the CallPolicies for the iterator's
111// next() function.
112template <class Container
113          , class NextPolicies = objects::default_iterator_call_policies>
114struct iterator : object
115{
116    iterator()
117        : object(
118            python::range<NextPolicies>(
119                &iterators<Container>::begin, &iterators<Container>::end
120                ))
121    {
122    }
123};
124
125}} // namespace boost::python
126
127#endif // ITERATOR_DWA2002512_HPP
Note: See TracBrowser for help on using the repository browser.