code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef NUMARRAY_DWA2002922_HPP
# define NUMARRAY_DWA2002922_HPP

# include <boost/python/detail/prefix.hpp>

# include <boost/python/tuple.hpp>
# include <boost/python/str.hpp>
# include <boost/preprocessor/iteration/local.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/repetition/enum.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>

namespace boost { namespace python { namespace numeric {

class array;

namespace aux
{
  struct BOOST_PYTHON_DECL array_base : object
  {
# define BOOST_PP_LOCAL_MACRO(n)                                \
      array_base(BOOST_PP_ENUM_PARAMS_Z(1, n, object const& x));
# define BOOST_PP_LOCAL_LIMITS (1, 7)
# include BOOST_PP_LOCAL_ITERATE()

      object argmax(long axis=-1);
      object argmin(long axis=-1);
      object argsort(long axis=-1);
      object astype(object const& type = object());
      void byteswap();
      object copy() const;
      object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const;
      void info() const;
      bool is_c_array() const;
      bool isbyteswapped() const;
      array new_(object type) const;
      void sort();
      object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const;
      object type() const;
      char typecode() const;

      object factory(
          object const& sequence = object()
        , object const& typecode = object()
        , bool copy = true
        , bool savespace = false
        , object type = object()
        , object shape = object());

      object getflat() const;
      long getrank() const;
      object getshape() const;
      bool isaligned() const;
      bool iscontiguous() const;
      long itemsize() const;
      long nelements() const;
      object nonzero() const;

      void put(object const& indices, object const& values);

      void ravel();

      object repeat(object const& repeats, long axis=0);

      void resize(object const& shape);

      void setflat(object const& flat);
      void setshape(object const& shape);

      void swapaxes(long axis1, long axis2);

      object take(object const& sequence, long axis = 0) const;

      void tofile(object const& file) const;

      str tostring() const;

      void transpose(object const& axes = object());

      object view() const;

   public: // implementation detail - do not touch.
      BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array_base, object);
  };

  struct BOOST_PYTHON_DECL array_object_manager_traits
  {
      static bool check(PyObject* obj);
      static detail::new_non_null_reference adopt(PyObject* obj);
      static PyTypeObject const* get_pytype() ;
  };
} // namespace aux

class array : public aux::array_base
{
    typedef aux::array_base base;
 public:

    object astype() { return base::astype(); }

    template <class Type>
    object astype(Type const& type_)
    {
        return base::astype(object(type_));
    }

    template <class Type>
    array new_(Type const& type_) const
    {
        return base::new_(object(type_));
    }

    template <class Sequence>
    void resize(Sequence const& x)
    {
        base::resize(object(x));
    }

# define BOOST_PP_LOCAL_MACRO(n)                                \
      void resize(BOOST_PP_ENUM_PARAMS_Z(1, n, long x))              \
      {                                                         \
          resize(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x)));       \
      }
# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY)
# include BOOST_PP_LOCAL_ITERATE()

    template <class Sequence>
    void setshape(Sequence const& x)
    {
        base::setshape(object(x));
    }

# define BOOST_PP_LOCAL_MACRO(n)                                \
    void setshape(BOOST_PP_ENUM_PARAMS_Z(1, n, long x))              \
    {                                                           \
        setshape(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x)));       \
    }
# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY)
# include BOOST_PP_LOCAL_ITERATE()

    template <class Indices, class Values>
    void put(Indices const& indices, Values const& values)
    {
        base::put(object(indices), object(values));
    }

    template <class Sequence>
    object take(Sequence const& sequence, long axis = 0)
    {
        return base::take(object(sequence), axis);
    }

    template <class File>
    void tofile(File const& f) const
    {
        base::tofile(object(f));
    }

    object factory()
    {
        return base::factory();
    }

    template <class Sequence>
    object factory(Sequence const& sequence)
    {
        return base::factory(object(sequence));
    }

    template <class Sequence, class Typecode>
    object factory(
        Sequence const& sequence
      , Typecode const& typecode_
      , bool copy = true
      , bool savespace = false
    )
    {
        return base::factory(object(sequence), object(typecode_), copy, savespace);
    }

    template <class Sequence, class Typecode, class Type>
    object factory(
        Sequence const& sequence
      , Typecode const& typecode_
      , bool copy
      , bool savespace
      , Type const& type
    )
    {
        return base::factory(object(sequence), object(typecode_), copy, savespace, object(type));
    }

    template <class Sequence, class Typecode, class Type, class Shape>
    object factory(
        Sequence const& sequence
      , Typecode const& typecode_
      , bool copy
      , bool savespace
      , Type const& type
      , Shape const& shape
    )
    {
        return base::factory(object(sequence), object(typecode_), copy, savespace, object(type), object(shape));
    }

# define BOOST_PYTHON_ENUM_AS_OBJECT(z, n, x) object(BOOST_PP_CAT(x,n))
# define BOOST_PP_LOCAL_MACRO(n)                                        \
    template <BOOST_PP_ENUM_PARAMS_Z(1, n, class T)>                    \
    explicit array(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, n, T, const& x))    \
    : base(BOOST_PP_ENUM_1(n, BOOST_PYTHON_ENUM_AS_OBJECT, x))          \
    {}
# define BOOST_PP_LOCAL_LIMITS (1, 7)
# include BOOST_PP_LOCAL_ITERATE()
# undef BOOST_PYTHON_AS_OBJECT

    static BOOST_PYTHON_DECL void set_module_and_type(char const* package_name = 0, char const* type_attribute_name = 0);
    static BOOST_PYTHON_DECL std::string get_module_name();

 public: // implementation detail -- for internal use only
    BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array, base);
};

} // namespace boost::python::numeric

namespace converter
{
  template <>
  struct object_manager_traits< numeric::array >
      : numeric::aux::array_object_manager_traits
  {
      BOOST_STATIC_CONSTANT(bool, is_specialized = true);
  };
}

}} // namespace boost::python

#endif // NUMARRAY_DWA2002922_HPP


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_hpp_
#define boost_python_numpy_hpp_

#include <boost/python/numpy/dtype.hpp>
#include <boost/python/numpy/ndarray.hpp>
#include <boost/python/numpy/scalars.hpp>
#include <boost/python/numpy/matrix.hpp>
#include <boost/python/numpy/ufunc.hpp>
#include <boost/python/numpy/invoke_matching.hpp>

namespace boost { namespace python { namespace numpy {

/**
 *  @brief Initialize the Numpy C-API
 *
 *  This must be called before using anything in boost.numpy;
 *  It should probably be the first line inside BOOST_PYTHON_MODULE.
 *
 *  @internal This just calls the Numpy C-API functions "import_array()"
 *            and "import_ufunc()", and then calls
 *            dtype::register_scalar_converters().
 */
void initialize(bool register_scalar_converters=true);

}}} // namespace boost::python::numpy

#endif

license: mit


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_dtype_hpp_
#define boost_python_numpy_dtype_hpp_

/**
 *  @file boost/python/numpy/dtype.hpp
 *  @brief Object manager for Python's numpy.dtype class.
 */

#include <boost/python.hpp>
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>

#include <boost/mpl/for_each.hpp>
#include <boost/type_traits/add_pointer.hpp>

namespace boost { namespace python { namespace numpy {

/**
 *  @brief A boost.python "object manager" (subclass of object) for numpy.dtype.
 *
 *  @todo This could have a lot more interesting accessors.
 */
class dtype : public object {
  static python::detail::new_reference convert(object::object_cref arg, bool align);
public:

  /// @brief Convert an arbitrary Python object to a data-type descriptor object.
  template <typename T>
  explicit dtype(T arg, bool align=false) : object(convert(arg, align)) {}

  /**
   *  @brief Get the built-in numpy dtype associated with the given scalar template type.
   *
   *  This is perhaps the most useful part of the numpy API: it returns the dtype object
   *  corresponding to a built-in C++ type.  This should work for any integer or floating point
   *  type supported by numpy, and will also work for std::complex if
   *  sizeof(std::complex<T>) == 2*sizeof(T).
   *
   *  It can also be useful for users to add explicit specializations for POD structs
   *  that return field-based dtypes.
   */
  template <typename T> static dtype get_builtin();

  /// @brief Return the size of the data type in bytes.
  int get_itemsize() const;

  /**
   *  @brief Compare two dtypes for equivalence.
   *
   *  This is more permissive than equality tests.  For instance, if long and int are the same
   *  size, the dtypes corresponding to each will be equivalent, but not equal.
   */
  friend bool equivalent(dtype const & a, dtype const & b);

  /**
   *  @brief Register from-Python converters for NumPy's built-in array scalar types.
   *
   *  This is usually called automatically by initialize(), and shouldn't be called twice
   *  (doing so just adds unused converters to the Boost.Python registry).
   */
  static void register_scalar_converters();

  BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dtype, object);

};

bool equivalent(dtype const & a, dtype const & b);

namespace detail
{

template <int bits, bool isUnsigned> dtype get_int_dtype();

template <int bits> dtype get_float_dtype();

template <int bits> dtype get_complex_dtype();

template <typename T, bool isInt=boost::is_integral<T>::value>
struct builtin_dtype;

template <typename T>
struct builtin_dtype<T,true> {
  static dtype get() { return get_int_dtype< 8*sizeof(T), boost::is_unsigned<T>::value >(); }
};

template <>
struct builtin_dtype<bool,true> {
  static dtype get();
};

template <typename T>
struct builtin_dtype<T,false> {
  static dtype get() { return get_float_dtype< 8*sizeof(T) >(); }
};

template <typename T>
struct builtin_dtype< std::complex<T>, false > {
  static dtype get() { return get_complex_dtype< 16*sizeof(T) >(); }
};

} // namespace detail

template <typename T>
inline dtype dtype::get_builtin() { return detail::builtin_dtype<T>::get(); }

} // namespace boost::python::numpy

namespace converter {
NUMPY_OBJECT_MANAGER_TRAITS(numpy::dtype);
}}} // namespace boost::python::converter

#endif


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_internal_hpp_
#define boost_python_numpy_internal_hpp_

