Boost-Geometry-Utils

 view release on metacpan or  search on metacpan

src/boost/python/object/iterator.hpp  view on Meta::CPAN

struct iterator_range
{
    iterator_range(object sequence, Iterator start, Iterator finish);

    typedef boost::detail::iterator_traits<Iterator> traits_t;

    struct next
    {
        typedef typename mpl::if_<
            is_reference<
                typename traits_t::reference
            >
          , typename traits_t::reference
          , typename traits_t::value_type
        >::type result_type;
        
        result_type
        operator()(iterator_range<NextPolicies,Iterator>& self)
        {
            if (self.m_start == self.m_finish)
                stop_iteration_error();
            return *self.m_start++;
        }

# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
        // CWPro8 has a codegen problem when this is an empty class
        int garbage;
# endif 
    };
    
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    // for compilers which can't deduce the value_type of pointers, we
    // have a special implementation of next.  This takes advantage of
    // the fact that T* results are treated like T& results by
    // Boost.Python's function wrappers.
    struct next_ptr
    {
        typedef Iterator result_type;
        
        result_type
        operator()(iterator_range<NextPolicies,Iterator>& self)
        {
            if (self.m_start == self.m_finish)
                stop_iteration_error();
            return self.m_start++;
        }
    };
    
    typedef mpl::if_<
        is_same<
            boost::detail::please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<Iterator>
          , typename traits_t::value_type
        >
      , next_ptr
      , next
    >::type next_fn;
# else
    typedef next next_fn;
# endif
    
    object m_sequence; // Keeps the sequence alive while iterating.
    Iterator m_start;
    Iterator m_finish;
};

namespace detail
{
  // Get a Python class which contains the given iterator and
  // policies, creating it if necessary. Requires: NextPolicies is
  // default-constructible.
  template <class Iterator, class NextPolicies>
  object demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies())
  {
      typedef iterator_range<NextPolicies,Iterator> range_;

      // Check the registry. If one is already registered, return it.
      handle<> class_obj(
          objects::registered_class_object(python::type_id<range_>()));
        
      if (class_obj.get() != 0)
          return object(class_obj);

      typedef typename range_::next_fn next_fn;
      typedef typename next_fn::result_type result_type;
      
      return class_<range_>(name, no_init)
          .def("__iter__", identity_function())
          .def(
#if PY_VERSION_HEX >= 0x03000000
              "__next__"
#else
              "next"
#endif
            , make_function(
                next_fn()
              , policies
              , mpl::vector2<result_type,range_&>()
            ));
  }

  // A function object which builds an iterator_range.
  template <
      class Target
    , class Iterator
    , class Accessor1
    , class Accessor2
    , class NextPolicies
  >
  struct py_iter_
  {
      py_iter_(Accessor1 const& get_start, Accessor2 const& get_finish)
        : m_get_start(get_start)
        , m_get_finish(get_finish)
      {}
      
      // Extract an object x of the Target type from the first Python
      // argument, and invoke get_start(x)/get_finish(x) to produce
      // iterators, which are used to construct a new iterator_range<>
      // object that gets wrapped into a Python iterator.
      iterator_range<NextPolicies,Iterator>
      operator()(back_reference<Target&> x) const



( run in 2.599 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )