Chris@16: // Copyright David Abrahams 2002. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: #ifndef ITERATOR_DWA2002512_HPP Chris@16: # define ITERATOR_DWA2002512_HPP Chris@16: Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: Chris@16: # if defined(BOOST_MSVC) && (BOOST_MSVC == 1400) /* Chris@16: > warning C4180: qualifier applied to function type has no meaning; ignored Chris@16: Peter Dimov wrote: Chris@16: This warning is caused by an overload resolution bug in VC8 that cannot be Chris@16: worked around and will probably not be fixed by MS in the VC8 line. The Chris@16: problematic overload is only instantiated and never called, and the code Chris@16: works correctly. */ Chris@16: # pragma warning(disable: 4180) Chris@16: # endif Chris@16: Chris@16: # include Chris@16: # include Chris@16: Chris@16: namespace boost { namespace python { Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: // Adds an additional layer of binding to Chris@16: // objects::make_iterator(...), which allows us to pass member Chris@16: // function and member data pointers. Chris@16: template Chris@16: inline object make_iterator( Chris@16: Accessor1 get_start Chris@16: , Accessor2 get_finish Chris@16: , NextPolicies next_policies Chris@16: , Target&(*)() Chris@16: ) Chris@16: { Chris@16: return objects::make_iterator_function( Chris@16: boost::protect(boost::bind(get_start, _1)) Chris@16: , boost::protect(boost::bind(get_finish, _1)) Chris@16: , next_policies Chris@16: ); Chris@16: } Chris@16: Chris@16: // Guts of template class iterators<>, below. Chris@16: template Chris@16: struct iterators_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename T::iterator iterator; Chris@16: static iterator begin(T& x) { return x.begin(); } Chris@16: static iterator end(T& x) { return x.end(); } Chris@16: }; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct iterators_impl Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename T::const_iterator iterator; Chris@16: static iterator begin(T& x) { return x.begin(); } Chris@16: static iterator end(T& x) { return x.end(); } Chris@16: }; Chris@16: }; Chris@16: } Chris@16: Chris@16: // An "ordinary function generator" which contains static begin(x) and Chris@16: // end(x) functions that invoke T::begin() and T::end(), respectively. Chris@16: template Chris@16: struct iterators Chris@16: : detail::iterators_impl< Chris@16: boost::is_const::value Chris@16: >::template apply Chris@16: { Chris@16: }; Chris@16: Chris@16: // Create an iterator-building function which uses the given Chris@16: // accessors. Deduce the Target type from the accessors. The iterator Chris@16: // returns copies of the inderlying elements. Chris@16: template Chris@16: object range(Accessor1 start, Accessor2 finish) Chris@16: { Chris@16: return detail::make_iterator( Chris@16: start, finish Chris@16: , objects::default_iterator_call_policies() Chris@16: , detail::target(start) Chris@16: ); Chris@16: } Chris@16: Chris@16: // Create an iterator-building function which uses the given accessors Chris@16: // and next() policies. Deduce the Target type. Chris@16: template Chris@16: object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) Chris@16: { Chris@16: return detail::make_iterator(start, finish, NextPolicies(), detail::target(start)); Chris@16: } Chris@16: Chris@16: // Create an iterator-building function which uses the given accessors Chris@16: // and next() policies, operating on the given Target type Chris@16: template Chris@16: object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) Chris@16: { Chris@16: // typedef typename add_reference::type target; Chris@16: return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0); Chris@16: } Chris@16: Chris@16: // A Python callable object which produces an iterator traversing Chris@16: // [x.begin(), x.end()), where x is an instance of the Container Chris@16: // type. NextPolicies are used as the CallPolicies for the iterator's Chris@16: // next() function. Chris@16: template Chris@16: struct iterator : object Chris@16: { Chris@16: iterator() Chris@16: : object( Chris@16: python::range( Chris@16: &iterators::begin, &iterators::end Chris@16: )) Chris@16: { Chris@16: } Chris@16: }; Chris@16: Chris@16: }} // namespace boost::python Chris@16: Chris@16: #endif // ITERATOR_DWA2002512_HPP