/**
 *  @file boost/python/numpy/internal.hpp
 *  @brief Internal header file to include the Numpy C-API headers.
 *
 *  This should only be included by source files in the boost.numpy library itself.
 */

#include <boost/python.hpp>
#ifdef BOOST_PYTHON_NUMPY_INTERNAL
#define NO_IMPORT_ARRAY
#define NO_IMPORT_UFUNC
#else
#ifndef BOOST_PYTHON_NUMPY_INTERNAL_MAIN
ERROR_internal_hpp_is_for_internal_use_only
#endif
#endif
#define PY_ARRAY_UNIQUE_SYMBOL BOOST_NUMPY_ARRAY_API
#define PY_UFUNC_UNIQUE_SYMBOL BOOST_UFUNC_ARRAY_API
#include <numpy/arrayobject.h>
#include <numpy/ufuncobject.h>
#include <boost/python/numpy.hpp>

#define NUMPY_OBJECT_MANAGER_TRAITS_IMPL(pytype,manager)                \
    PyTypeObject const * object_manager_traits<manager>::get_pytype() { return &pytype; }

#endif


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_invoke_matching_hpp_
#define boost_python_numpy_invoke_matching_hpp_

/**
 *  @brief Template invocation based on dtype matching.
 */

#include <boost/python/numpy/dtype.hpp>
#include <boost/python/numpy/ndarray.hpp>
#include <boost/mpl/integral_c.hpp>

namespace boost { namespace python { namespace numpy {
namespace detail
{

struct add_pointer_meta
{
  template <typename T>
  struct apply
  {
    typedef typename boost::add_pointer<T>::type type;
  };

};

struct dtype_template_match_found {};
struct nd_template_match_found {};

template <typename Function>
struct dtype_template_invoker
{

  template <typename T>
  void operator()(T *) const
  {
    if (dtype::get_builtin<T>() == m_dtype)
    {
      m_func.Function::template apply<T>();
      throw dtype_template_match_found();
    }
  }

  dtype_template_invoker(dtype const & dtype_, Function func)
    : m_dtype(dtype_), m_func(func) {}

private:
  dtype const & m_dtype;
  Function m_func;
};

template <typename Function>
struct dtype_template_invoker< boost::reference_wrapper<Function> >
{

  template <typename T>
  void operator()(T *) const
  {
    if (dtype::get_builtin<T>() == m_dtype)
    {
      m_func.Function::template apply<T>();
      throw dtype_template_match_found();
    }
  }

  dtype_template_invoker(dtype const & dtype_, Function & func)
    : m_dtype(dtype_), m_func(func) {}

private:
  dtype const & m_dtype;
  Function & m_func;
};

template <typename Function>
struct nd_template_invoker
{
  template <int N>
  void operator()(boost::mpl::integral_c<int,N> *) const
  {
    if (m_nd == N)
    {
      m_func.Function::template apply<N>();
      throw nd_template_match_found();
    }
  }

  nd_template_invoker(int nd, Function func) : m_nd(nd), m_func(func) {}

private:
  int m_nd;
  Function m_func;
};

template <typename Function>
struct nd_template_invoker< boost::reference_wrapper<Function> >
{
  template <int N>
  void operator()(boost::mpl::integral_c<int,N> *) const
  {
    if (m_nd == N)
    {
      m_func.Function::template apply<N>();
      throw nd_template_match_found();
    }
  }

  nd_template_invoker(int nd, Function & func) : m_nd(nd), m_func(func) {}

private:
  int m_nd;
  Function & m_func;
};

} // namespace boost::python::numpy::detail

template <typename Sequence, typename Function>
void invoke_matching_nd(int nd, Function f)
{
  detail::nd_template_invoker<Function> invoker(nd, f);
  try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
  catch (detail::nd_template_match_found &) { return;}
  PyErr_SetString(PyExc_TypeError, "number of dimensions not found in template list.");
  python::throw_error_already_set();
}

template <typename Sequence, typename Function>
void invoke_matching_dtype(dtype const & dtype_, Function f)
{
  detail::dtype_template_invoker<Function> invoker(dtype_, f);
  try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
  catch (detail::dtype_template_match_found &) { return;}
  PyErr_SetString(PyExc_TypeError, "dtype not found in template list.");
  python::throw_error_already_set();
}

namespace detail
{

template <typename T, typename Function>
struct array_template_invoker_wrapper_2
{
  template <int N>
  void apply() const { m_func.Function::template apply<T,N>();}
  array_template_invoker_wrapper_2(Function & func) : m_func(func) {}

private:
  Function & m_func;
};

template <typename DimSequence, typename Function>
struct array_template_invoker_wrapper_1
{
  template <typename T>
  void apply() const { invoke_matching_nd<DimSequence>(m_nd, array_template_invoker_wrapper_2<T,Function>(m_func));}
  array_template_invoker_wrapper_1(int nd, Function & func) : m_nd(nd), m_func(func) {}

private:
  int m_nd;
  Function & m_func;
};

template <typename DimSequence, typename Function>
struct array_template_invoker_wrapper_1< DimSequence, boost::reference_wrapper<Function> >
  : public array_template_invoker_wrapper_1< DimSequence, Function >
{
  array_template_invoker_wrapper_1(int nd, Function & func)
    : array_template_invoker_wrapper_1< DimSequence, Function >(nd, func) {}
};

} // namespace boost::python::numpy::detail

template <typename TypeSequence, typename DimSequence, typename Function>
void invoke_matching_array(ndarray const & array_, Function f)
{
  detail::array_template_invoker_wrapper_1<DimSequence,Function> wrapper(array_.get_nd(), f);
  invoke_matching_dtype<TypeSequence>(array_.get_dtype(), wrapper);
}

}}} // namespace boost::python::numpy

#endif


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_matrix_hpp_
#define boost_python_numpy_matrix_hpp_

/**
 *  @brief Object manager for numpy.matrix.
 */

#include <boost/python.hpp>
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
#include <boost/python/numpy/ndarray.hpp>

namespace boost { namespace python { namespace numpy {

/**
 *  @brief A boost.python "object manager" (subclass of object) for numpy.matrix.
 *
 *  @internal numpy.matrix is defined in Python, so object_manager_traits<matrix>::get_pytype()
 *            is implemented by importing numpy and getting the "matrix" attribute of the module.
 *            We then just hope that doesn't get destroyed while we need it, because if we put
 *            a dynamic python object in a static-allocated boost::python::object or handle<>,
 *            bad things happen when Python shuts down.  I think this solution is safe, but I'd
 *            love to get that confirmed.
 */
class matrix : public ndarray
{
  static object construct(object_cref obj, dtype const & dt, bool copy);
  static object construct(object_cref obj, bool copy);
public:

  BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(matrix, ndarray);

  /// @brief Equivalent to "numpy.matrix(obj,dt,copy)" in Python.
  explicit matrix(object const & obj, dtype const & dt, bool copy=true)
    : ndarray(extract<ndarray>(construct(obj, dt, copy))) {}

  /// @brief Equivalent to "numpy.matrix(obj,copy=copy)" in Python.
  explicit matrix(object const & obj, bool copy=true)
    : ndarray(extract<ndarray>(construct(obj, copy))) {}

  /// \brief Return a view of the matrix with the given dtype.
  matrix view(dtype const & dt) const;

  /// \brief Copy the scalar (deep for all non-object fields).
  matrix copy() const;

  /// \brief Transpose the matrix.
  matrix transpose() const;

};

/**
 *  @brief CallPolicies that causes a function that returns a numpy.ndarray to
 *         return a numpy.matrix instead.
 */
template <typename Base = default_call_policies>
struct as_matrix : Base
{
  static PyObject * postcall(PyObject *, PyObject * result)
  {
    object a = object(handle<>(result));
    numpy::matrix m(a, false);
    Py_INCREF(m.ptr());
    return m.ptr();
  }
};

} // namespace boost::python::numpy

namespace converter
{

NUMPY_OBJECT_MANAGER_TRAITS(numpy::matrix);

}}} // namespace boost::python::converter

#endif


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_ndarray_hpp_
#define boost_python_numpy_ndarray_hpp_

/**
 *  @brief Object manager and various utilities for numpy.ndarray.
 */

#include <boost/python.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
#include <boost/python/numpy/dtype.hpp>
#include <vector>

namespace boost { namespace python { namespace numpy {

/**
 *  @brief A boost.python "object manager" (subclass of object) for numpy.ndarray.
 *
 *  @todo This could have a lot more functionality (like boost::python::numeric::array).
 *        Right now all that exists is what was needed to move raw data between C++ and Python.
 */
class ndarray : public object
{

  /**
   *  @brief An internal struct that's byte-compatible with PyArrayObject.
   *
   *  This is just a hack to allow inline access to this stuff while hiding numpy/arrayobject.h
   *  from the user.
   */
  struct array_struct
  {
    PyObject_HEAD
    char * data;
    int nd;
    Py_intptr_t * shape;
    Py_intptr_t * strides;
    PyObject * base;
    PyObject * descr;
    int flags;
    PyObject * weakreflist;
  };

  /// @brief Return the held Python object as an array_struct.
  array_struct * get_struct() const { return reinterpret_cast<array_struct*>(this->ptr()); }

public:

  /**
   *  @brief Enum to represent (some) of Numpy's internal flags.
   *
   *  These don't match the actual Numpy flag values; we can't get those without including
   *  numpy/arrayobject.h or copying them directly.  That's very unfortunate.
   *
   *  @todo I'm torn about whether this should be an enum.  It's very convenient to not
   *        make these simple integer values for overloading purposes, but the need to
   *        define every possible combination and custom bitwise operators is ugly.
   */
  enum bitflag
  {
    NONE=0x0, C_CONTIGUOUS=0x1, F_CONTIGUOUS=0x2, V_CONTIGUOUS=0x1|0x2,
    ALIGNED=0x4, WRITEABLE=0x8, BEHAVED=0x4|0x8,
    CARRAY_RO=0x1|0x4, CARRAY=0x1|0x4|0x8, CARRAY_MIS=0x1|0x8,
    FARRAY_RO=0x2|0x4, FARRAY=0x2|0x4|0x8, FARRAY_MIS=0x2|0x8,
    UPDATE_ALL=0x1|0x2|0x4, VARRAY=0x1|0x2|0x8, ALL=0x1|0x2|0x4|0x8
  };

  BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(ndarray, object);

  /// @brief Return a view of the scalar with the given dtype.
  ndarray view(dtype const & dt) const;

  /// @brief Copy the array, cast to a specified type.
  ndarray astype(dtype const & dt) const;

  /// @brief Copy the scalar (deep for all non-object fields).
  ndarray copy() const;

  /// @brief Return the size of the nth dimension.
  Py_intptr_t shape(int n) const { return get_shape()[n]; }

  /// @brief Return the stride of the nth dimension.
  Py_intptr_t strides(int n) const { return get_strides()[n]; }

  /**
   *  @brief Return the array's raw data pointer.
   *
   *  This returns char so stride math works properly on it.  It's pretty much
   *  expected that the user will have to reinterpret_cast it.
   */
  char * get_data() const { return get_struct()->data; }

  /// @brief Return the array's data-type descriptor object.
  dtype get_dtype() const;

  /// @brief Return the object that owns the array's data, or None if the array owns its own data.
  object get_base() const;

  /// @brief Set the object that owns the array's data.  Use with care.
  void set_base(object const & base);

  /// @brief Return the shape of the array as an array of integers (length == get_nd()).
  Py_intptr_t const * get_shape() const { return get_struct()->shape; }

  /// @brief Return the stride of the array as an array of integers (length == get_nd()).
  Py_intptr_t const * get_strides() const { return get_struct()->strides; }

  /// @brief Return the number of array dimensions.
  int get_nd() const { return get_struct()->nd; }

  /// @brief Return the array flags.
  bitflag get_flags() const;

  /// @brief Reverse the dimensions of the array.
  ndarray transpose() const;

  /// @brief Eliminate any unit-sized dimensions.
  ndarray squeeze() const;

  /// @brief Equivalent to self.reshape(*shape) in Python.
  ndarray reshape(python::tuple const & shape) const;

  /**
   *  @brief If the array contains only a single element, return it as an array scalar; otherwise return
   *         the array.
   *
   *  @internal This is simply a call to PyArray_Return();
   */
  object scalarize() const;
};

/**
 *  @brief Construct a new array with the given shape and data type, with data initialized to zero.
 */
ndarray zeros(python::tuple const & shape, dtype const & dt);
ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);

/**
 *  @brief Construct a new array with the given shape and data type, with data left uninitialized.
 */
ndarray empty(python::tuple const & shape, dtype const & dt);
ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);

/**
 *  @brief Construct a new array from an arbitrary Python sequence.
 *
 *  @todo This does't seem to handle ndarray subtypes the same way that "numpy.array" does in Python.
 */
ndarray array(object const & obj);
ndarray array(object const & obj, dtype const & dt);

namespace detail
{

ndarray from_data_impl(void * data,
		       dtype const & dt,
		       std::vector<Py_intptr_t> const & shape,
		       std::vector<Py_intptr_t> const & strides,
		       object const & owner,
		       bool writeable);

template <typename Container>
ndarray from_data_impl(void * data,
		       dtype const & dt,
		       Container shape,
		       Container strides,
		       object const & owner,
		       bool writeable,
		       typename boost::enable_if< boost::is_integral<typename Container::value_type> >::type * enabled = NULL)
{
  std::vector<Py_intptr_t> shape_(shape.begin(),shape.end());
  std::vector<Py_intptr_t> strides_(strides.begin(), strides.end());
  return from_data_impl(data, dt, shape_, strides_, owner, writeable);
}

ndarray from_data_impl(void * data,
		       dtype const & dt,
		       object const & shape,
		       object const & strides,
		       object const & owner,
		       bool writeable);

} // namespace boost::python::numpy::detail

/**
 *  @brief Construct a new ndarray object from a raw pointer.
 *
 *  @param[in] data    Raw pointer to the first element of the array.
 *  @param[in] dt      Data type descriptor.  Often retrieved with dtype::get_builtin().
 *  @param[in] shape   Shape of the array as STL container of integers; must have begin() and end().
 *  @param[in] strides Shape of the array as STL container of integers; must have begin() and end().
 *  @param[in] owner   An arbitray Python object that owns that data pointer.  The array object will
 *                     keep a reference to the object, and decrement it's reference count when the
 *                     array goes out of scope.  Pass None at your own peril.
 *
 *  @todo Should probably take ranges of iterators rather than actual container objects.
 */
template <typename Container>
inline ndarray from_data(void * data,
			 dtype const & dt,
			 Container shape,
			 Container strides,
			 python::object const & owner)
{
  return numpy::detail::from_data_impl(data, dt, shape, strides, owner, true);
}

/**
 *  @brief Construct a new ndarray object from a raw pointer.
 *
 *  @param[in] data    Raw pointer to the first element of the array.
 *  @param[in] dt      Data type descriptor.  Often retrieved with dtype::get_builtin().
 *  @param[in] shape   Shape of the array as STL container of integers; must have begin() and end().
 *  @param[in] strides Shape of the array as STL container of integers; must have begin() and end().
 *  @param[in] owner   An arbitray Python object that owns that data pointer.  The array object will
 *                     keep a reference to the object, and decrement it's reference count when the
 *                     array goes out of scope.  Pass None at your own peril.
 *
 *  This overload takes a const void pointer and sets the "writeable" flag of the array to false.
 *
 *  @todo Should probably take ranges of iterators rather than actual container objects.
 */
template <typename Container>
inline ndarray from_data(void const * data,
			 dtype const & dt,
			 Container shape,
			 Container strides,
			 python::object const & owner)
{
  return numpy::detail::from_data_impl(const_cast<void*>(data), dt, shape, strides, owner, false);
}

/**
 *  @brief Transform an arbitrary object into a numpy array with the given requirements.
 *
 *  @param[in] obj     An arbitrary python object to convert.  Arrays that meet the requirements
 *                     will be passed through directly.
 *  @param[in] dt      Data type descriptor.  Often retrieved with dtype::get_builtin().
 *  @param[in] nd_min  Minimum number of dimensions.
 *  @param[in] nd_max  Maximum number of dimensions.
 *  @param[in] flags   Bitwise OR of flags specifying additional requirements.
 */
ndarray from_object(object const & obj, dtype const & dt,
                    int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);

inline ndarray from_object(object const & obj, dtype const & dt,
                           int nd, ndarray::bitflag flags=ndarray::NONE)
{
  return from_object(obj, dt, nd, nd, flags);
}

inline ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE)
{
  return from_object(obj, dt, 0, 0, flags);
}

ndarray from_object(object const & obj, int nd_min, int nd_max,
                    ndarray::bitflag flags=ndarray::NONE);

inline ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE)
{
  return from_object(obj, nd, nd, flags);
}

inline ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE)
{
  return from_object(obj, 0, 0, flags);
}

inline ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b)
{
  return ndarray::bitflag(int(a) | int(b));
}

inline ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b)
{
  return ndarray::bitflag(int(a) & int(b));
}

} // namespace boost::python::numpy

namespace converter
{

NUMPY_OBJECT_MANAGER_TRAITS(numpy::ndarray);

}}} // namespace boost::python::converter

#endif


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_numpy_object_mgr_traits_hpp_
#define boost_python_numpy_numpy_object_mgr_traits_hpp_

/**
 *  @brief Macro that specializes object_manager_traits by requiring a
 *         source-file implementation of get_pytype().
 */

#define NUMPY_OBJECT_MANAGER_TRAITS(manager)                            \
template <>								\
struct object_manager_traits<manager>					\
{									\
  BOOST_STATIC_CONSTANT(bool, is_specialized = true);			\
  static inline python::detail::new_reference adopt(PyObject* x)	\
  {									\
    return python::detail::new_reference(python::pytype_check((PyTypeObject*)get_pytype(), x)); \
  }									\
  static bool check(PyObject* x)					\
  {									\
    return ::PyObject_IsInstance(x, (PyObject*)get_pytype());		\
  }									\
  static manager* checked_downcast(PyObject* x)				\
  {									\
    return python::downcast<manager>((checked_downcast_impl)(x, (PyTypeObject*)get_pytype())); \
  }									\
  static PyTypeObject const * get_pytype();				\
}

#endif


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_scalars_hpp_
#define boost_python_numpy_scalars_hpp_

/**
 *  @brief Object managers for array scalars (currently only numpy.void is implemented).
 */

#include <boost/python.hpp>
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
#include <boost/python/numpy/dtype.hpp>

namespace boost { namespace python { namespace numpy {

/**
 *  @brief A boost.python "object manager" (subclass of object) for numpy.void.
 *
 *  @todo This could have a lot more functionality.
 */
class void_ : public object
{
  static python::detail::new_reference convert(object_cref arg, bool align);
public:

  /**
   *  @brief Construct a new array scalar with the given size and void dtype.
   *
   *  Data is initialized to zero.  One can create a standalone scalar object
   *  with a certain dtype "dt" with:
   *  @code
   *  void_ scalar = void_(dt.get_itemsize()).view(dt);
   *  @endcode
   */
  explicit void_(Py_ssize_t size);

  BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(void_, object);

  /// @brief Return a view of the scalar with the given dtype.
  void_ view(dtype const & dt) const;

  /// @brief Copy the scalar (deep for all non-object fields).
  void_ copy() const;

};

} // namespace boost::python::numpy

namespace converter
{
NUMPY_OBJECT_MANAGER_TRAITS(numpy::void_);
}}} // namespace boost::python::converter

#endif


code:
// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_numpy_ufunc_hpp_
#define boost_python_numpy_ufunc_hpp_

/**
 *  @brief Utilities to create ufunc-like broadcasting functions out of C++ functors.
 */

#include <boost/python.hpp>
#include <boost/python/numpy/numpy_object_mgr_traits.hpp>
#include <boost/python/numpy/dtype.hpp>
#include <boost/python/numpy/ndarray.hpp>

