Warning, file /include/boost/python/object/iterator.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005 #ifndef ITERATOR_DWA2002510_HPP
0006 # define ITERATOR_DWA2002510_HPP
0007
0008 # include <boost/python/detail/prefix.hpp>
0009 # include <boost/python/detail/type_traits.hpp>
0010
0011 # include <boost/python/class.hpp>
0012 # include <boost/python/return_value_policy.hpp>
0013 # include <boost/python/return_by_value.hpp>
0014 # include <boost/python/handle.hpp>
0015 # include <boost/python/make_function.hpp>
0016
0017 # include <boost/python/object/iterator_core.hpp>
0018 # include <boost/python/object/class_detail.hpp>
0019 # include <boost/python/object/function_object.hpp>
0020
0021 # include <boost/mpl/vector/vector10.hpp>
0022 # include <boost/mpl/if.hpp>
0023
0024 # include <boost/python/detail/raw_pyobject.hpp>
0025
0026 # include <boost/type.hpp>
0027
0028 # include <iterator>
0029
0030 namespace boost { namespace python { namespace objects {
0031
0032
0033
0034
0035
0036
0037 typedef return_value_policy<return_by_value> default_iterator_call_policies;
0038
0039
0040 template <class NextPolicies, class Iterator>
0041 struct iterator_range
0042 {
0043 iterator_range(object sequence, Iterator start, Iterator finish);
0044
0045 typedef std::iterator_traits<Iterator> traits_t;
0046
0047 struct next
0048 {
0049 typedef typename mpl::if_<
0050 is_reference<
0051 typename traits_t::reference
0052 >
0053 , typename traits_t::reference
0054 , typename traits_t::value_type
0055 >::type result_type;
0056
0057 result_type
0058 operator()(iterator_range<NextPolicies,Iterator>& self)
0059 {
0060 if (self.m_start == self.m_finish)
0061 stop_iteration_error();
0062 return *self.m_start++;
0063 }
0064
0065 # if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
0066
0067 int garbage;
0068 # endif
0069 };
0070
0071 typedef next next_fn;
0072
0073 object m_sequence;
0074 Iterator m_start;
0075 Iterator m_finish;
0076 };
0077
0078 namespace detail
0079 {
0080
0081
0082
0083 template <class Iterator, class NextPolicies>
0084 object demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies())
0085 {
0086 typedef iterator_range<NextPolicies,Iterator> range_;
0087
0088
0089 handle<> class_obj(
0090 objects::registered_class_object(python::type_id<range_>()));
0091
0092 if (class_obj.get() != 0)
0093 return object(class_obj);
0094
0095 typedef typename range_::next_fn next_fn;
0096 typedef typename next_fn::result_type result_type;
0097
0098 return class_<range_>(name, no_init)
0099 .def("__iter__", identity_function())
0100 .def(
0101 #if PY_VERSION_HEX >= 0x03000000
0102 "__next__"
0103 #else
0104 "next"
0105 #endif
0106 , make_function(
0107 next_fn()
0108 , policies
0109 , mpl::vector2<result_type,range_&>()
0110 ));
0111 }
0112
0113
0114 template <
0115 class Target
0116 , class Iterator
0117 , class Accessor1
0118 , class Accessor2
0119 , class NextPolicies
0120 >
0121 struct py_iter_
0122 {
0123 py_iter_(Accessor1 const& get_start, Accessor2 const& get_finish)
0124 : m_get_start(get_start)
0125 , m_get_finish(get_finish)
0126 {}
0127
0128
0129
0130
0131
0132 iterator_range<NextPolicies,Iterator>
0133 operator()(back_reference<Target&> x) const
0134 {
0135
0136 detail::demand_iterator_class("iterator", (Iterator*)0, NextPolicies());
0137
0138 return iterator_range<NextPolicies,Iterator>(
0139 x.source()
0140 , m_get_start(x.get())
0141 , m_get_finish(x.get())
0142 );
0143 }
0144 private:
0145 Accessor1 m_get_start;
0146 Accessor2 m_get_finish;
0147 };
0148
0149 template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
0150 inline object make_iterator_function(
0151 Accessor1 const& get_start
0152 , Accessor2 const& get_finish
0153 , NextPolicies const&
0154 , Iterator const& (*)()
0155 , boost::type<Target>*
0156 , int
0157 )
0158 {
0159 return make_function(
0160 py_iter_<Target,Iterator,Accessor1,Accessor2,NextPolicies>(get_start, get_finish)
0161 , default_call_policies()
0162 , mpl::vector2<iterator_range<NextPolicies,Iterator>, back_reference<Target&> >()
0163 );
0164 }
0165
0166 template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
0167 inline object make_iterator_function(
0168 Accessor1 const& get_start
0169 , Accessor2 const& get_finish
0170 , NextPolicies const& next_policies
0171 , Iterator& (*)()
0172 , boost::type<Target>*
0173 , ...)
0174 {
0175 return make_iterator_function(
0176 get_start
0177 , get_finish
0178 , next_policies
0179 , (Iterator const&(*)())0
0180 , (boost::type<Target>*)0
0181 , 0
0182 );
0183 }
0184
0185 }
0186
0187
0188
0189
0190
0191
0192
0193 template <class Target, class NextPolicies, class Accessor1, class Accessor2>
0194 inline object make_iterator_function(
0195 Accessor1 const& get_start
0196 , Accessor2 const& get_finish
0197 , NextPolicies const& next_policies
0198 , boost::type<Target>* = 0
0199 )
0200 {
0201 typedef typename Accessor1::result_type iterator;
0202 typedef typename boost::python::detail::add_const<iterator>::type iterator_const;
0203 typedef typename boost::python::detail::add_lvalue_reference<iterator_const>::type iterator_cref;
0204
0205 return detail::make_iterator_function(
0206 get_start
0207 , get_finish
0208 , next_policies
0209 , (iterator_cref(*)())0
0210 , (boost::type<Target>*)0
0211 , 0
0212 );
0213 }
0214
0215
0216
0217
0218 template <class NextPolicies, class Iterator>
0219 inline iterator_range<NextPolicies,Iterator>::iterator_range(
0220 object sequence, Iterator start, Iterator finish)
0221 : m_sequence(sequence), m_start(start), m_finish(finish)
0222 {
0223 }
0224
0225 }}}
0226
0227 #endif