os/ossrv/ossrv_pub/boost_apis/boost/python/iterator.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright David Abrahams 2002.
sl@0
     2
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
     3
// accompanying file LICENSE_1_0.txt or copy at
sl@0
     4
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     5
#ifndef ITERATOR_DWA2002512_HPP
sl@0
     6
# define ITERATOR_DWA2002512_HPP
sl@0
     7
sl@0
     8
# include <boost/python/detail/prefix.hpp>
sl@0
     9
sl@0
    10
# include <boost/python/detail/target.hpp>
sl@0
    11
# include <boost/python/object/iterator.hpp>
sl@0
    12
# include <boost/python/object_core.hpp>
sl@0
    13
sl@0
    14
# include <boost/type_traits/cv_traits.hpp>
sl@0
    15
# include <boost/type_traits/transform_traits.hpp>
sl@0
    16
sl@0
    17
# include <boost/bind.hpp>
sl@0
    18
# include <boost/bind/protect.hpp>
sl@0
    19
sl@0
    20
namespace boost { namespace python { 
sl@0
    21
sl@0
    22
namespace detail
sl@0
    23
{
sl@0
    24
  // Adds an additional layer of binding to
sl@0
    25
  // objects::make_iterator(...), which allows us to pass member
sl@0
    26
  // function and member data pointers.
sl@0
    27
  template <class Target, class Accessor1, class Accessor2, class NextPolicies>
sl@0
    28
  inline object make_iterator(
sl@0
    29
      Accessor1 get_start
sl@0
    30
    , Accessor2 get_finish
sl@0
    31
    , NextPolicies next_policies
sl@0
    32
    , Target&(*)()
sl@0
    33
  )
sl@0
    34
  {
sl@0
    35
      return objects::make_iterator_function<Target>(
sl@0
    36
          boost::protect(boost::bind(get_start, _1))
sl@0
    37
        , boost::protect(boost::bind(get_finish, _1))
sl@0
    38
        , next_policies
sl@0
    39
      );
sl@0
    40
  }
sl@0
    41
sl@0
    42
  // Guts of template class iterators<>, below.
sl@0
    43
  template <bool const_ = false>
sl@0
    44
  struct iterators_impl
sl@0
    45
  {
sl@0
    46
      template <class T>
sl@0
    47
      struct apply
sl@0
    48
      {
sl@0
    49
          typedef typename T::iterator iterator;
sl@0
    50
          static iterator begin(T& x) { return x.begin(); }
sl@0
    51
          static iterator end(T& x) { return x.end(); }
sl@0
    52
      };
sl@0
    53
  };
sl@0
    54
sl@0
    55
  template <>
sl@0
    56
  struct iterators_impl<true>
sl@0
    57
  {
sl@0
    58
      template <class T>
sl@0
    59
      struct apply
sl@0
    60
      {
sl@0
    61
          typedef typename T::const_iterator iterator;
sl@0
    62
          static iterator begin(T& x) { return x.begin(); }
sl@0
    63
          static iterator end(T& x) { return x.end(); }
sl@0
    64
      };
sl@0
    65
  };
sl@0
    66
}
sl@0
    67
sl@0
    68
// An "ordinary function generator" which contains static begin(x) and
sl@0
    69
// end(x) functions that invoke T::begin() and T::end(), respectively.
sl@0
    70
template <class T>
sl@0
    71
struct iterators
sl@0
    72
    : detail::iterators_impl<
sl@0
    73
        boost::is_const<T>::value
sl@0
    74
      >::template apply<T>
sl@0
    75
{
sl@0
    76
};
sl@0
    77
sl@0
    78
// Create an iterator-building function which uses the given
sl@0
    79
// accessors. Deduce the Target type from the accessors. The iterator
sl@0
    80
// returns copies of the inderlying elements.
sl@0
    81
template <class Accessor1, class Accessor2>
sl@0
    82
object range(Accessor1 start, Accessor2 finish)
sl@0
    83
{
sl@0
    84
    return detail::make_iterator(
sl@0
    85
        start, finish
sl@0
    86
      , objects::default_iterator_call_policies()
sl@0
    87
      , detail::target(start)
sl@0
    88
    );
sl@0
    89
}
sl@0
    90
sl@0
    91
// Create an iterator-building function which uses the given accessors
sl@0
    92
// and next() policies. Deduce the Target type.
sl@0
    93
template <class NextPolicies, class Accessor1, class Accessor2>
sl@0
    94
object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0)
sl@0
    95
{
sl@0
    96
    return detail::make_iterator(start, finish, NextPolicies(), detail::target(start));
sl@0
    97
}
sl@0
    98
sl@0
    99
// Create an iterator-building function which uses the given accessors
sl@0
   100
// and next() policies, operating on the given Target type
sl@0
   101
template <class NextPolicies, class Target, class Accessor1, class Accessor2>
sl@0
   102
object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type<Target>* = 0)
sl@0
   103
{
sl@0
   104
    // typedef typename add_reference<Target>::type target;
sl@0
   105
    return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0);
sl@0
   106
}
sl@0
   107
sl@0
   108
// A Python callable object which produces an iterator traversing
sl@0
   109
// [x.begin(), x.end()), where x is an instance of the Container
sl@0
   110
// type. NextPolicies are used as the CallPolicies for the iterator's
sl@0
   111
// next() function.
sl@0
   112
template <class Container
sl@0
   113
          , class NextPolicies = objects::default_iterator_call_policies>
sl@0
   114
struct iterator : object
sl@0
   115
{
sl@0
   116
    iterator()
sl@0
   117
        : object(
sl@0
   118
            python::range<NextPolicies>(
sl@0
   119
                &iterators<Container>::begin, &iterators<Container>::end
sl@0
   120
                ))
sl@0
   121
    {
sl@0
   122
    }
sl@0
   123
};
sl@0
   124
sl@0
   125
}} // namespace boost::python
sl@0
   126
sl@0
   127
#endif // ITERATOR_DWA2002512_HPP