namespace boost { namespace python { namespace numpy {

/**
 *  @brief A boost.python "object manager" (subclass of object) for PyArray_MultiIter.
 *
 *  multi_iter is a Python object, but a very low-level one.  It should generally only be used
 *  in loops of the form:
 *  @code
 *  while (iter.not_done()) {
 *      ...
 *      iter.next();
 *  }
 *  @endcode
 *
 *  @todo I can't tell if this type is exposed in Python anywhere; if it is, we should use that name.
 *        It's more dangerous than most object managers, however - maybe it actually belongs in
 *        a detail namespace?
 */
class multi_iter : public object
{
public:

  BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(multi_iter, object);

  /// @brief Increment the iterator.
  void next();

  /// @brief Check if the iterator is at its end.
  bool not_done() const;

  /// @brief Return a pointer to the element of the nth broadcasted array.
  char * get_data(int n) const;

  /// @brief Return the number of dimensions of the broadcasted array expression.
  int get_nd() const;

  /// @brief Return the shape of the broadcasted array expression as an array of integers.
  Py_intptr_t const * get_shape() const;

  /// @brief Return the shape of the broadcasted array expression in the nth dimension.
  Py_intptr_t shape(int n) const;

};

/// @brief Construct a multi_iter over a single sequence or scalar object.
multi_iter make_multi_iter(object const & a1);

/// @brief Construct a multi_iter by broadcasting two objects.
multi_iter make_multi_iter(object const & a1, object const & a2);

/// @brief Construct a multi_iter by broadcasting three objects.
multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);

/**
 *  @brief Helps wrap a C++ functor taking a single scalar argument as a broadcasting ufunc-like
 *         Python object.
 *
 *  Typical usage looks like this:
 *  @code
 *  struct TimesPI
 *  {
 *    typedef double argument_type;
 *    typedef double result_type;
 *    double operator()(double input) const { return input * M_PI; }
 *  };
 *
 *  BOOST_PYTHON_MODULE(example)
 *  {
 *    class_< TimesPI >("TimesPI")
 *      .def("__call__", unary_ufunc<TimesPI>::make());
 *  }
 *  @endcode
 *
 */
template <typename TUnaryFunctor,
          typename TArgument=typename TUnaryFunctor::argument_type,
          typename TResult=typename TUnaryFunctor::result_type>
struct unary_ufunc
{

  /**
   *  @brief A C++ function with object arguments that broadcasts its arguments before
   *         passing them to the underlying C++ functor.
   */
  static object call(TUnaryFunctor & self, object const & input, object const & output)
  {
    dtype in_dtype = dtype::get_builtin<TArgument>();
    dtype out_dtype = dtype::get_builtin<TResult>();
    ndarray in_array = from_object(input, in_dtype, ndarray::ALIGNED);
    ndarray out_array = (output != object()) ?
      from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
      : zeros(in_array.get_nd(), in_array.get_shape(), out_dtype);
    multi_iter iter = make_multi_iter(in_array, out_array);
    while (iter.not_done())
    {
      TArgument * argument = reinterpret_cast<TArgument*>(iter.get_data(0));
      TResult * result = reinterpret_cast<TResult*>(iter.get_data(1));
      *result = self(*argument);
      iter.next();
    }
    return out_array.scalarize();
  }

  /**
   *  @brief Construct a boost.python function object from call() with reasonable keyword names.
   *
   *  Users will often want to specify their own keyword names with the same signature, but this
   *  is a convenient shortcut.
   */
  static object make()
  {
    return make_function(call, default_call_policies(), (arg("input"), arg("output")=object()));
  }
};

/**
 *  @brief Helps wrap a C++ functor taking a pair of scalar arguments as a broadcasting ufunc-like
 *         Python object.
 *
 *  Typical usage looks like this:
 *  @code
 *  struct CosSum
 *  {
 *    typedef double first_argument_type;
 *    typedef double second_argument_type;
 *    typedef double result_type;
 *    double operator()(double input1, double input2) const { return std::cos(input1 + input2); }
 *  };
 *
 *  BOOST_PYTHON_MODULE(example)
 *  {
 *    class_< CosSum >("CosSum")
 *      .def("__call__", binary_ufunc<CosSum>::make());
 *  }
 *  @endcode
 *
 */
template <typename TBinaryFunctor,
          typename TArgument1=typename TBinaryFunctor::first_argument_type,
          typename TArgument2=typename TBinaryFunctor::second_argument_type,
          typename TResult=typename TBinaryFunctor::result_type>
struct binary_ufunc
{

  static object
  call(TBinaryFunctor & self, object const & input1, object const & input2,
       object const & output)
  {
    dtype in1_dtype = dtype::get_builtin<TArgument1>();
    dtype in2_dtype = dtype::get_builtin<TArgument2>();
    dtype out_dtype = dtype::get_builtin<TResult>();
    ndarray in1_array = from_object(input1, in1_dtype, ndarray::ALIGNED);
    ndarray in2_array = from_object(input2, in2_dtype, ndarray::ALIGNED);
    multi_iter iter = make_multi_iter(in1_array, in2_array);
    ndarray out_array = (output != object())
      ? from_object(output, out_dtype, ndarray::ALIGNED | ndarray::WRITEABLE)
      : zeros(iter.get_nd(), iter.get_shape(), out_dtype);
    iter = make_multi_iter(in1_array, in2_array, out_array);
    while (iter.not_done())
    {
      TArgument1 * argument1 = reinterpret_cast<TArgument1*>(iter.get_data(0));
      TArgument2 * argument2 = reinterpret_cast<TArgument2*>(iter.get_data(1));
      TResult * result = reinterpret_cast<TResult*>(iter.get_data(2));
      *result = self(*argument1, *argument2);
      iter.next();
    }
    return out_array.scalarize();
  }

  static object make()
  {
    return make_function(call, default_call_policies(),
			    (arg("input1"), arg("input2"), arg("output")=object()));
  }

};

} // namespace boost::python::numpy

namespace converter
{

NUMPY_OBJECT_MANAGER_TRAITS(numpy::multi_iter);

}}} // namespace boost::python::converter

#endif


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef OBJECT_DWA2002612_HPP
# define OBJECT_DWA2002612_HPP

# include <boost/python/ssize_t.hpp>
# include <boost/python/object_core.hpp>
# include <boost/python/object_attributes.hpp>
# include <boost/python/object_items.hpp>
# include <boost/python/object_slices.hpp>
# include <boost/python/object_operators.hpp>
# include <boost/python/converter/arg_to_python.hpp>

namespace boost { namespace python {

    inline ssize_t len(object const& obj)
    {
        ssize_t result = PyObject_Length(obj.ptr());
        if (PyErr_Occurred()) throw_error_already_set();
        return result;
    }

}} // namespace boost::python

#endif // OBJECT_DWA2002612_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ADD_TO_NAMESPACE_DWA200286_HPP
# define ADD_TO_NAMESPACE_DWA200286_HPP

# include <boost/python/object_fwd.hpp>

namespace boost { namespace python { namespace objects {

//
// A setattr that's "smart" about function overloading (and docstrings).
//
BOOST_PYTHON_DECL void add_to_namespace(
    object const& name_space, char const* name, object const& attribute);

BOOST_PYTHON_DECL void add_to_namespace(
    object const& name_space, char const* name, object const& attribute, char const* doc);

}}} // namespace boost::python::objects

#endif // ADD_TO_NAMESPACE_DWA200286_HPP


code:
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef CLASS_DWA20011214_HPP
# define CLASS_DWA20011214_HPP

# include <boost/python/detail/prefix.hpp>
# include <boost/python/object_core.hpp>
# include <boost/python/type_id.hpp>
# include <cstddef>

namespace boost { namespace python {

namespace objects {

struct BOOST_PYTHON_DECL class_base : python::api::object
{
    // constructor
    class_base(
        char const* name              // The name of the class

        , std::size_t num_types         // A list of class_ids. The first is the type
        , type_info const*const types    // this is wrapping. The rest are the types of
                                        // any bases.

        , char const* doc = 0           // Docstring, if any.
        );

    // Implementation detail. Hiding this in the private section would
    // require use of template friend declarations.
    void enable_pickling_(bool getstate_manages_dict);

 protected:
    void add_property(
        char const* name, object const& fget, char const* docstr);
    void add_property(char const* name,
        object const& fget, object const& fset, char const* docstr);

    void add_static_property(char const* name, object const& fget);
    void add_static_property(char const* name, object const& fget, object const& fset);

    // Retrieve the underlying object
    void setattr(char const* name, object const&);

    // Set a special attribute in the class which tells Boost.Python
    // to allocate extra bytes for embedded C++ objects in Python
    // instances.
    void set_instance_size(std::size_t bytes);

    // Set an __init__ function which throws an appropriate exception
    // for abstract classes.
    void def_no_init();

    // Effects:
    //  setattr(self, staticmethod(getattr(self, method_name)))
    void make_method_static(const char *method_name);
};

}}} // namespace boost::python::objects

#endif // CLASS_DWA20011214_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef CLASS_DETAIL_DWA200295_HPP
# define CLASS_DETAIL_DWA200295_HPP

# include <boost/python/handle.hpp>
# include <boost/python/type_id.hpp>

namespace boost { namespace python { namespace objects {

BOOST_PYTHON_DECL type_handle registered_class_object(type_info id);
BOOST_PYTHON_DECL type_handle class_metatype();
BOOST_PYTHON_DECL type_handle class_type();

}}} // namespace boost::python::object

#endif // CLASS_DETAIL_DWA200295_HPP


code:
// Copyright David Abrahams 2004.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef boost_python_object_class_metadata_hpp_
#define boost_python_object_class_metadata_hpp_

#include <boost/python/converter/shared_ptr_from_python.hpp>
#include <boost/python/object/inheritance.hpp>
#include <boost/python/object/class_wrapper.hpp>
#include <boost/python/object/make_instance.hpp>
#include <boost/python/object/value_holder.hpp>
#include <boost/python/object/pointer_holder.hpp>
#include <boost/python/object/make_ptr_instance.hpp>

#include <boost/python/detail/force_instantiate.hpp>
#include <boost/python/detail/not_specified.hpp>

#include <boost/python/has_back_reference.hpp>
#include <boost/python/bases.hpp>

#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_polymorphic.hpp>

#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/single_view.hpp>

#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>

#include <boost/type_traits/is_convertible.hpp>

