sl@0: // Copyright David Abrahams 2002. sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: #ifndef ITERATOR_DWA2002512_HPP sl@0: # define ITERATOR_DWA2002512_HPP sl@0: sl@0: # include sl@0: sl@0: # include sl@0: # include sl@0: # include sl@0: sl@0: # include sl@0: # include sl@0: sl@0: # include sl@0: # include sl@0: sl@0: namespace boost { namespace python { sl@0: sl@0: namespace detail sl@0: { sl@0: // Adds an additional layer of binding to sl@0: // objects::make_iterator(...), which allows us to pass member sl@0: // function and member data pointers. sl@0: template sl@0: inline object make_iterator( sl@0: Accessor1 get_start sl@0: , Accessor2 get_finish sl@0: , NextPolicies next_policies sl@0: , Target&(*)() sl@0: ) sl@0: { sl@0: return objects::make_iterator_function( sl@0: boost::protect(boost::bind(get_start, _1)) sl@0: , boost::protect(boost::bind(get_finish, _1)) sl@0: , next_policies sl@0: ); sl@0: } sl@0: sl@0: // Guts of template class iterators<>, below. sl@0: template sl@0: struct iterators_impl sl@0: { sl@0: template sl@0: struct apply sl@0: { sl@0: typedef typename T::iterator iterator; sl@0: static iterator begin(T& x) { return x.begin(); } sl@0: static iterator end(T& x) { return x.end(); } sl@0: }; sl@0: }; sl@0: sl@0: template <> sl@0: struct iterators_impl sl@0: { sl@0: template sl@0: struct apply sl@0: { sl@0: typedef typename T::const_iterator iterator; sl@0: static iterator begin(T& x) { return x.begin(); } sl@0: static iterator end(T& x) { return x.end(); } sl@0: }; sl@0: }; sl@0: } sl@0: sl@0: // An "ordinary function generator" which contains static begin(x) and sl@0: // end(x) functions that invoke T::begin() and T::end(), respectively. sl@0: template sl@0: struct iterators sl@0: : detail::iterators_impl< sl@0: boost::is_const::value sl@0: >::template apply sl@0: { sl@0: }; sl@0: sl@0: // Create an iterator-building function which uses the given sl@0: // accessors. Deduce the Target type from the accessors. The iterator sl@0: // returns copies of the inderlying elements. sl@0: template sl@0: object range(Accessor1 start, Accessor2 finish) sl@0: { sl@0: return detail::make_iterator( sl@0: start, finish sl@0: , objects::default_iterator_call_policies() sl@0: , detail::target(start) sl@0: ); sl@0: } sl@0: sl@0: // Create an iterator-building function which uses the given accessors sl@0: // and next() policies. Deduce the Target type. sl@0: template sl@0: object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) sl@0: { sl@0: return detail::make_iterator(start, finish, NextPolicies(), detail::target(start)); sl@0: } sl@0: sl@0: // Create an iterator-building function which uses the given accessors sl@0: // and next() policies, operating on the given Target type sl@0: template sl@0: object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) sl@0: { sl@0: // typedef typename add_reference::type target; sl@0: return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0); sl@0: } sl@0: sl@0: // A Python callable object which produces an iterator traversing sl@0: // [x.begin(), x.end()), where x is an instance of the Container sl@0: // type. NextPolicies are used as the CallPolicies for the iterator's sl@0: // next() function. sl@0: template sl@0: struct iterator : object sl@0: { sl@0: iterator() sl@0: : object( sl@0: python::range( sl@0: &iterators::begin, &iterators::end sl@0: )) sl@0: { sl@0: } sl@0: }; sl@0: sl@0: }} // namespace boost::python sl@0: sl@0: #endif // ITERATOR_DWA2002512_HPP