#include <boost/noncopyable.hpp>
#include <boost/detail/workaround.hpp>

namespace boost { namespace python { namespace objects {

BOOST_PYTHON_DECL
void copy_class_object(type_info const& src, type_info const& dst);

//
// Support for registering base/derived relationships
//
template <class Derived>
struct register_base_of
{
    template <class Base>
    inline void operator()(Base*) const
    {
        BOOST_MPL_ASSERT_NOT((is_same<Base,Derived>));

        // Register the Base class
        register_dynamic_id<Base>();

        // Register the up-cast
        register_conversion<Derived,Base>(false);

        // Register the down-cast, if appropriate.
        this->register_downcast((Base*)0, is_polymorphic<Base>());
    }

 private:
    static inline void register_downcast(void*, mpl::false_) {}

    template <class Base>
    static inline void register_downcast(Base*, mpl::true_)
    {
        register_conversion<Base, Derived>(true);
    }

};

//
// Preamble of register_class.  Also used for callback classes, which
// need some registration of their own.
//

template <class T, class Bases>
inline void register_shared_ptr_from_python_and_casts(T*, Bases)
{
  // Constructor performs registration
  python::detail::force_instantiate(converter::shared_ptr_from_python<T, boost::shared_ptr>());
#if __cplusplus >= 201103L
  python::detail::force_instantiate(converter::shared_ptr_from_python<T, std::shared_ptr>());
#endif

  //
  // register all up/downcasts here.  We're using the alternate
  // interface to mpl::for_each to avoid an MSVC 6 bug.
  //
  register_dynamic_id<T>();
  mpl::for_each(register_base_of<T>(), (Bases*)0, (add_pointer<mpl::_>*)0);
}

//
// Helper for choosing the unnamed held_type argument
//
template <class T, class Prev>
struct select_held_type
  : mpl::if_<
        mpl::or_<
            python::detail::specifies_bases<T>
          , is_same<T,noncopyable>
        >
      , Prev
      , T
    >
{
};

template <
    class T // class being wrapped
  , class X1 // = detail::not_specified
  , class X2 // = detail::not_specified
  , class X3 // = detail::not_specified
>
struct class_metadata
{
    //
    // Calculate the unnamed template arguments
    //

    // held_type_arg -- not_specified, [a class derived from] T or a
    // smart pointer to [a class derived from] T.  Preserving
    // not_specified allows us to give class_<T,T> a back-reference.
    typedef typename select_held_type<
        X1
      , typename select_held_type<
            X2
          , typename select_held_type<
                X3
              , python::detail::not_specified
            >::type
        >::type
    >::type held_type_arg;

    // bases
    typedef typename python::detail::select_bases<
        X1
      , typename python::detail::select_bases<
            X2
          , typename python::detail::select_bases<
                X3
              , python::bases<>
            >::type
        >::type
    >::type bases;

    typedef mpl::or_<
        is_same<X1,noncopyable>
      , is_same<X2,noncopyable>
      , is_same<X3,noncopyable>
    > is_noncopyable;

    //
    // Holder computation.
    //

    // Compute the actual type that will be held in the Holder.
    typedef typename mpl::if_<
        is_same<held_type_arg,python::detail::not_specified>, T, held_type_arg
    >::type held_type;

    // Determine if the object will be held by value
    typedef mpl::bool_<is_convertible<held_type*,T*>::value> use_value_holder;

    // Compute the "wrapped type", that is, if held_type is a smart
    // pointer, we're talking about the pointee.
    typedef typename mpl::eval_if<
        use_value_holder
      , mpl::identity<held_type>
      , pointee<held_type>
    >::type wrapped;

    // Determine whether to use a "back-reference holder"
    typedef mpl::bool_<
        mpl::or_<
            has_back_reference<T>
          , is_same<held_type_arg,T>
          , is_base_and_derived<T,wrapped>
        >::value
    > use_back_reference;

    // Select the holder.
    typedef typename mpl::eval_if<
        use_back_reference
      , mpl::if_<
            use_value_holder
          , value_holder_back_reference<T, wrapped>
          , pointer_holder_back_reference<held_type,T>
        >
      , mpl::if_<
            use_value_holder
          , value_holder<T>
          , pointer_holder<held_type,wrapped>
        >
    >::type holder;

    inline static void register_() // Register the runtime metadata.
    {
        class_metadata::register_aux((T*)0);
    }

 private:
    template <class T2>
    inline static void register_aux(python::wrapper<T2>*)
    {
        typedef typename mpl::not_<is_same<T2,wrapped> >::type use_callback;
        class_metadata::register_aux2((T2*)0, use_callback());
    }

    inline static void register_aux(void*)
    {
        typedef typename is_base_and_derived<T,wrapped>::type use_callback;
        class_metadata::register_aux2((T*)0, use_callback());
    }

    template <class T2, class Callback>
    inline static void register_aux2(T2*, Callback)
    {
	objects::register_shared_ptr_from_python_and_casts((T2*)0, bases());
        class_metadata::maybe_register_callback_class((T2*)0, Callback());

        class_metadata::maybe_register_class_to_python((T2*)0, is_noncopyable());

        class_metadata::maybe_register_pointer_to_python(
            (T2*)0, (use_value_holder*)0, (use_back_reference*)0);
    }

    //
    // Support for converting smart pointers to python
    //
    inline static void maybe_register_pointer_to_python(...) {}

#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
    {
        objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
        objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T &> >());
    }
#endif

    template <class T2>
    inline static void maybe_register_pointer_to_python(T2*, mpl::false_*, mpl::false_*)
    {
        python::detail::force_instantiate(
            objects::class_value_wrapper<
                held_type
              , make_ptr_instance<T2, pointer_holder<held_type, T2> >
            >()
        );
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
        // explicit qualification of type_id makes msvc6 happy
        objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
    }
    //
    // Support for registering to-python converters
    //
    inline static void maybe_register_class_to_python(void*, mpl::true_) {}

    template <class T2>
    inline static void maybe_register_class_to_python(T2*, mpl::false_)
    {
        python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
        // explicit qualification of type_id makes msvc6 happy
        objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
    }

    //
    // Support for registering callback classes
    //
    inline static void maybe_register_callback_class(void*, mpl::false_) {}

    template <class T2>
    inline static void maybe_register_callback_class(T2*, mpl::true_)
    {
	objects::register_shared_ptr_from_python_and_casts(
            (wrapped*)0, mpl::single_view<T2>());
        // explicit qualification of type_id makes msvc6 happy
        objects::copy_class_object(python::type_id<T2>(), python::type_id<wrapped>());
    }
};

}}} // namespace boost::python::object

#endif


code:
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef CLASS_WRAPPER_DWA20011221_HPP
# define CLASS_WRAPPER_DWA20011221_HPP

# include <boost/python/to_python_converter.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/ref.hpp>

namespace boost { namespace python { namespace objects {

//
// These two classes adapt the static execute function of a class
// MakeInstance execute() function returning a new PyObject*
// reference. The first one is used for class copy constructors, and
// the second one is used to handle smart pointers.
//

template <class Src, class MakeInstance>
struct class_cref_wrapper
    : to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> ,true>
{
    static PyObject* convert(Src const& x)
    {
        return MakeInstance::execute(boost::ref(x));
    }
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    static PyTypeObject const *get_pytype() { return converter::registered_pytype_direct<Src>::get_pytype(); }
#endif
};

template <class Src, class MakeInstance>
struct class_value_wrapper
    : to_python_converter<Src,class_value_wrapper<Src,MakeInstance> ,true>
{
    static PyObject* convert(Src x)
    {
        return MakeInstance::execute(x);
    }
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    static PyTypeObject const *get_pytype() { return MakeInstance::get_pytype(); }
#endif
};

}}} // namespace boost::python::objects

#endif // CLASS_WRAPPER_DWA20011221_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ENUM_BASE_DWA200298_HPP
# define ENUM_BASE_DWA200298_HPP

# include <boost/python/object_core.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/converter/to_python_function_type.hpp>
# include <boost/python/converter/convertible_function.hpp>
# include <boost/python/converter/constructor_function.hpp>

namespace boost { namespace python { namespace objects {

struct BOOST_PYTHON_DECL enum_base : python::api::object
{
 protected:
    enum_base(
        char const* name
        , converter::to_python_function_t
        , converter::convertible_function
        , converter::constructor_function
        , type_info
        , const char *doc = 0
        );

    void add_value(char const* name, long value);
    void export_values();

    static PyObject* to_python(PyTypeObject* type, long x);
};

}}} // namespace boost::python::object

#endif // ENUM_BASE_DWA200298_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FIND_INSTANCE_DWA2002312_HPP
# define FIND_INSTANCE_DWA2002312_HPP

# include <boost/python/type_id.hpp>

namespace boost { namespace python { namespace objects {

// Given a type_id, find the instance data which corresponds to it, or
// return 0 in case no such type is held.  If null_shared_ptr_only is
// true and the type being sought is a shared_ptr, only find an
// instance if it turns out to be NULL.  Needed for shared_ptr rvalue
// from_python support.
BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, type_info, bool null_shared_ptr_only = false);

}}} // namespace boost::python::objects

#endif // FIND_INSTANCE_DWA2002312_HPP


code:
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FORWARD_DWA20011215_HPP
# define FORWARD_DWA20011215_HPP

# include <boost/mpl/if.hpp>
# include <boost/type_traits/is_scalar.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/ref.hpp>
# include <boost/python/detail/value_arg.hpp>
# include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
# include <boost/mpl/or.hpp>

namespace boost { namespace python { namespace objects {

// Very much like boost::reference_wrapper<T>, except that in this
// case T can be a reference already without causing a
// reference-to-reference error.
template <class T>
struct reference_to_value
{
    typedef typename add_reference<typename add_const<T>::type>::type reference;

    reference_to_value(reference x) : m_value(x) {}
    reference get() const { return m_value; }
 private:
    reference m_value;
};

// A little metaprogram which selects the type to pass through an
// intermediate forwarding function when the destination argument type
// is T.
template <class T>
struct forward
    : mpl::if_<
          mpl::or_<python::detail::copy_ctor_mutates_rhs<T>, is_scalar<T> >
        , T
        , reference_to_value<T>
      >
{
};

template<typename T>
struct unforward
{
    typedef typename unwrap_reference<T>::type& type;
};

template<typename T>
struct unforward<reference_to_value<T> >
{
    typedef T type;
};

template <typename T>
struct unforward_cref
  : python::detail::value_arg<
        typename unwrap_reference<T>::type
    >
{
};

template<typename T>
struct unforward_cref<reference_to_value<T> >
  : add_reference<typename add_const<T>::type>
{
};

template <class T>
typename reference_to_value<T>::reference
do_unforward(reference_to_value<T> const& x, int)
{
    return x.get();
}

template <class T>
typename reference_wrapper<T>::type&
do_unforward(reference_wrapper<T> const& x, int)
{
    return x.get();
}

template <class T>
T const& do_unforward(T const& x, ...)
{
    return x;
}

}}} // namespace boost::python::objects

#endif // FORWARD_DWA20011215_HPP


code:
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FUNCTION_DWA20011214_HPP
# define FUNCTION_DWA20011214_HPP

# include <boost/python/detail/prefix.hpp>
# include <boost/python/args_fwd.hpp>
# include <boost/python/handle.hpp>
# include <boost/function/function2.hpp>
# include <boost/python/object_core.hpp>
# include <boost/python/object/py_function.hpp>

namespace boost { namespace python { namespace objects {

struct BOOST_PYTHON_DECL function : PyObject
{
    function(
        py_function const&
        , python::detail::keyword const* names_and_defaults
        , unsigned num_keywords);

    ~function();

    PyObject* call(PyObject*, PyObject*) const;

    // Add an attribute to the name_space with the given name. If it is
    // a function object (this class), and an existing function is
    // already there, add it as an overload.
    static void add_to_namespace(
        object const& name_space, char const* name, object const& attribute);

    static void add_to_namespace(
        object const& name_space, char const* name, object const& attribute, char const* doc);

    object const& doc() const;
    void doc(object const& x);

    object const& name() const;

    object const& get_namespace() const { return m_namespace; }

 private: // helper functions
    object signature(bool show_return_type=false) const;
    object signatures(bool show_return_type=false) const;
    void argument_error(PyObject* args, PyObject* keywords) const;
    void add_overload(handle<function> const&);

 private: // data members
    py_function m_fn;
    handle<function> m_overloads;
    object m_name;
    object m_namespace;
    object m_doc;
    object m_arg_names;
    unsigned m_nkeyword_values;
    friend class function_doc_signature_generator;
};

//
// implementations
//
inline object const& function::doc() const
{
    return this->m_doc;
}

inline void function::doc(object const& x)
{
    this->m_doc = x;
}

inline object const& function::name() const
{
    return this->m_name;
}

}}} // namespace boost::python::objects

#endif // FUNCTION_DWA20011214_HPP


code:
// Copyright Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FUNCTION_SIGNATURE_20070531_HPP
# define FUNCTION_SIGNATURE_20070531_HPP

#include <boost/python/object/function.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/str.hpp>
#include <boost/python/tuple.hpp>

#include <boost/python/detail/signature.hpp>

#include <vector>

namespace boost { namespace python { namespace objects {

class function_doc_signature_generator{
    static const  char * py_type_str(const python::detail::signature_element &s);
    static bool arity_cmp( function const *f1, function const *f2 );
    static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
    static std::vector<function const*> flatten(function const *f);
    static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
    static str raw_function_pretty_signature(function const *f, size_t n_overloads,  bool cpp_types = false);
    static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
    static str pretty_signature(function const *f, size_t n_overloads,  bool cpp_types = false);

public:
    static list function_doc_signatures( function const * f);
};

}}}//end of namespace boost::python::objects

#endif //FUNCTION_SIGNATURE_20070531_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FUNCTION_HANDLE_DWA2002725_HPP
# define FUNCTION_HANDLE_DWA2002725_HPP
# include <boost/python/handle.hpp>
# include <boost/python/detail/caller.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/object/py_function.hpp>
# include <boost/python/signature.hpp>

namespace boost { namespace python { namespace objects {

BOOST_PYTHON_DECL handle<> function_handle_impl(py_function const& f);

// Just like function_object, but returns a handle<> instead. Using
// this for arg_to_python<> allows us to break a circular dependency
// between object and arg_to_python.
template <class F, class Signature>
inline handle<> function_handle(F const& f, Signature)
{
    enum { n_arguments = mpl::size<Signature>::value - 1 };

    return objects::function_handle_impl(
        python::detail::caller<
            F,default_call_policies,Signature
        >(
            f, default_call_policies()
         )
    );
}

// Just like make_function, but returns a handle<> intead. Same
// reasoning as above.
template <class F>
handle<> make_function_handle(F f)
{
    return objects::function_handle(f, python::detail::get_signature(f));
}

}}} // namespace boost::python::objects

#endif // FUNCTION_HANDLE_DWA2002725_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FUNCTION_OBJECT_DWA2002725_HPP
# define FUNCTION_OBJECT_DWA2002725_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/function/function2.hpp>
# include <boost/python/object_core.hpp>
# include <boost/python/args_fwd.hpp>
# include <boost/python/object/py_function.hpp>

namespace boost { namespace python {

namespace objects
{
  BOOST_PYTHON_DECL api::object function_object(
      py_function const& f
      , python::detail::keyword_range const&);

  BOOST_PYTHON_DECL api::object function_object(
      py_function const& f
      , python::detail::keyword_range const&);

  BOOST_PYTHON_DECL api::object function_object(py_function const& f);

  // Add an attribute to the name_space with the given name. If it is
  // a Boost.Python function object
  // (boost/python/object/function.hpp), and an existing function is
  // already there, add it as an overload.
  BOOST_PYTHON_DECL void add_to_namespace(
      object const& name_space, char const* name, object const& attribute);

  BOOST_PYTHON_DECL void add_to_namespace(
      object const& name_space, char const* name, object const& attribute, char const* doc);
}

}} // namespace boost::python::objects

#endif // FUNCTION_OBJECT_DWA2002725_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef INHERITANCE_DWA200216_HPP
# define INHERITANCE_DWA200216_HPP

# include <boost/python/type_id.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/mpl/if.hpp>
# include <boost/type_traits/is_polymorphic.hpp>
# include <boost/type_traits/is_base_and_derived.hpp>
# include <boost/detail/workaround.hpp>

namespace boost { namespace python { namespace objects {

typedef type_info class_id;
using python::type_id;

// Types used to get address and id of most derived type
typedef std::pair<void*,class_id> dynamic_id_t;
typedef dynamic_id_t (*dynamic_id_function)(void*);

BOOST_PYTHON_DECL void register_dynamic_id_aux(
    class_id static_id, dynamic_id_function get_dynamic_id);

BOOST_PYTHON_DECL void add_cast(
    class_id src_t, class_id dst_t, void* (*cast)(void*), bool is_downcast);

//
// a generator with an execute() function which, given a source type
// and a pointer to an object of that type, returns its most-derived
// /reachable/ type identifier and object pointer.
//

// first, the case where T has virtual functions
template <class T>
struct polymorphic_id_generator
{
    static dynamic_id_t execute(void* p_)
    {
        T* p = static_cast<T*>(p_);
        return std::make_pair(dynamic_cast<void*>(p), class_id(typeid(*p)));
    }
};

// now, the non-polymorphic case.
template <class T>
struct non_polymorphic_id_generator
{
    static dynamic_id_t execute(void* p_)
    {
        return std::make_pair(p_, python::type_id<T>());
    }
};

// Now the generalized selector
template <class T>
struct dynamic_id_generator
  : mpl::if_<
        boost::is_polymorphic<T>
        , boost::python::objects::polymorphic_id_generator<T>
        , boost::python::objects::non_polymorphic_id_generator<T>
    >
{};

// Register the dynamic id function for T with the type-conversion
// system.
template <class T>
void register_dynamic_id(T* = 0)
{
    typedef typename dynamic_id_generator<T>::type generator;
    register_dynamic_id_aux(
        python::type_id<T>(), &generator::execute);
}

//
// a generator with an execute() function which, given a void*
// pointing to an object of type Source will attempt to convert it to
// an object of type Target.
//

template <class Source, class Target>
struct dynamic_cast_generator
{
    static void* execute(void* source)
    {
        return dynamic_cast<Target*>(
            static_cast<Source*>(source));
    }

};

template <class Source, class Target>
struct implicit_cast_generator
{
    static void* execute(void* source)
    {
        Target* result = static_cast<Source*>(source);
        return result;
    }
};

template <class Source, class Target>
struct cast_generator
  : mpl::if_<
        is_base_and_derived<Target,Source>
      , implicit_cast_generator<Source,Target>
      , dynamic_cast_generator<Source,Target>
    >
{
};

template <class Source, class Target>
inline void register_conversion(
    bool is_downcast = ::boost::is_base_and_derived<Source,Target>::value
    // These parameters shouldn't be used; they're an MSVC bug workaround
    , Source* = 0, Target* = 0)
{
    typedef typename cast_generator<Source,Target>::type generator;

    add_cast(
        python::type_id<Source>()
      , python::type_id<Target>()
      , &generator::execute
      , is_downcast
    );
}

}}} // namespace boost::python::object

#endif // INHERITANCE_DWA200216_HPP


code:
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef INHERITANCE_QUERY_DWA2003520_HPP
# define INHERITANCE_QUERY_DWA2003520_HPP

# include <boost/python/type_id.hpp>

namespace boost { namespace python { namespace objects {

BOOST_PYTHON_DECL void* find_static_type(void* p, type_info src, type_info dst);
BOOST_PYTHON_DECL void* find_dynamic_type(void* p, type_info src, type_info dst);

}}} // namespace boost::python::object

#endif // INHERITANCE_QUERY_DWA2003520_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef INSTANCE_DWA200295_HPP
# define INSTANCE_DWA200295_HPP

# include <boost/python/detail/prefix.hpp>
# include <boost/type_traits/alignment_traits.hpp>
# include <cstddef>

namespace boost { namespace python
{
  struct BOOST_PYTHON_DECL_FORWARD instance_holder;
}} // namespace boost::python

namespace boost { namespace python { namespace objects {

// Each extension instance will be one of these
template <class Data = char>
struct instance
{
    PyObject_VAR_HEAD
    PyObject* dict;
    PyObject* weakrefs;
    instance_holder* objects;

    typedef typename type_with_alignment<
        ::boost::alignment_of<Data>::value
    >::type align_t;

    union
    {
        align_t align;
        char bytes[sizeof(Data)];
    } storage;
};

template <class Data>
struct additional_instance_size
{
    typedef instance<Data> instance_data;
    typedef instance<char> instance_char;
    BOOST_STATIC_CONSTANT(
        std::size_t, value = sizeof(instance_data)
                           - BOOST_PYTHON_OFFSETOF(instance_char,storage));
};

}}} // namespace boost::python::object

#endif // INSTANCE_DWA200295_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ITERATOR_DWA2002510_HPP
# define ITERATOR_DWA2002510_HPP

# include <boost/python/detail/prefix.hpp>

# include <boost/python/class.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/return_by_value.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/make_function.hpp>

# include <boost/python/object/iterator_core.hpp>
# include <boost/python/object/class_detail.hpp>
# include <boost/python/object/function_object.hpp>

# include <boost/mpl/vector/vector10.hpp>
# include <boost/mpl/if.hpp>

# include <boost/python/detail/raw_pyobject.hpp>

# include <boost/type.hpp>

# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>

# include <boost/detail/iterator.hpp>

namespace boost { namespace python { namespace objects {

// CallPolicies for the next() method of iterators. We don't want
// users to have to explicitly specify that the references returned by
// iterators are copied, so we just replace the result_converter from
// the default_iterator_call_policies with a permissive one which
// always copies the result.
typedef return_value_policy<return_by_value> default_iterator_call_policies;

// Instantiations of these are wrapped to produce Python iterators.
template <class NextPolicies, class Iterator>
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
    };

    typedef next next_fn;

    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
      {
          // Make sure the Python class is instantiated.
          detail::demand_iterator_class("iterator", (Iterator*)0, NextPolicies());

          return iterator_range<NextPolicies,Iterator>(
              x.source()
            , m_get_start(x.get())
            , m_get_finish(x.get())
          );
      }
   private:
      Accessor1 m_get_start;
      Accessor2 m_get_finish;
  };

  template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
  inline object make_iterator_function(
      Accessor1 const& get_start
    , Accessor2 const& get_finish
    , NextPolicies const& /*next_policies*/
    , Iterator const& (*)()
    , boost::type<Target>*
    , int
  )
  {
      return make_function(
          py_iter_<Target,Iterator,Accessor1,Accessor2,NextPolicies>(get_start, get_finish)
        , default_call_policies()
        , mpl::vector2<iterator_range<NextPolicies,Iterator>, back_reference<Target&> >()
      );
  }

  template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
  inline object make_iterator_function(
      Accessor1 const& get_start
    , Accessor2 const& get_finish
    , NextPolicies const& next_policies
    , Iterator& (*)()
    , boost::type<Target>*
    , ...)
  {
      return make_iterator_function(
          get_start
        , get_finish
        , next_policies
        , (Iterator const&(*)())0
        , (boost::type<Target>*)0
        , 0
      );
  }

}

// Create a Python callable object which accepts a single argument
// convertible to the C++ Target type and returns a Python
// iterator. The Python iterator uses get_start(x) and get_finish(x)
// (where x is an instance of Target) to produce begin and end
// iterators for the range, and an instance of NextPolicies is used as
// CallPolicies for the Python iterator's next() function.
template <class Target, class NextPolicies, class Accessor1, class Accessor2>
inline object make_iterator_function(
    Accessor1 const& get_start
  , Accessor2 const& get_finish
  , NextPolicies const& next_policies
  , boost::type<Target>* = 0
)
{
    typedef typename Accessor1::result_type iterator;
    typedef typename add_const<iterator>::type iterator_const;
    typedef typename add_reference<iterator_const>::type iterator_cref;

    return detail::make_iterator_function(
        get_start
      , get_finish
      , next_policies
      , (iterator_cref(*)())0
      , (boost::type<Target>*)0
      , 0
    );
}

//
// implementation
//
template <class NextPolicies, class Iterator>
inline iterator_range<NextPolicies,Iterator>::iterator_range(
    object sequence, Iterator start, Iterator finish)
    : m_sequence(sequence), m_start(start), m_finish(finish)
{
}

}}} // namespace boost::python::objects

#endif // ITERATOR_DWA2002510_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ITERATOR_CORE_DWA2002512_HPP
# define ITERATOR_CORE_DWA2002512_HPP

# include <boost/python/object_fwd.hpp>

namespace boost { namespace python { namespace objects {

BOOST_PYTHON_DECL object const& identity_function();
BOOST_PYTHON_DECL void stop_iteration_error();

}}} // namespace boost::python::object

#endif // ITERATOR_CORE_DWA2002512_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef LIFE_SUPPORT_DWA200222_HPP
# define LIFE_SUPPORT_DWA200222_HPP
# include <boost/python/detail/prefix.hpp>

namespace boost { namespace python { namespace objects {

BOOST_PYTHON_DECL PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient);

}}} // namespace boost::python::object

#endif // LIFE_SUPPORT_DWA200222_HPP


code:
#if !defined(BOOST_PP_IS_ITERATING)

// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

# ifndef MAKE_HOLDER_DWA20011215_HPP
#  define MAKE_HOLDER_DWA20011215_HPP

#  include <boost/python/detail/prefix.hpp>

#  include <boost/python/object/instance.hpp>
#  include <boost/python/converter/registry.hpp>
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
#  include <boost/python/detail/python_type.hpp>
#endif

#  include <boost/python/object/forward.hpp>
#  include <boost/python/detail/preprocessor.hpp>

#  include <boost/mpl/next.hpp>
#  include <boost/mpl/begin_end.hpp>
#  include <boost/mpl/deref.hpp>

#  include <boost/preprocessor/iterate.hpp>
#  include <boost/preprocessor/iteration/local.hpp>
#  include <boost/preprocessor/repeat.hpp>
#  include <boost/preprocessor/debug/line.hpp>
#  include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>

#  include <cstddef>

namespace boost { namespace python { namespace objects {

template <int nargs> struct make_holder;

#  define BOOST_PYTHON_DO_FORWARD_ARG(z, index, _) , f##index(a##index)

// specializations...
#  define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/make_holder.hpp>))
#  include BOOST_PP_ITERATE()

#  undef BOOST_PYTHON_DO_FORWARD_ARG

}}} // namespace boost::python::objects

# endif // MAKE_HOLDER_DWA20011215_HPP

// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100)                      \
        && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
#  line BOOST_PP_LINE(__LINE__, make_holder.hpp)
# endif

# define N BOOST_PP_ITERATION()

template <>
struct make_holder<N>
{
    template <class Holder, class ArgList>
    struct apply
    {
# if N
        // Unrolled iteration through each argument type in ArgList,
        // choosing the type that will be forwarded on to the holder's
        // templated constructor.
        typedef typename mpl::begin<ArgList>::type iter0;

#  define BOOST_PP_LOCAL_MACRO(n)               \
    typedef typename mpl::deref<iter##n>::type t##n;        \
    typedef typename forward<t##n>::type f##n;  \
    typedef typename mpl::next<iter##n>::type   \
        BOOST_PP_CAT(iter,BOOST_PP_INC(n)); // Next iterator type

#  define BOOST_PP_LOCAL_LIMITS (0, N-1)
#  include BOOST_PP_LOCAL_ITERATE()
# endif

        static void execute(
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
            boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
#else
            PyObject *p
#endif
            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a))
        {
            typedef instance<Holder> instance_t;

            void* memory = Holder::allocate(p, offsetof(instance_t, storage), sizeof(Holder));
            try {
                (new (memory) Holder(
                    p BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p);
            }
            catch(...) {
                Holder::deallocate(p, memory);
                throw;
            }
        }
    };
};

# undef N

#endif // BOOST_PP_ITERATION_DEPTH()
#endif


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MAKE_INSTANCE_DWA200296_HPP
# define MAKE_INSTANCE_DWA200296_HPP

# include <boost/python/detail/prefix.hpp>
# include <boost/python/object/instance.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/decref_guard.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/mpl/assert.hpp>
# include <boost/mpl/or.hpp>
# include <boost/type_traits/is_union.hpp>

namespace boost { namespace python { namespace objects {

template <class T, class Holder, class Derived>
struct make_instance_impl
{
    typedef objects::instance<Holder> instance_t;

    template <class Arg>
    static inline PyObject* execute(Arg& x)
    {
        BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >));

        PyTypeObject* type = Derived::get_class_object(x);

        if (type == 0)
            return python::detail::none();

        PyObject* raw_result = type->tp_alloc(
            type, objects::additional_instance_size<Holder>::value);

        if (raw_result != 0)
        {
            python::detail::decref_guard protect(raw_result);

            instance_t* instance = (instance_t*)raw_result;

            // construct the new C++ object and install the pointer
            // in the Python object.
            Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result);

            // Note the position of the internally-stored Holder,
            // for the sake of destruction
            Py_SIZE(instance) = offsetof(instance_t, storage);

            // Release ownership of the python object
            protect.cancel();
        }
        return raw_result;
    }
};

template <class T, class Holder>
struct make_instance
    : make_instance_impl<T, Holder, make_instance<T,Holder> >
{
    template <class U>
    static inline PyTypeObject* get_class_object(U&)
    {
        return converter::registered<T>::converters.get_class_object();
    }

    static inline Holder* construct(void* storage, PyObject* instance, reference_wrapper<T const> x)
    {
        return new (storage) Holder(instance, x);
    }
};

}}} // namespace boost::python::object

#endif // MAKE_INSTANCE_DWA200296_HPP


code:
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MAKE_PTR_INSTANCE_DWA200296_HPP
# define MAKE_PTR_INSTANCE_DWA200296_HPP

# include <boost/python/object/make_instance.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/type_traits/is_polymorphic.hpp>
# include <boost/get_pointer.hpp>
# include <boost/detail/workaround.hpp>
# include <typeinfo>

namespace boost { namespace python { namespace objects {

template <class T, class Holder>
struct make_ptr_instance
    : make_instance_impl<T, Holder, make_ptr_instance<T,Holder> >
{
    template <class Arg>
    static inline Holder* construct(void* storage, PyObject*, Arg& x)
    {
#if __cplusplus < 201103L
      return new (storage) Holder(x);
#else
      return new (storage) Holder(std::move(x));
#endif
    }

    template <class Ptr>
    static inline PyTypeObject* get_class_object(Ptr const& x)
    {
        return get_class_object_impl(get_pointer(x));
    }
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    static inline PyTypeObject const* get_pytype()
    {
        return converter::registered<T>::converters.get_class_object();
    }
#endif
 private:
    template <class U>
    static inline PyTypeObject* get_class_object_impl(U const volatile* p)
    {
        if (p == 0)
            return 0; // means "return None".

        PyTypeObject* derived = get_derived_class_object(
            BOOST_DEDUCED_TYPENAME is_polymorphic<U>::type(), p);

        if (derived)
            return derived;
        return converter::registered<T>::converters.get_class_object();
    }

    template <class U>
    static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x)
    {
        converter::registration const* r = converter::registry::query(
            type_info(typeid(*get_pointer(x)))
        );
        return r ? r->m_class_object : 0;
    }

    template <class U>
    static inline PyTypeObject* get_derived_class_object(mpl::false_, U*)
    {
        return 0;
    }
};

}}} // namespace boost::python::object

#endif // MAKE_PTR_INSTANCE_DWA200296_HPP


code:
//  (C) Copyright R.W. Grosse-Kunstleve 2002.
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP
# define BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP

# include <boost/python/detail/prefix.hpp>

namespace boost { namespace python {

namespace api
{
  class object;
}
using api::object;
class tuple;

BOOST_PYTHON_DECL object const& make_instance_reduce_function();

struct pickle_suite;

namespace error_messages {

  template <class T>
  struct missing_pickle_suite_function_or_incorrect_signature {};

  inline void must_be_derived_from_pickle_suite(pickle_suite const&) {}
}

namespace detail { struct pickle_suite_registration; }

struct pickle_suite
{
  private:
    struct inaccessible {};
    friend struct detail::pickle_suite_registration;
  public:
    static inaccessible* getinitargs() { return 0; }
    static inaccessible* getstate() { return 0; }
    static inaccessible* setstate() { return 0; }
    static bool getstate_manages_dict() { return false; }
};

namespace detail {

  struct pickle_suite_registration
  {
    typedef pickle_suite::inaccessible inaccessible;

    template <class Class_, class Tgetinitargs>
    static
    void
    register_(
      Class_& cl,
      tuple (*getinitargs_fn)(Tgetinitargs),
      inaccessible* (* /*getstate_fn*/)(),
      inaccessible* (* /*setstate_fn*/)(),
      bool)
    {
      cl.enable_pickling_(false);
      cl.def("__getinitargs__", getinitargs_fn);
    }

    template <class Class_,
              class Rgetstate, class Tgetstate,
              class Tsetstate, class Ttuple>
    static
    void
    register_(
      Class_& cl,
      inaccessible* (* /*getinitargs_fn*/)(),
      Rgetstate (*getstate_fn)(Tgetstate),
      void (*setstate_fn)(Tsetstate, Ttuple),
      bool getstate_manages_dict)
    {
      cl.enable_pickling_(getstate_manages_dict);
      cl.def("__getstate__", getstate_fn);
      cl.def("__setstate__", setstate_fn);
    }

    template <class Class_,
              class Tgetinitargs,
              class Rgetstate, class Tgetstate,
              class Tsetstate, class Ttuple>
    static
    void
    register_(
      Class_& cl,
      tuple (*getinitargs_fn)(Tgetinitargs),
      Rgetstate (*getstate_fn)(Tgetstate),
      void (*setstate_fn)(Tsetstate, Ttuple),
      bool getstate_manages_dict)
    {
      cl.enable_pickling_(getstate_manages_dict);
      cl.def("__getinitargs__", getinitargs_fn);
      cl.def("__getstate__", getstate_fn);
      cl.def("__setstate__", setstate_fn);
    }

    template <class Class_>
    static
    void
    register_(
      Class_&,
      ...)
    {
      typedef typename
        error_messages::missing_pickle_suite_function_or_incorrect_signature<
          Class_>::error_type error_type BOOST_ATTRIBUTE_UNUSED;
    }
  };

  template <typename PickleSuiteType>
  struct pickle_suite_finalize
  : PickleSuiteType,
    pickle_suite_registration
  {};

} // namespace detail

}} // namespace boost::python

#endif // BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP


code:
#if !defined(BOOST_PP_IS_ITERATING)

// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

# ifndef POINTER_HOLDER_DWA20011215_HPP
#  define POINTER_HOLDER_DWA20011215_HPP

# include <boost/get_pointer.hpp>
#  include <boost/type.hpp>

#  include <boost/python/instance_holder.hpp>
#  include <boost/python/object/inheritance_query.hpp>
#  include <boost/python/object/forward.hpp>

#  include <boost/python/pointee.hpp>
#  include <boost/python/type_id.hpp>

#  include <boost/python/detail/wrapper_base.hpp>
#  include <boost/python/detail/force_instantiate.hpp>
#  include <boost/python/detail/preprocessor.hpp>

#  include <boost/mpl/if.hpp>
#  include <boost/mpl/apply.hpp>

#  include <boost/preprocessor/comma_if.hpp>
#  include <boost/preprocessor/iterate.hpp>
#  include <boost/preprocessor/repeat.hpp>
#  include <boost/preprocessor/debug/line.hpp>
#  include <boost/preprocessor/enum_params.hpp>
#  include <boost/preprocessor/repetition/enum_binary_params.hpp>

#  include <boost/detail/workaround.hpp>

#  include <boost/type_traits/remove_const.hpp>

namespace boost { namespace python {

template <class T> class wrapper;

}}

namespace boost { namespace python { namespace objects {

#define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)

template <class Pointer, class Value>
struct pointer_holder : instance_holder
{
    typedef Value value_type;

    pointer_holder(Pointer);

    // Forward construction to the held object

#  define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/pointer_holder.hpp>, 1))
#  include BOOST_PP_ITERATE()

 private: // types

 private: // required holder implementation
    void* holds(type_info, bool null_ptr_only);

    template <class T>
    inline void* holds_wrapped(type_info dst_t, wrapper<T>*,T* p)
    {
        return python::type_id<T>() == dst_t ? p : 0;
    }

    inline void* holds_wrapped(type_info, ...)
    {
        return 0;
    }

 private: // data members
    Pointer m_p;
};

template <class Pointer, class Value>
struct pointer_holder_back_reference : instance_holder
{
 private:
    typedef typename python::pointee<Pointer>::type held_type;
 public:
    typedef Value value_type;

    // Not sure about this one -- can it work? The source object
    // undoubtedly does not carry the correct back reference pointer.
    pointer_holder_back_reference(Pointer);

    // Forward construction to the held object
#  define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/pointer_holder.hpp>, 2))
#  include BOOST_PP_ITERATE()

 private: // required holder implementation
    void* holds(type_info, bool null_ptr_only);

 private: // data members
    Pointer m_p;
};

#  undef BOOST_PYTHON_UNFORWARD_LOCAL

template <class Pointer, class Value>
inline pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
#if __cplusplus < 201103L
    : m_p(p)
#else
    : m_p(std::move(p))
#endif
{
}

template <class Pointer, class Value>
inline pointer_holder_back_reference<Pointer,Value>::pointer_holder_back_reference(Pointer p)
#if __cplusplus < 201103L
    : m_p(p)
#else
    : m_p(std::move(p))
#endif
{
}

template <class Pointer, class Value>
void* pointer_holder<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
{
    typedef typename boost::remove_const< Value >::type non_const_value;

    if (dst_t == python::type_id<Pointer>()
        && !(null_ptr_only && get_pointer(this->m_p))
    )
        return &this->m_p;

    Value* p0
#  if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
        = static_cast<Value*>( get_pointer(this->m_p) )
#  else
        = get_pointer(this->m_p)
#  endif
        ;
    non_const_value* p = const_cast<non_const_value*>( p0 );

    if (p == 0)
        return 0;

    if (void* wrapped = holds_wrapped(dst_t, p, p))
        return wrapped;

    type_info src_t = python::type_id<non_const_value>();
    return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
}

template <class Pointer, class Value>
void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t, bool null_ptr_only)
{
    if (dst_t == python::type_id<Pointer>()
        && !(null_ptr_only && get_pointer(this->m_p))
    )
        return &this->m_p;

    if (!get_pointer(this->m_p))
        return 0;

    Value* p = get_pointer(m_p);

    if (dst_t == python::type_id<held_type>())
        return p;

    type_info src_t = python::type_id<Value>();
    return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
}

}}} // namespace boost::python::objects

# endif // POINTER_HOLDER_DWA20011215_HPP

/* --------------- pointer_holder --------------- */
// For gcc 4.4 compatability, we must include the
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
#else // BOOST_PP_IS_ITERATING
#if BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100)                      \
        && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
#  line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
# endif

# define N BOOST_PP_ITERATION()

# if (N != 0)
    template< BOOST_PP_ENUM_PARAMS_Z(1, N, class A) >
# endif
    pointer_holder(PyObject* self BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a))
        : m_p(new Value(
                BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil)
            ))
    {
        python::detail::initialize_wrapper(self, get_pointer(this->m_p));
    }

# undef N

/* --------------- pointer_holder_back_reference --------------- */
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100)                      \
        && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
#  line BOOST_PP_LINE(__LINE__, pointer_holder.hpp(pointer_holder_back_reference))
# endif

# define N BOOST_PP_ITERATION()

# if (N != 0)
    template < BOOST_PP_ENUM_PARAMS_Z(1, N, class A) >
# endif
    pointer_holder_back_reference(
        PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a))
        : m_p(new held_type(
                    p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil)
            ))
    {}

# undef N

#endif // BOOST_PP_ITERATION_DEPTH()
#endif