code:
#ifndef BOOST_PYTHON_SLICE_JDB20040105_HPP
#define BOOST_PYTHON_SLICE_JDB20040105_HPP

// Copyright (c) 2004 Jonathan Brandmeyer
//  Use, modification and distribution are subject to 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)

#include <boost/python/detail/prefix.hpp>
#include <boost/config.hpp>
#include <boost/python/object.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/converter/pytype_object_mgr_traits.hpp>

#include <boost/iterator/iterator_traits.hpp>

#include <iterator>
#include <algorithm>

namespace boost { namespace python {

namespace detail
{
  class BOOST_PYTHON_DECL slice_base : public object
  {
   public:
      // Get the Python objects associated with the slice.  In principle, these
      // may be any arbitrary Python type, but in practice they are usually
      // integers.  If one or more parameter is ommited in the Python expression
      // that created this slice, than that parameter is None here, and compares
      // equal to a default-constructed boost::python::object.
      // If a user-defined type wishes to support slicing, then support for the
      // special meaning associated with negative indices is up to the user.
      object start() const;
      object stop() const;
      object step() const;

   protected:
      explicit slice_base(PyObject*, PyObject*, PyObject*);

      BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(slice_base, object)
  };
}

class slice : public detail::slice_base
{
    typedef detail::slice_base base;
 public:
    // Equivalent to slice(::)
    slice() : base(0,0,0) {}

    // Each argument must be slice_nil, or implicitly convertable to object.
    // They should normally be integers.
    template<typename Integer1, typename Integer2>
    slice( Integer1 start, Integer2 stop)
        : base( object(start).ptr(), object(stop).ptr(), 0 )
    {}

    template<typename Integer1, typename Integer2, typename Integer3>
    slice( Integer1 start, Integer2 stop, Integer3 stride)
        : base( object(start).ptr(), object(stop).ptr(), object(stride).ptr() )
    {}

    // The following algorithm is intended to automate the process of
    // determining a slice range when you want to fully support negative
    // indices and non-singular step sizes.  Its functionallity is simmilar to
    // PySlice_GetIndicesEx() in the Python/C API, but tailored for C++ users.
    // This template returns a slice::range struct that, when used in the
    // following iterative loop, will traverse a slice of the function's
    // arguments.
    // while (start != end) {
    //     do_foo(...);
    //     std::advance( start, step);
    // }
    // do_foo(...); // repeat exactly once more.

    // Arguments: a [begin, end) pair of STL-conforming random-access iterators.

    // Return: slice::range, where start and stop define a _closed_ interval
    // that covers at most [begin, end-1] of the provided arguments, and a step
    // that is non-zero.

    // Throws: error_already_set() if any of the indices are neither None nor
    //   integers, or the slice has a step value of zero.
    // std::invalid_argument if the resulting range would be empty.  Normally,
    //   you should catch this exception and return an empty sequence of the
    //   appropriate type.

    // Performance: constant time for random-access iterators.

    // Rationale:
    //   closed-interval: If an open interval were used, then for a non-singular
    //     value for step, the required state for the end iterator could be
    //     beyond the one-past-the-end postion of the specified range.  While
    //     probably harmless, the behavior of STL-conforming iterators is
    //     undefined in this case.
    //   exceptions on zero-length range: It is impossible to define a closed
    //     interval over an empty range, so some other form of error checking
    //     would have to be used by the user to prevent undefined behavior.  In
    //     the case where the user fails to catch the exception, it will simply
    //     be translated to Python by the default exception handling mechanisms.

    template<typename RandomAccessIterator>
    struct range
    {
        RandomAccessIterator start;
        RandomAccessIterator stop;
        typename iterator_difference<RandomAccessIterator>::type step;
    };

    template<typename RandomAccessIterator>
    slice::range<RandomAccessIterator>
    get_indices( const RandomAccessIterator& begin,
        const RandomAccessIterator& end) const
    {
        // This is based loosely on PySlice_GetIndicesEx(), but it has been
        // carefully crafted to ensure that these iterators never fall out of
        // the range of the container.
        slice::range<RandomAccessIterator> ret;

        typedef typename iterator_difference<RandomAccessIterator>::type difference_type;
        difference_type max_dist = std::distance(begin, end);

        object slice_start = this->start();
        object slice_stop = this->stop();
        object slice_step = this->step();

        // Extract the step.
        if (slice_step == object()) {
            ret.step = 1;
        }
        else {
            ret.step = extract<long>( slice_step);
            if (ret.step == 0) {
                PyErr_SetString( PyExc_IndexError, "step size cannot be zero.");
                throw_error_already_set();
            }
        }

        // Setup the start iterator.
        if (slice_start == object()) {
            if (ret.step < 0) {
                ret.start = end;
                --ret.start;
            }
            else
                ret.start = begin;
        }
        else {
            difference_type i = extract<long>( slice_start);
            if (i >= max_dist && ret.step > 0)
                    throw std::invalid_argument( "Zero-length slice");
            if (i >= 0) {
                ret.start = begin;
                BOOST_USING_STD_MIN();
                std::advance( ret.start, min BOOST_PREVENT_MACRO_SUBSTITUTION(i, max_dist-1));
            }
            else {
                if (i < -max_dist && ret.step < 0)
                    throw std::invalid_argument( "Zero-length slice");
                ret.start = end;
                // Advance start (towards begin) not farther than begin.
                std::advance( ret.start, (-i < max_dist) ? i : -max_dist );
            }
        }

        // Set up the stop iterator.  This one is a little trickier since slices
        // define a [) range, and we are returning a [] range.
        if (slice_stop == object()) {
            if (ret.step < 0) {
                ret.stop = begin;
            }
            else {
                ret.stop = end;
                std::advance( ret.stop, -1);
            }
        }
        else {
            difference_type i = extract<long>(slice_stop);
            // First, branch on which direction we are going with this.
            if (ret.step < 0) {
                if (i+1 >= max_dist || i == -1)
                    throw std::invalid_argument( "Zero-length slice");

                if (i >= 0) {
                    ret.stop = begin;
                    std::advance( ret.stop, i+1);
                }
                else { // i is negative, but more negative than -1.
                    ret.stop = end;
                    std::advance( ret.stop, (-i < max_dist) ? i : -max_dist);
                }
            }
            else { // stepping forward
                if (i == 0 || -i >= max_dist)
                    throw std::invalid_argument( "Zero-length slice");

                if (i > 0) {
                    ret.stop = begin;
                    std::advance( ret.stop, (std::min)( i-1, max_dist-1));
                }
                else { // i is negative, but not more negative than -max_dist
                    ret.stop = end;
                    std::advance( ret.stop, i-1);
                }
            }
        }

        // Now the fun part, handling the possibilites surrounding step.
        // At this point, step has been initialized, ret.stop, and ret.step
        // represent the widest possible range that could be traveled
        // (inclusive), and final_dist is the maximum distance covered by the
        // slice.
        typename iterator_difference<RandomAccessIterator>::type final_dist =
            std::distance( ret.start, ret.stop);

        // First case, if both ret.start and ret.stop are equal, then step
        // is irrelevant and we can return here.
        if (final_dist == 0)
            return ret;

        // Second, if there is a sign mismatch, than the resulting range and
        // step size conflict: std::advance( ret.start, ret.step) goes away from
        // ret.stop.
        if ((final_dist > 0) != (ret.step > 0))
            throw std::invalid_argument( "Zero-length slice.");

        // Finally, if the last step puts us past the end, we move ret.stop
        // towards ret.start in the amount of the remainder.
        // I don't remember all of the oolies surrounding negative modulii,
        // so I am handling each of these cases separately.
        if (final_dist < 0) {
            difference_type remainder = -final_dist % -ret.step;
            std::advance( ret.stop, remainder);
        }
        else {
            difference_type remainder = final_dist % ret.step;
            std::advance( ret.stop, -remainder);
        }

        return ret;
    }

    // Incorrect spelling. DO NOT USE. Only here for backward compatibility.
    // Corrected 2011-06-14.
    template<typename RandomAccessIterator>
    slice::range<RandomAccessIterator>
    get_indicies( const RandomAccessIterator& begin,
        const RandomAccessIterator& end) const
    {
        return get_indices(begin, end);
    }

 public:
    // This declaration, in conjunction with the specialization of
    // object_manager_traits<> below, allows C++ functions accepting slice
    // arguments to be called from from Python.  These constructors should never
    // be used in client code.
    BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(slice, detail::slice_base)
};

namespace converter {

template<>
struct object_manager_traits<slice>
    : pytype_object_manager_traits<&PySlice_Type, slice>
{
};

} // !namesapce converter

} } // !namespace ::boost::python

#endif // !defined BOOST_PYTHON_SLICE_JDB20040105_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 SLICE_NIL_DWA2002620_HPP
# define SLICE_NIL_DWA2002620_HPP

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

namespace boost { namespace python { namespace api {

class slice_nil : public object
{
 public:
    slice_nil() : object() {}
};

# ifndef _ // Watch out for GNU gettext users, who #define _(x)
static const slice_nil _ = slice_nil();
# endif

template <class T>
struct slice_bound
{
    typedef object type;
};

template <>
struct slice_bound<slice_nil>
{
    typedef slice_nil type;
};

}

using api::slice_nil;
# ifndef _ // Watch out for GNU gettext users, who #define _(x)
using api::_;
# endif

}} // namespace boost::python

#endif // SLICE_NIL_DWA2002620_HPP

license: mit


code:
// Copyright Ralf W. Grosse-Kunstleve & David Abrahams 2006.
// 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_SSIZE_T_RWGK20060924_HPP
# define BOOST_PYTHON_SSIZE_T_RWGK20060924_HPP

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

namespace boost { namespace python {

#if PY_VERSION_HEX >= 0x02050000

typedef Py_ssize_t ssize_t;
ssize_t const ssize_t_max = PY_SSIZE_T_MAX;
ssize_t const ssize_t_min = PY_SSIZE_T_MIN;

#else

typedef int ssize_t;
ssize_t const ssize_t_max = INT_MAX;
ssize_t const ssize_t_min = INT_MIN;

#endif

}} // namespace boost::python

#endif // BOOST_PYTHON_SSIZE_T_RWGK20060924_HPP


code:
// Copyright Eric Niebler 2005.
// 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 STL_ITERATOR_EAN20051028_HPP
# define STL_ITERATOR_EAN20051028_HPP

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

# include <boost/python/object/stl_iterator_core.hpp>

# include <boost/iterator/iterator_facade.hpp>

namespace boost { namespace python
{

// An STL input iterator over a python sequence
template<typename ValueT>
struct stl_input_iterator
  : boost::iterator_facade<
        stl_input_iterator<ValueT>
      , ValueT
      , std::input_iterator_tag
      , ValueT
    >
{
    stl_input_iterator()
      : impl_()
    {
    }

    // ob is the python sequence
    stl_input_iterator(boost::python::object const &ob)
      : impl_(ob)
    {
    }

private:
    friend class boost::iterator_core_access;

    void increment()
    {
        this->impl_.increment();
    }

    ValueT dereference() const
    {
        return extract<ValueT>(this->impl_.current().get())();
    }

    bool equal(stl_input_iterator<ValueT> const &that) const
    {
        return this->impl_.equal(that.impl_);
    }

    objects::stl_input_iterator_impl impl_;
};

}} // namespace boost::python

#endif // STL_ITERATOR_EAN20051028_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 STR_20020703_HPP
#define STR_20020703_HPP

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

#include <boost/python/object.hpp>
#include <boost/python/list.hpp>
#include <boost/python/converter/pytype_object_mgr_traits.hpp>

// disable defines in <cctype> provided by some system libraries
#undef isspace
#undef islower
#undef isalpha
#undef isdigit
#undef isalnum
#undef isupper

namespace boost { namespace python {

class str;

namespace detail
{
  struct BOOST_PYTHON_DECL str_base : object
  {
      str capitalize() const;

      str center(object_cref width) const;

      long count(object_cref sub) const;

      long count(object_cref sub, object_cref start) const;

      long count(object_cref sub, object_cref start, object_cref end) const;

#if PY_VERSION_HEX < 0x03000000
      object decode() const;
      object decode(object_cref encoding) const;

      object decode(object_cref encoding, object_cref errors) const;
#endif

      object encode() const;
      object encode(object_cref encoding) const;
      object encode(object_cref encoding, object_cref errors) const;

      bool endswith(object_cref suffix) const;

      bool endswith(object_cref suffix, object_cref start) const;
      bool endswith(object_cref suffix, object_cref start, object_cref end) const;

      str expandtabs() const;
      str expandtabs(object_cref tabsize) const;

      long find(object_cref sub) const;
      long find(object_cref sub, object_cref start) const;

      long find(object_cref sub, object_cref start, object_cref end) const;

      long index(object_cref sub) const;

      long index(object_cref sub, object_cref start) const;
      long index(object_cref sub, object_cref start, object_cref end) const;

      bool isalnum() const;
      bool isalpha() const;
      bool isdigit() const;
      bool islower() const;
      bool isspace() const;
      bool istitle() const;
      bool isupper() const;

      str join(object_cref sequence) const;

      str ljust(object_cref width) const;
      str lower() const;
      str lstrip() const;

      str replace(object_cref old, object_cref new_) const;
      str replace(object_cref old, object_cref new_, object_cref maxsplit) const;
      long rfind(object_cref sub) const;

      long rfind(object_cref sub, object_cref start) const;

      long rfind(object_cref sub, object_cref start, object_cref end) const;
      long rindex(object_cref sub) const;
      long rindex(object_cref sub, object_cref start) const;

      long rindex(object_cref sub, object_cref start, object_cref end) const;

      str rjust(object_cref width) const;

      str rstrip() const;

      list split() const;
      list split(object_cref sep) const;

      list split(object_cref sep, object_cref maxsplit) const;

      list splitlines() const;
      list splitlines(object_cref keepends) const;

      bool startswith(object_cref prefix) const;

      bool startswith(object_cref prefix, object_cref start) const;
      bool startswith(object_cref prefix, object_cref start, object_cref end) const;

      str strip() const;
      str swapcase() const;
      str title() const;

      str translate(object_cref table) const;

      str translate(object_cref table, object_cref deletechars) const;

      str upper() const;

   protected:
      str_base(); // new str

      str_base(const char* s); // new str

      str_base(char const* start, char const* finish);

      str_base(char const* start, std::size_t length);

      explicit str_base(object_cref other);

      BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str_base, object)
   private:
      static new_reference call(object const&);
  };
}

class str : public detail::str_base
{
    typedef detail::str_base base;
 public:
    str() {} // new str

    str(const char* s) : base(s) {} // new str

    str(char const* start, char const* finish) // new str
      : base(start, finish)
    {}

    str(char const* start, std::size_t length) // new str
      : base(start, length)
    {}

    template <class T>
    explicit str(T const& other)
        : base(object(other))
    {
    }

    template <class T>
    str center(T const& width) const
    {
        return base::center(object(width));
    }

    template<class T>
    long count(T const& sub) const
    {
        return base::count(object(sub));
    }

    template<class T1, class T2>
    long count(T1 const& sub,T2 const& start) const
    {
        return base::count(object(sub), object(start));
    }

    template<class T1, class T2, class T3>
    long count(T1 const& sub,T2 const& start, T3 const& end) const
    {
        return base::count(object(sub), object(start), object(end));
    }

#if PY_VERSION_HEX < 0x03000000
    object decode() const { return base::decode(); }

    template<class T>
    object decode(T const& encoding) const
    {
        return base::decode(object(encoding));
    }

    template<class T1, class T2>
    object decode(T1 const& encoding, T2 const& errors) const
    {
        return base::decode(object(encoding),object(errors));
    }
#endif

    object encode() const { return base::encode(); }

    template <class T>
    object encode(T const& encoding) const
    {
        return base::encode(object(encoding));
    }

    template <class T1, class T2>
    object encode(T1 const& encoding, T2 const& errors) const
    {
        return base::encode(object(encoding),object(errors));
    }

    template <class T>
    bool endswith(T const& suffix) const
    {
        return base::endswith(object(suffix));
    }

    template <class T1, class T2>
    bool endswith(T1 const& suffix, T2 const& start) const
    {
        return base::endswith(object(suffix), object(start));
    }

    template <class T1, class T2, class T3>
    bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const
    {
        return base::endswith(object(suffix), object(start), object(end));
    }

    str expandtabs() const { return base::expandtabs(); }

    template <class T>
    str expandtabs(T const& tabsize) const
    {
        return base::expandtabs(object(tabsize));
    }

    template <class T>
    long find(T const& sub) const
    {
        return base::find(object(sub));
    }

    template <class T1, class T2>
    long find(T1 const& sub, T2 const& start) const
    {
        return base::find(object(sub), object(start));
    }

    template <class T1, class T2, class T3>
    long find(T1 const& sub, T2 const& start, T3 const& end) const
    {
        return base::find(object(sub), object(start), object(end));
    }

    template <class T>
    long index(T const& sub) const
    {
        return base::index(object(sub));
    }

    template <class T1, class T2>
    long index(T1 const& sub, T2 const& start) const
    {
        return base::index(object(sub), object(start));
    }

    template <class T1, class T2, class T3>
    long index(T1 const& sub, T2 const& start, T3 const& end) const
    {
        return base::index(object(sub), object(start), object(end));
    }

    template <class T>
    str join(T const& sequence) const
    {
        return base::join(object(sequence));
    }

    template <class T>
    str ljust(T const& width) const
    {
        return base::ljust(object(width));
    }

    template <class T1, class T2>
    str replace(T1 const& old, T2 const& new_) const
    {
        return base::replace(object(old),object(new_));
    }

    template <class T1, class T2, class T3>
    str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const
    {
        return base::replace(object(old),object(new_), object(maxsplit));
    }

    template <class T>
    long rfind(T const& sub) const
    {
        return base::rfind(object(sub));
    }

    template <class T1, class T2>
    long rfind(T1 const& sub, T2 const& start) const
    {
        return base::rfind(object(sub), object(start));
    }

    template <class T1, class T2, class T3>
    long rfind(T1 const& sub, T2 const& start, T3 const& end) const
    {
        return base::rfind(object(sub), object(start), object(end));
    }

    template <class T>
    long rindex(T const& sub) const
    {
        return base::rindex(object(sub));
    }

    template <class T1, class T2>
    long rindex(T1 const& sub, T2 const& start) const
    {
        return base::rindex(object(sub), object(start));
    }

    template <class T1, class T2, class T3>
    long rindex(T1 const& sub, T2 const& start, T3 const& end) const
    {
        return base::rindex(object(sub), object(start), object(end));
    }

    template <class T>
    str rjust(T const& width) const
    {
        return base::rjust(object(width));
    }

    list split() const { return base::split(); }

    template <class T>
    list split(T const& sep) const
    {
        return base::split(object(sep));
    }

    template <class T1, class T2>
    list split(T1 const& sep, T2 const& maxsplit) const
    {
        return base::split(object(sep), object(maxsplit));
    }

    list splitlines() const { return base::splitlines(); }

    template <class T>
    list splitlines(T const& keepends) const
    {
        return base::splitlines(object(keepends));
    }

    template <class T>
    bool startswith(T const& prefix) const
    {
        return base::startswith(object(prefix));
    }

    template <class T1, class T2>
    bool startswith(T1 const& prefix, T2 const& start) const
    {
        return base::startswith(object(prefix), object(start));
    }

    template <class T1, class T2, class T3>
    bool startswith(T1 const& prefix, T2 const& start, T3 const& end) const
    {
        return base::startswith(object(prefix), object(start), object(end));
    }

    template <class T>
    str translate(T const& table) const
    {
        return base::translate(object(table));
    }

    template <class T1, class T2>
    str translate(T1 const& table, T2 const& deletechars) const
    {
        return base::translate(object(table), object(deletechars));
    }

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

//
// Converter Specializations
//
namespace converter
{
  template <>
  struct object_manager_traits<str>
#if PY_VERSION_HEX >= 0x03000000
      : pytype_object_manager_traits<&PyUnicode_Type,str>
#else
      : pytype_object_manager_traits<&PyString_Type,str>
#endif
  {
  };
}

}}  // namespace boost::python

#endif // STR_20020703_HPP


code:
//  (C) Copyright Joel de Guzman 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 PY_CONTAINER_UTILS_JDG20038_HPP
# define PY_CONTAINER_UTILS_JDG20038_HPP

# include <utility>
# include <boost/foreach.hpp>
# include <boost/python/object.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/extract.hpp>
# include <boost/python/stl_iterator.hpp>

namespace boost { namespace python { namespace container_utils {

    template <typename Container>
    void
    extend_container(Container& container, object l)
    {
        typedef typename Container::value_type data_type;

        //  l must be iterable
        BOOST_FOREACH(object elem,
            std::make_pair(
              boost::python::stl_input_iterator<object>(l),
              boost::python::stl_input_iterator<object>()
              ))
        {
            extract<data_type const&> x(elem);
            //  try if elem is an exact data_type type
            if (x.check())
            {
                container.push_back(x());
            }
            else
            {
                //  try to convert elem to data_type type
                extract<data_type> x(elem);
                if (x.check())
                {
                    container.push_back(x());
                }
                else
                {
                    PyErr_SetString(PyExc_TypeError, "Incompatible Data Type");
                    throw_error_already_set();
                }
            }
        }
    }

}}} // namespace boost::python::container_utils

#endif


code:
//  (C) Copyright Joel de Guzman 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 INDEXING_SUITE_DETAIL_JDG20036_HPP
# define INDEXING_SUITE_DETAIL_JDG20036_HPP

# include <boost/python/extract.hpp>
# include <boost/scoped_ptr.hpp>
# include <boost/get_pointer.hpp>
# include <boost/detail/binary_search.hpp>
# include <boost/numeric/conversion/cast.hpp>
# include <boost/type_traits/is_pointer.hpp>
# include <vector>
# include <map>
#include <iostream>

namespace boost { namespace python { namespace detail {

#if defined(NDEBUG)
#define BOOST_PYTHON_INDEXING_CHECK_INVARIANT
#else
#define BOOST_PYTHON_INDEXING_CHECK_INVARIANT check_invariant()
#endif

    template <class Proxy>
    struct compare_proxy_index
    {
        //  This functor compares a proxy and an index.
        //  This is used by proxy_group::first_proxy to
        //  get first proxy with index i.

        template <class Index>
        bool operator()(PyObject* prox, Index i) const
        {
            typedef typename Proxy::policies_type policies_type;
            Proxy& proxy = extract<Proxy&>(prox)();
            return policies_type::
                compare_index(proxy.get_container(), proxy.get_index(), i);
        }
    };

    //  The proxy_group class holds a vector of container element
    //  proxies. First, what is a container element proxy? A container
    //  element proxy acts like a smart pointer holding a reference to
    //  a container and an index (see container_element, for details).
    //
    //  The proxies are held in a vector always sorted by its index.
    //  Various functions manage the addition, removal and searching
    //  of proxies from the vector.
    //
    template <class Proxy>
    class proxy_group
    {
    public:

        typedef typename std::vector<PyObject*>::const_iterator const_iterator;
        typedef typename std::vector<PyObject*>::iterator iterator;
        typedef typename Proxy::index_type index_type;
        typedef typename Proxy::policies_type policies_type;

        iterator
        first_proxy(index_type i)
        {
            // Return the first proxy with index <= i
            return boost::detail::lower_bound(
                proxies.begin(), proxies.end(),
                i, compare_proxy_index<Proxy>());
        }

        void
        remove(Proxy& proxy)
        {
            // Remove a proxy
            for (iterator iter = first_proxy(proxy.get_index());
                iter != proxies.end(); ++iter)
            {
                if (&extract<Proxy&>(*iter)() == &proxy)
                {
                    proxies.erase(iter);
                    break;
                }
            }
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
        }

        void
        add(PyObject* prox)
        {
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            // Add a proxy
            proxies.insert(
                first_proxy(extract<Proxy&>(prox)().get_index()), prox);
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
        }

        void
        erase(index_type i, mpl::false_)
        {
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            // Erase the proxy with index i
            replace(i, i+1, 0);
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
        }

        void
        erase(index_type i, mpl::true_)
        {
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            // Erase the proxy with index i

            iterator iter = first_proxy(i);
            extract<Proxy&> p(*iter);

            if (iter != proxies.end() && p().get_index() == i)
            {
                extract<Proxy&> p(*iter);
                p().detach();
                proxies.erase(iter);
            }
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
        }

        void
        erase(index_type from, index_type to)
        {
            // note: this cannot be called when container is not sliceable

            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            // Erase all proxies with indexes from..to
            replace(from, to, 0);
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
        }

        void
        replace(
            index_type from,
            index_type to,
            typename std::vector<PyObject*>::size_type len)
        {
            // note: this cannot be called when container is not sliceable

            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            // Erase all proxies with indexes from..to.
            // Adjust the displaced indexes such that the
            // final effect is that we have inserted *len*
            // number of proxies in the vacated region. This
            // procedure involves adjusting the indexes of
            // the proxies.

            iterator left = first_proxy(from);
            iterator right = proxies.end(); // we'll adjust this later

            for (iterator iter = left; iter != right; ++iter)
            {
                if (extract<Proxy&>(*iter)().get_index() > to)
                {
                    right = iter; // adjust right
                    break;
                }
                extract<Proxy&> p(*iter);
                p().detach();
            }

            typename std::vector<PyObject*>::size_type
                offset = left-proxies.begin();
            proxies.erase(left, right);
            right = proxies.begin()+offset;

            while (right != proxies.end())
            {
                typedef typename Proxy::container_type::difference_type difference_type;
                extract<Proxy&> p(*right);
                p().set_index(
                    extract<Proxy&>(*right)().get_index()
                    - (difference_type(to) - from - len)
                );

                ++right;
            }
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
        }

        PyObject*
        find(index_type i)
        {
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            // Find the proxy with *exact* index i.
            // Return 0 (null) if no proxy with the
            // given index is found.
            iterator iter = first_proxy(i);
            if (iter != proxies.end()
                && extract<Proxy&>(*iter)().get_index() == i)
            {
                BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
                return *iter;
            }
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            return 0;
        }

        typename std::vector<PyObject*>::size_type
        size() const
        {
            BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
            // How many proxies are there so far?
            return proxies.size();
        }

    private:

#if !defined(NDEBUG)
        void
        check_invariant() const
        {
            for (const_iterator i = proxies.begin(); i != proxies.end(); ++i)
            {
                if ((*i)->ob_refcnt <= 0)
                {
                    PyErr_SetString(PyExc_RuntimeError,
                        "Invariant: Proxy vector in an inconsistent state");
                    throw_error_already_set();
                }

                if (i+1 != proxies.end())
                {
                    if (extract<Proxy&>(*(i+1))().get_index() ==
                        extract<Proxy&>(*(i))().get_index())
                    {
                        PyErr_SetString(PyExc_RuntimeError,
                            "Invariant: Proxy vector in an inconsistent state (duplicate proxy)");
                        throw_error_already_set();
                    }
                }
            }
        }
#endif

        std::vector<PyObject*> proxies;
    };

    // proxy_links holds a map of Container pointers (keys)
    // with proxy_group(s) (data). Various functions manage
    // the addition, removal and searching of proxies from
    // the map.
    //
    template <class Proxy, class Container>
    class proxy_links
    {
    public:

        typedef std::map<Container*, proxy_group<Proxy> > links_t;
        typedef typename Proxy::index_type index_type;

        void
        remove(Proxy& proxy)
        {
            // Remove a proxy.
            typename links_t::iterator r = links.find(&proxy.get_container());
            if (r != links.end())
            {
                r->second.remove(proxy);
                if (r->second.size() == 0)
                    links.erase(r);
            }
        }

        void
        add(PyObject* prox, Container& container)
        {
            // Add a proxy
            links[&container].add(prox);
        }

        template <class NoSlice>
        void erase(Container& container, index_type i, NoSlice no_slice)
        {
            // Erase the proxy with index i
            typename links_t::iterator r = links.find(&container);
            if (r != links.end())
            {
                r->second.erase(i, no_slice);
                if (r->second.size() == 0)
                    links.erase(r);
            }
        }

        void
        erase(Container& container, index_type from, index_type to)
        {
            // Erase all proxies with indexes from..to
            typename links_t::iterator r = links.find(&container);
            if (r != links.end())
            {
                r->second.erase(from, to);
                if (r->second.size() == 0)
                    links.erase(r);
            }
        }

        void
        replace(
            Container& container,
            index_type from, index_type to, index_type len)
        {
            // Erase all proxies with indexes from..to.
            // Adjust the displaced indexes such that the
            // final effect is that we have inserted *len*
            // number of proxies in the vacated region. This
            // procedure involves adjusting the indexes of
            // the proxies.

            typename links_t::iterator r = links.find(&container);
            if (r != links.end())
            {
                r->second.replace(from, to, len);
                if (r->second.size() == 0)
                    links.erase(r);
            }
        }

        PyObject*
        find(Container& container, index_type i)
        {
            // Find the proxy with *exact* index i.
            // Return 0 (null) if no proxy with the given
            // index is found.
            typename links_t::iterator r = links.find(&container);
            if (r != links.end())
                return r->second.find(i);
            return 0;
        }

    private:

        links_t links;
    };

    // container_element is our container proxy class.
    // This class acts like a smart pointer to a container
    // element. The class holds an index and a reference to
    // a container. Dereferencing the smart pointer will
    // retrieve the nth (index) element from the container.
    //
    // A container_element can also be detached from the
    // container. In such a detached state, the container_element
    // holds a copy of the nth (index) element, which it
    // returns when dereferenced.
    //
    template <class Container, class Index, class Policies>
    class container_element
    {
    public:

        typedef Index index_type;
        typedef Container container_type;
        typedef typename Policies::data_type element_type;
        typedef Policies policies_type;
        typedef container_element<Container, Index, Policies> self_t;
        typedef proxy_group<self_t> links_type;

        container_element(object container, Index index)
            : ptr()
            , container(container)
            , index(index)
        {
        }

        container_element(container_element const& ce)
          : ptr(ce.ptr.get() == 0 ? 0 : new element_type(*ce.ptr.get()))
          , container(ce.container)
          , index(ce.index)
        {
        }

        ~container_element()
        {
            if (!is_detached())
                get_links().remove(*this);
        }

        element_type& operator*() const
        {
            if (is_detached())
                return *get_pointer(ptr);
            return Policies::get_item(get_container(), index);
        }

        element_type* get() const
        {
            if (is_detached())
                return get_pointer(ptr);
            return &Policies::get_item(get_container(), index);
        }

        void
        detach()
        {
            if (!is_detached())
            {
                ptr.reset(
                    new element_type(
                        Policies::get_item(get_container(), index)));
                container = object(); // free container. reset it to None
            }
        }

        bool
        is_detached() const
        {
            return get_pointer(ptr) != 0;
        }

        Container&
        get_container() const
        {
            return extract<Container&>(container)();
        }

        Index
        get_index() const
        {
            return index;
        }

        void
        set_index(Index i)
        {
            index = i;
        }

        static proxy_links<self_t, Container>&
        get_links()
        {
            // All container_element(s) maintain links to
            // its container in a global map (see proxy_links).
            // This global "links" map is a singleton.

            static proxy_links<self_t, Container> links;
            return links; // singleton
        }

    private:

        container_element& operator=(container_element const& ce);

        scoped_ptr<element_type> ptr;
        object container;
        Index index;
    };

    template <
          class Container
        , class DerivedPolicies
        , class ContainerElement
        , class Index
    >
    struct no_proxy_helper
    {
        static void
        register_container_element()
        {
        }

        template <class DataType>
        static object
        base_get_item_helper(DataType const& p, mpl::true_)
        {
            return object(ptr(p));
        }

        template <class DataType>
        static object
        base_get_item_helper(DataType const& x, mpl::false_)
        {
            return object(x);
        }

        static object
        base_get_item_(back_reference<Container&> const& container, PyObject* i)
        {
            return base_get_item_helper(
                DerivedPolicies::get_item(
                    container.get(), DerivedPolicies::
                        convert_index(container.get(), i))
              , is_pointer<BOOST_DEDUCED_TYPENAME Container::value_type>()
            );
        }

        static void
        base_replace_indexes(
            Container& /*container*/, Index /*from*/,
            Index /*to*/, Index /*n*/)
        {
        }

        template <class NoSlice>
        static void
        base_erase_index(
            Container& /*container*/, Index /*i*/, NoSlice /*no_slice*/)
        {
        }

        static void
        base_erase_indexes(Container& /*container*/, Index /*from*/, Index /*to*/)
        {
        }
    };

    template <
          class Container
        , class DerivedPolicies
        , class ContainerElement
        , class Index
    >
    struct proxy_helper
    {
        static void
        register_container_element()
        {
            register_ptr_to_python<ContainerElement>();
        }

        static object
        base_get_item_(back_reference<Container&> const& container, PyObject* i)
        {
            // Proxy
            Index idx = DerivedPolicies::convert_index(container.get(), i);

            if (PyObject* shared =
                ContainerElement::get_links().find(container.get(), idx))
            {
                handle<> h(python::borrowed(shared));
                return object(h);
            }
            else
            {
                object prox(ContainerElement(container.source(), idx));
                ContainerElement::
                    get_links().add(prox.ptr(), container.get());
                return prox;
            }
        }

        static void
        base_replace_indexes(
            Container& container, Index from,
            Index to, Index n)
        {
            ContainerElement::get_links().replace(container, from, to, n);
        }

        template <class NoSlice>
        static void
        base_erase_index(
            Container& container, Index i, NoSlice no_slice)
        {
            ContainerElement::get_links().erase(container, i, no_slice);
        }

        static void
        base_erase_indexes(
            Container& container, Index from, Index to)
        {
            ContainerElement::get_links().erase(container, from, to);
        }
    };

    template <
          class Container
        , class DerivedPolicies
        , class ProxyHandler
        , class Data
        , class Index
    >
    struct slice_helper
    {
        static object
        base_get_slice(Container& container, PySliceObject* slice)
        {
            Index from, to;
            base_get_slice_data(container, slice, from, to);
            return DerivedPolicies::get_slice(container, from, to);
        }

        static void
        base_get_slice_data(
            Container& container, PySliceObject* slice, Index& from_, Index& to_)
        {
            if (Py_None != slice->step) {
                PyErr_SetString( PyExc_IndexError, "slice step size not supported.");
                throw_error_already_set();
            }

            Index min_index = DerivedPolicies::get_min_index(container);
            Index max_index = DerivedPolicies::get_max_index(container);

            if (Py_None == slice->start) {
                from_ = min_index;
            }
            else {
                long from = extract<long>( slice->start);
                if (from < 0) // Negative slice index
                    from += max_index;
                if (from < 0) // Clip lower bounds to zero
                    from = 0;
                from_ = boost::numeric_cast<Index>(from);
                if (from_ > max_index) // Clip upper bounds to max_index.
                    from_ = max_index;
            }

            if (Py_None == slice->stop) {
                to_ = max_index;
            }
            else {
                long to = extract<long>( slice->stop);
                if (to < 0)
                    to += max_index;
                if (to < 0)
                    to = 0;
                to_ = boost::numeric_cast<Index>(to);
                if (to_ > max_index)
                    to_ = max_index;
            }
        }

        static void
        base_set_slice(Container& container, PySliceObject* slice, PyObject* v)
        {
            Index from, to;
            base_get_slice_data(container, slice, from, to);

            extract<Data&> elem(v);
            // try if elem is an exact Data
            if (elem.check())
            {
                ProxyHandler::base_replace_indexes(container, from, to, 1);
                DerivedPolicies::set_slice(container, from, to, elem());
            }
            else
            {
                //  try to convert elem to Data
                extract<Data> elem(v);
                if (elem.check())
                {
                    ProxyHandler::base_replace_indexes(container, from, to, 1);
                    DerivedPolicies::set_slice(container, from, to, elem());
                }
                else
                {
                    //  Otherwise, it must be a list or some container
                    handle<> l_(python::borrowed(v));
                    object l(l_);

                    std::vector<Data> temp;
                    for (int i = 0; i < l.attr("__len__")(); i++)
                    {
                        object elem(l[i]);
                        extract<Data const&> x(elem);
                        //  try if elem is an exact Data type
                        if (x.check())
                        {
                            temp.push_back(x());
                        }
                        else
                        {
                            //  try to convert elem to Data type
                            extract<Data> x(elem);
                            if (x.check())
                            {
                                temp.push_back(x());
                            }
                            else
                            {
                                PyErr_SetString(PyExc_TypeError,
                                    "Invalid sequence element");
                                throw_error_already_set();
                            }
                        }
                    }

                    ProxyHandler::base_replace_indexes(container, from, to,
                        temp.end()-temp.begin());
                    DerivedPolicies::set_slice(container, from, to,
                        temp.begin(), temp.end());
                }
            }
        }

        static void
        base_delete_slice(Container& container, PySliceObject* slice)
        {
            Index from, to;
            base_get_slice_data(container, slice, from, to);
            ProxyHandler::base_erase_indexes(container, from, to);
            DerivedPolicies::delete_slice(container, from, to);
        }
    };

    template <
          class Container
        , class DerivedPolicies
        , class ProxyHandler
        , class Data
        , class Index
    >
    struct no_slice_helper
    {
        static void
        slicing_not_suported()
        {
            PyErr_SetString(PyExc_RuntimeError, "Slicing not supported");
            throw_error_already_set();
        }

        static object
        base_get_slice(Container& /*container*/, PySliceObject* /*slice*/)
        {
            slicing_not_suported();
            return object();
        }

        static void
        base_set_slice(Container& /*container*/, PySliceObject* /*slice*/, PyObject* /*v*/)
        {
            slicing_not_suported();
        }

        static void
        base_delete_slice(Container& /*container*/, PySliceObject* /*slice*/)
        {
            slicing_not_suported();
        }
    };

#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
}} // namespace python::detail
#endif

    template <class Container, class Index, class Policies>
    inline typename Policies::data_type*
    get_pointer(
        python::detail::container_element<Container, Index, Policies> const& p)
    {
        // Get the pointer of a container_element smart pointer
        return p.get();
    }

#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
    // Don't hide these other get_pointer overloads
    using boost::python::get_pointer;
    using boost::get_pointer;
}} // namespace python::detail
#endif

} // namespace boost

#endif // INDEXING_SUITE_DETAIL_JDG20036_HPP


code:
//  (C) Copyright Joel de Guzman 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 INDEXING_SUITE_JDG20036_HPP
# define INDEXING_SUITE_JDG20036_HPP

# include <boost/python/class.hpp>
# include <boost/python/def_visitor.hpp>
# include <boost/python/register_ptr_to_python.hpp>
# include <boost/python/suite/indexing/detail/indexing_suite_detail.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/iterator.hpp>
# include <boost/mpl/or.hpp>
# include <boost/mpl/not.hpp>
# include <boost/type_traits/is_same.hpp>

namespace boost { namespace python {

    // indexing_suite class. This class is the facade class for
    // the management of C++ containers intended to be integrated
    // to Python. The objective is make a C++ container look and
    // feel and behave exactly as we'd expect a Python container.
    // By default indexed elements are returned by proxy. This can be
    // disabled by supplying *true* in the NoProxy template parameter.
    //
    // Derived classes provide the hooks needed by the indexing_suite
    // to do its job:
    //
    //      static data_type&
    //      get_item(Container& container, index_type i);
    //
    //      static object
    //      get_slice(Container& container, index_type from, index_type to);
    //
    //      static void
    //      set_item(Container& container, index_type i, data_type const& v);
    //
    //      static void
    //      set_slice(
    //         Container& container, index_type from,
    //         index_type to, data_type const& v
    //      );
    //
    //      template <class Iter>
    //      static void
    //      set_slice(Container& container, index_type from,
    //          index_type to, Iter first, Iter last
    //      );
    //
    //      static void
    //      delete_item(Container& container, index_type i);
    //
    //      static void
    //      delete_slice(Container& container, index_type from, index_type to);
    //
    //      static size_t
    //      size(Container& container);
    //
    //      template <class T>
    //      static bool
    //      contains(Container& container, T const& val);
    //
    //      static index_type
    //      convert_index(Container& container, PyObject* i);
    //
    //      static index_type
    //      adjust_index(index_type current, index_type from,
    //          index_type to, size_type len
    //      );
    //
    // Most of these policies are self explanatory. convert_index and
    // adjust_index, however, deserves some explanation.
    //
    // convert_index converts an Python index into a C++ index that the
    // container can handle. For instance, negative indexes in Python, by
    // convention, indexes from the right (e.g. C[-1] indexes the rightmost
    // element in C). convert_index should handle the necessary conversion
    // for the C++ container (e.g. convert -1 to C.size()-1). convert_index
    // should also be able to convert the type of the index (A dynamic Python
    // type) to the actual type that the C++ container expects.
    //
    // When a container expands or contracts, held indexes to its elements
    // must be adjusted to follow the movement of data. For instance, if
    // we erase 3 elements, starting from index 0 from a 5 element vector,
    // what used to be at index 4 will now be at index 1:
    //
    //      [a][b][c][d][e] ---> [d][e]
    //                   ^           ^
    //                   4           1
    //
    // adjust_index takes care of the adjustment. Given a current index,
    // the function should return the adjusted index when data in the
    // container at index from..to is replaced by *len* elements.
    //

    template <
          class Container
        , class DerivedPolicies
        , bool NoProxy = false
        , bool NoSlice = false
        , class Data = typename Container::value_type
        , class Index = typename Container::size_type
        , class Key = typename Container::value_type
    >
    class indexing_suite
        : public def_visitor<
            indexing_suite<
              Container
            , DerivedPolicies
            , NoProxy
            , NoSlice
            , Data
            , Index
            , Key
        > >
    {
    private:

        typedef mpl::or_<
            mpl::bool_<NoProxy>
          , mpl::not_<is_class<Data> >
          , typename mpl::or_<
                is_same<Data, std::string>
              , is_same<Data, std::complex<float> >
              , is_same<Data, std::complex<double> >
              , is_same<Data, std::complex<long double> > >::type>
        no_proxy;

        typedef detail::container_element<Container, Index, DerivedPolicies>
            container_element_t;

        typedef return_internal_reference<> return_policy;

        typedef typename mpl::if_<
            no_proxy
          , iterator<Container>
          , iterator<Container, return_policy> >::type
        def_iterator;

        typedef typename mpl::if_<
            no_proxy
          , detail::no_proxy_helper<
                Container
              , DerivedPolicies
              , container_element_t
              , Index>
          , detail::proxy_helper<
                Container
              , DerivedPolicies
              , container_element_t
              , Index> >::type
        proxy_handler;

        typedef typename mpl::if_<
            mpl::bool_<NoSlice>
          , detail::no_slice_helper<
                Container
              , DerivedPolicies
              , proxy_handler
              , Data
              , Index>
          , detail::slice_helper<
                Container
              , DerivedPolicies
              , proxy_handler
              , Data
              , Index> >::type
        slice_handler;

    public:

        template <class Class>
        void visit(Class& cl) const
        {
            // Hook into the class_ generic visitation .def function
            proxy_handler::register_container_element();

            cl
                .def("__len__", base_size)
                .def("__setitem__", &base_set_item)
                .def("__delitem__", &base_delete_item)
                .def("__getitem__", &base_get_item)
                .def("__contains__", &base_contains)
                .def("__iter__", def_iterator())
            ;

            DerivedPolicies::extension_def(cl);
        }

        template <class Class>
        static void
        extension_def(Class& cl)
        {
            // default.
            // no more extensions
        }

    private:

        static object
        base_get_item(back_reference<Container&> container, PyObject* i)
        {
            if (PySlice_Check(i))
                return slice_handler::base_get_slice(
                    container.get(), static_cast<PySliceObject*>(static_cast<void*>(i)));

            return proxy_handler::base_get_item_(container, i);
        }

        static void
        base_set_item(Container& container, PyObject* i, PyObject* v)
        {
            if (PySlice_Check(i))
            {
                 slice_handler::base_set_slice(container,
                     static_cast<PySliceObject*>(static_cast<void*>(i)), v);
            }
            else
            {
                extract<Data&> elem(v);
                // try if elem is an exact Data
                if (elem.check())
                {
                    DerivedPolicies::
                        set_item(container,
                            DerivedPolicies::
                                convert_index(container, i), elem());
                }
                else
                {
                    //  try to convert elem to Data
                    extract<Data> elem(v);
                    if (elem.check())
                    {
                        DerivedPolicies::
                            set_item(container,
                                DerivedPolicies::
                                    convert_index(container, i), elem());
                    }
                    else
                    {
                        PyErr_SetString(PyExc_TypeError, "Invalid assignment");
                        throw_error_already_set();
                    }
                }
            }
        }

        static void
        base_delete_item(Container& container, PyObject* i)
        {
            if (PySlice_Check(i))
            {
                slice_handler::base_delete_slice(
                    container, static_cast<PySliceObject*>(static_cast<void*>(i)));
                return;
            }

            Index index = DerivedPolicies::convert_index(container, i);
            proxy_handler::base_erase_index(container, index, mpl::bool_<NoSlice>());
            DerivedPolicies::delete_item(container, index);
        }

        static size_t
        base_size(Container& container)
        {
            return DerivedPolicies::size(container);
        }

        static bool
        base_contains(Container& container, PyObject* key)
        {
            extract<Key const&> x(key);
            //  try if key is an exact Key type
            if (x.check())
            {
                return DerivedPolicies::contains(container, x());
            }
            else
            {
                //  try to convert key to Key type
                extract<Key> x(key);
                if (x.check())
                    return DerivedPolicies::contains(container, x());
                else
                    return false;
            }
        }
    };

}} // namespace boost::python

#endif // INDEXING_SUITE_JDG20036_HPP


code:
//  (C) Copyright Joel de Guzman 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 VECTOR_INDEXING_SUITE_JDG20036_HPP
# define VECTOR_INDEXING_SUITE_JDG20036_HPP

# include <boost/python/suite/indexing/indexing_suite.hpp>
# include <boost/python/suite/indexing/container_utils.hpp>
# include <boost/python/iterator.hpp>

namespace boost { namespace python {

    // Forward declaration
    template <class Container, bool NoProxy, class DerivedPolicies>
    class vector_indexing_suite;

    namespace detail
    {
        template <class Container, bool NoProxy>
        class final_vector_derived_policies
            : public vector_indexing_suite<Container,
                NoProxy, final_vector_derived_policies<Container, NoProxy> > {};
    }

    // The vector_indexing_suite class is a predefined indexing_suite derived
    // class for wrapping std::vector (and std::vector like) classes. It provides
    // all the policies required by the indexing_suite (see indexing_suite).
    // Example usage:
    //
    //  class X {...};
    //
    //  ...
    //
    //      class_<std::vector<X> >("XVec")
    //          .def(vector_indexing_suite<std::vector<X> >())
    //      ;
    //
    // By default indexed elements are returned by proxy. This can be
    // disabled by supplying *true* in the NoProxy template parameter.
    //
    template <
        class Container,
        bool NoProxy = false,
        class DerivedPolicies
            = detail::final_vector_derived_policies<Container, NoProxy> >
    class vector_indexing_suite
        : public indexing_suite<Container, DerivedPolicies, NoProxy>
    {
    public:

        typedef typename Container::value_type data_type;
        typedef typename Container::value_type key_type;
        typedef typename Container::size_type index_type;
        typedef typename Container::size_type size_type;
        typedef typename Container::difference_type difference_type;

        template <class Class>
        static void
        extension_def(Class& cl)
        {
            cl
                .def("append", &base_append)
                .def("extend", &base_extend)
            ;
        }

        static
        typename mpl::if_<
            is_class<data_type>
          , data_type&
          , data_type
        >::type
        get_item(Container& container, index_type i)
        {
            return container[i];
        }

        static object
        get_slice(Container& container, index_type from, index_type to)
        {
            if (from > to)
                return object(Container());
            return object(Container(container.begin()+from, container.begin()+to));
        }

        static void
        set_item(Container& container, index_type i, data_type const& v)
        {
            container[i] = v;
        }

        static void
        set_slice(Container& container, index_type from,
            index_type to, data_type const& v)
        {
            if (from > to) {
                return;
            }
            else {
                container.erase(container.begin()+from, container.begin()+to);
                container.insert(container.begin()+from, v);
            }
        }

        template <class Iter>
        static void
        set_slice(Container& container, index_type from,
            index_type to, Iter first, Iter last)
        {
            if (from > to) {
                container.insert(container.begin()+from, first, last);
            }
            else {
                container.erase(container.begin()+from, container.begin()+to);
                container.insert(container.begin()+from, first, last);
            }
        }

        static void
        delete_item(Container& container, index_type i)
        {
            container.erase(container.begin()+i);
        }

        static void
        delete_slice(Container& container, index_type from, index_type to)
        {
            if (from > to) {
                // A null-op.
                return;
            }
            container.erase(container.begin()+from, container.begin()+to);
        }

        static size_t
        size(Container& container)
        {
            return container.size();
        }

        static bool
        contains(Container& container, key_type const& key)
        {
            return std::find(container.begin(), container.end(), key)
                != container.end();
        }

        static index_type
        get_min_index(Container& /*container*/)
        {
            return 0;
        }

        static index_type
        get_max_index(Container& container)
        {
            return container.size();
        }

        static bool
        compare_index(Container& /*container*/, index_type a, index_type b)
        {
            return a < b;
        }

        static index_type
        convert_index(Container& container, PyObject* i_)
        {
            extract<long> i(i_);
            if (i.check())
            {
                long index = i();
                if (index < 0)
                    index += DerivedPolicies::size(container);
                if (index >= long(container.size()) || index < 0)
                {
                    PyErr_SetString(PyExc_IndexError, "Index out of range");
                    throw_error_already_set();
                }
                return index;
            }

            PyErr_SetString(PyExc_TypeError, "Invalid index type");
            throw_error_already_set();
            return index_type();
        }

        static void
        append(Container& container, data_type const& v)
        {
            container.push_back(v);
        }

        template <class Iter>
        static void
        extend(Container& container, Iter first, Iter last)
        {
            container.insert(container.end(), first, last);
        }

    private:

        static void
        base_append(Container& container, object v)
        {
            extract<data_type&> elem(v);
            // try if elem is an exact Data
            if (elem.check())
            {
                DerivedPolicies::append(container, elem());
            }
            else
            {
                //  try to convert elem to data_type
                extract<data_type> elem(v);
                if (elem.check())
                {
                    DerivedPolicies::append(container, elem());
                }
                else
                {
                    PyErr_SetString(PyExc_TypeError,
                        "Attempting to append an invalid type");
                    throw_error_already_set();
                }
            }
        }

        static void
        base_extend(Container& container, object v)
        {
            std::vector<data_type> temp;
            container_utils::extend_container(temp, v);
            DerivedPolicies::extend(container, temp.begin(), temp.end());
        }
    };

}} // namespace boost::python

#endif // VECTOR_INDEXING_SUITE_JDG20036_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 TAG_DWA2002720_HPP
# define TAG_DWA2002720_HPP

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

namespace boost { namespace python {

// used only to prevent argument-dependent lookup from finding the
// wrong function in some cases. Cheaper than qualification.
enum tag_t { tag };

}} // namespace boost::python

#endif // TAG_DWA2002720_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 TO_PYTHON_CONVERTER_DWA200221_HPP
# define TO_PYTHON_CONVERTER_DWA200221_HPP

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

# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/as_to_python_function.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/python/type_id.hpp>

namespace boost { namespace python {

#if 0 //get_pytype member detection
namespace detail
{
    typedef char yes_type;
    typedef struct {char a[2]; } no_type;
    template<PyTypeObject const * (*f)()> struct test_get_pytype1 { };
    template<PyTypeObject * (*f)()>          struct test_get_pytype2 { };

    template<class T> yes_type tester(test_get_pytype1<&T::get_pytype>*);

    template<class T> yes_type tester(test_get_pytype2<&T::get_pytype>*);

    template<class T> no_type tester(...);

    template<class T>
    struct test_get_pytype_base
    {
        BOOST_STATIC_CONSTANT(bool, value= (sizeof(detail::tester<T>(0)) == sizeof(yes_type)));
    };

    template<class T>
    struct test_get_pytype : boost::mpl::bool_<test_get_pytype_base<T>::value>
    {
    };

}
#endif

template < class T, class Conversion, bool has_get_pytype=false >
struct to_python_converter
{
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    typedef boost::mpl::bool_<has_get_pytype> HasGetPytype;

    static PyTypeObject const* get_pytype_1(boost::mpl::true_ *)
    {
        return Conversion::get_pytype();
    }

    static PyTypeObject const* get_pytype_1(boost::mpl::false_ *)
    {
        return 0;
    }
    static PyTypeObject const* get_pytype_impl()
    {
        return get_pytype_1((HasGetPytype*)0);
    }
#endif

    to_python_converter();
};

//
// implementation
//

template <class T, class Conversion ,bool has_get_pytype>
to_python_converter<T,Conversion, has_get_pytype>::to_python_converter()
{
    typedef converter::as_to_python_function<
        T, Conversion
        > normalized;

    converter::registry::insert(
        &normalized::convert
        , type_id<T>()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
        , &get_pytype_impl
#endif
        );
}

}} // namespace boost::python

#endif // TO_PYTHON_CONVERTER_DWA200221_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 TO_PYTHON_INDIRECT_DWA200221_HPP
# define TO_PYTHON_INDIRECT_DWA200221_HPP

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

# include <boost/python/object/pointer_holder.hpp>
# include <boost/python/object/make_ptr_instance.hpp>

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

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

# include <boost/python/refcount.hpp>

# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_polymorphic.hpp>

# include <boost/mpl/bool.hpp>

# if defined(__ICL) && __ICL < 600
#  include <boost/shared_ptr.hpp>
# else
#  include <memory>
# endif

namespace boost { namespace python {

template <class T, class MakeHolder>
struct to_python_indirect
{
    template <class U>
    inline PyObject*
    operator()(U const& ref) const
    {
        return this->execute(const_cast<U&>(ref), is_pointer<U>());
    }
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    inline PyTypeObject const*
    get_pytype()const
    {
        return converter::registered_pytype<T>::get_pytype();
    }
#endif
 private:
    template <class U>
    inline PyObject* execute(U* ptr, mpl::true_) const
    {
        // No special NULL treatment for references
        if (ptr == 0)
            return python::detail::none();
        else
            return this->execute(*ptr, mpl::false_());
    }

    template <class U>
    inline PyObject* execute(U const& x, mpl::false_) const
    {
        U* const p = &const_cast<U&>(x);
        if (is_polymorphic<U>::value)
        {
            if (PyObject* o = detail::wrapper_base_::owner(p))
                return incref(o);
        }
        return MakeHolder::execute(p);
    }
};

//
// implementations
//
namespace detail
{
  struct make_owning_holder
  {
      template <class T>
      static PyObject* execute(T* p)
      {
          // can't use auto_ptr with Intel 5 and VC6 Dinkum library
          // for some reason. We get link errors against the auto_ptr
          // copy constructor.
# if defined(__ICL) && __ICL < 600
          typedef boost::shared_ptr<T> smart_pointer;
# elif __cplusplus < 201103L
          typedef std::auto_ptr<T> smart_pointer;
# else
          typedef std::unique_ptr<T> smart_pointer;
# endif
          typedef objects::pointer_holder<smart_pointer, T> holder_t;

          smart_pointer ptr(const_cast<T*>(p));
          return objects::make_ptr_instance<T, holder_t>::execute(ptr);
      }
  };

  struct make_reference_holder
  {
      template <class T>
      static PyObject* execute(T* p)
      {
          typedef objects::pointer_holder<T*, T> holder_t;
          T* q = const_cast<T*>(p);
          return objects::make_ptr_instance<T, holder_t>::execute(q);
      }
  };
}

}} // namespace boost::python

#endif // TO_PYTHON_INDIRECT_DWA200221_HPP


code:
// Copyright David Abrahams 2002.
// 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_to_python_value_hpp_
#define boost_python_to_python_value_hpp_

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

#include <boost/python/refcount.hpp>
#include <boost/python/tag.hpp>
#include <boost/python/handle.hpp>

#include <boost/python/converter/registry.hpp>
#include <boost/python/converter/registered.hpp>
#include <boost/python/converter/builtin_converters.hpp>
#include <boost/python/converter/object_manager.hpp>
#include <boost/python/converter/shared_ptr_to_python.hpp>

#include <boost/python/detail/value_is_shared_ptr.hpp>
#include <boost/python/detail/value_arg.hpp>

#include <boost/type_traits/transform_traits.hpp>

#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_const.hpp>

namespace boost { namespace python {

namespace detail
{
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES

template <bool is_const_ref>
struct object_manager_get_pytype
{
   template <class U>
   static PyTypeObject const* get( U& (*)() =0)
   {
      return converter::object_manager_traits<U>::get_pytype();
   }
};

template <>
struct object_manager_get_pytype<true>
{
   template <class U>
   static PyTypeObject const* get( U const& (*)() =0)
   {
      return converter::object_manager_traits<U>::get_pytype();
   }
};

#endif

  template <class T>
  struct object_manager_to_python_value
  {
      typedef typename value_arg<T>::type argument_type;

      PyObject* operator()(argument_type) const;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
      typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
      typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
      PyTypeObject const* get_pytype() const {
          return get_pytype_aux((is_t_handle*)0);
      }

      inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}

      inline static PyTypeObject const* get_pytype_aux(mpl::false_* )
      {
          return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
      }

#endif

      // This information helps make_getter() decide whether to try to
      // return an internal reference or not. I don't like it much,
      // but it will have to serve for now.
      BOOST_STATIC_CONSTANT(bool, uses_registry = false);
  };

  template <class T>
  struct registry_to_python_value
  {
      typedef typename value_arg<T>::type argument_type;

      PyObject* operator()(argument_type) const;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
      PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
#endif

      // This information helps make_getter() decide whether to try to
      // return an internal reference or not. I don't like it much,
      // but it will have to serve for now.
      BOOST_STATIC_CONSTANT(bool, uses_registry = true);
  };

  template <class T>
  struct shared_ptr_to_python_value
  {
      typedef typename value_arg<T>::type argument_type;

      PyObject* operator()(argument_type) const;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
      PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);}
#endif
      // This information helps make_getter() decide whether to try to
      // return an internal reference or not. I don't like it much,
      // but it will have to serve for now.
      BOOST_STATIC_CONSTANT(bool, uses_registry = false);
  private:
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    template <class U>
    PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
    template <class U>
    PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
# if __cplusplus >= 201103L
    template <class U>
    PyTypeObject const* get_pytype(boost::type<std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
    template <class U>
    PyTypeObject const* get_pytype(boost::type<const std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
# endif
#endif
  };
}

template <class T>
struct to_python_value
    : mpl::if_<
          detail::value_is_shared_ptr<T>
        , detail::shared_ptr_to_python_value<T>
        , typename mpl::if_<
              mpl::or_<
                  converter::is_object_manager<T>
                , converter::is_reference_to_object_manager<T>
              >
            , detail::object_manager_to_python_value<T>
            , detail::registry_to_python_value<T>
          >::type
      >::type
{
};

//
// implementation
//
namespace detail
{
  template <class T>
  inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
  {
      return converter::registered<argument_type>::converters.to_python(&x);
  }

  template <class T>
  inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const
  {
      return python::upcast<PyObject>(
          python::xincref(
              get_managed_object(x, tag))
          );
  }

  template <class T>
  inline PyObject* shared_ptr_to_python_value<T>::operator()(argument_type x) const
  {
      return converter::shared_ptr_to_python(x);
  }
}

}} // namespace boost::python

#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 TUPLE_20020706_HPP
#define TUPLE_20020706_HPP

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

#include <boost/python/object.hpp>
#include <boost/python/converter/pytype_object_mgr_traits.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>

namespace boost { namespace python {

namespace detail
{
  struct BOOST_PYTHON_DECL tuple_base : object
  {
   protected:
      tuple_base();
      tuple_base(object_cref sequence);

      BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple_base, object)

   private:
      static detail::new_reference call(object const&);
  };
}

class tuple : public detail::tuple_base
{
    typedef detail::tuple_base base;
 public:
    tuple() {}

    template <class T>
    explicit tuple(T const& sequence)
        : base(object(sequence))
    {
    }

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

//
// Converter Specializations    // $$$ JDG $$$ moved here to prevent
//                              // G++ bug complaining specialization
                                // provided after instantiation
namespace converter
{
  template <>
  struct object_manager_traits<tuple>
      : pytype_object_manager_traits<&PyTuple_Type,tuple>
  {
  };
}

// for completeness
inline tuple make_tuple() { return tuple(); }

# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/make_tuple.hpp>))
# include BOOST_PP_ITERATE()

}}  // namespace boost::python

#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 TYPE_ID_DWA2002517_HPP
# define TYPE_ID_DWA2002517_HPP

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

# include <boost/python/detail/msvc_typeinfo.hpp>
# include <boost/operators.hpp>
# include <typeinfo>
# include <cstring>
# include <ostream>
# include <boost/static_assert.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/type_traits/same_traits.hpp>

#  ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
#   if defined(__GNUC__)                                                \
    && !defined(__EDG_VERSION__)
#    define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
#   endif
#  endif

namespace boost { namespace python {

// for this compiler at least, cross-shared-library type_info
// comparisons don't work, so use typeid(x).name() instead. It's not
// yet clear what the best default strategy is.
# if defined(__GNUC__) \
 || defined(_AIX) \
 || (   defined(__sgi) && defined(__host_mips)) \
 || (defined(__hpux) && defined(__HP_aCC)) \
 || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
#  define BOOST_PYTHON_TYPE_ID_NAME
# endif

#ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
// Runtime detection of broken cxxabi::__cxa_demangle versions,
// to avoid #ifdef clutter.
bool cxxabi_cxa_demangle_is_broken();
#define BOOST_PYTHON_HAVE_CXXABI_CXA_DEMANGLE_IS_BROKEN
#endif

// type ids which represent the same information as std::type_info
// (i.e. the top-level reference and cv-qualifiers are stripped), but
// which works across shared libraries.
struct type_info : private totally_ordered<type_info>
{
    inline type_info(std::type_info const& = typeid(void));

    inline bool operator<(type_info const& rhs) const;
    inline bool operator==(type_info const& rhs) const;

    char const* name() const;
    friend BOOST_PYTHON_DECL std::ostream& operator<<(
        std::ostream&, type_info const&);

 private: // data members
#  ifdef BOOST_PYTHON_TYPE_ID_NAME
    typedef char const* base_id_t;
#  else
    typedef std::type_info const* base_id_t;
#  endif

    base_id_t m_base_type;
};

// This macro is obsolete. Port away and remove.
# define BOOST_PYTHON_EXPLICIT_TT_DEF(T)

template <class T>
inline type_info type_id()
{
    return type_info(
#  if !defined(_MSC_VER)                                       \
      || !BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700)
        typeid(T)
#  else // strip the decoration which Intel mistakenly leaves in
        python::detail::msvc_typeid((boost::type<T>*)0)
#  endif
        );
}

#  if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
   || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
// Older EDG-based compilers seems to mistakenly distinguish "int" from
// "signed int", etc., but only in typeid() expressions. However
// though int == signed int, the "signed" decoration is propagated
// down into template instantiations. Explicit specialization stops
// that from taking hold.

#   define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T)              \
template <>                                                     \
inline type_info type_id<T>()                                   \
{                                                               \
    return type_info(typeid(T));                                \
}

BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short)
BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int)
BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long)
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
#   ifdef HAVE_LONG_LONG
BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long)
#   endif
#   undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID
#  endif

//
inline type_info::type_info(std::type_info const& id)
    : m_base_type(
#  ifdef BOOST_PYTHON_TYPE_ID_NAME
        id.name()
#  else
        &id
#  endif
        )
{
}

inline bool type_info::operator<(type_info const& rhs) const
{
#  ifdef BOOST_PYTHON_TYPE_ID_NAME
    return std::strcmp(m_base_type, rhs.m_base_type) < 0;
#  else
    return m_base_type->before(*rhs.m_base_type);
#  endif
}

inline bool type_info::operator==(type_info const& rhs) const
{
#  ifdef BOOST_PYTHON_TYPE_ID_NAME
    return !std::strcmp(m_base_type, rhs.m_base_type);
#  else
    return *m_base_type == *rhs.m_base_type;
#  endif
}

#  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
namespace detail
{
  BOOST_PYTHON_DECL char const* gcc_demangle(char const*);
}
#  endif

inline char const* type_info::name() const
{
    char const* raw_name
        = m_base_type
#  ifndef BOOST_PYTHON_TYPE_ID_NAME
          ->name()
#  endif
        ;

#  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
    return detail::gcc_demangle(raw_name);
#  else
    return raw_name;
#  endif
}

BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&);

template<>
inline type_info type_id<void>()
{
    return type_info (typeid (void *));
}
#   ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template<>
inline type_info type_id<const volatile void>()
{
    return type_info (typeid (void *));
}
#  endif

}} // namespace boost::python

#endif // TYPE_ID_DWA2002517_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 WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
# define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP

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

# include <boost/python/default_call_policies.hpp>
# include <boost/python/object/life_support.hpp>
# include <algorithm>

namespace boost { namespace python {

namespace detail
{
  template <std::size_t N>
  struct get_prev
  {
      template <class ArgumentPackage>
      static PyObject* execute(ArgumentPackage const& args, PyObject* = 0)
      {
          int const pre_n = static_cast<int>(N) - 1; // separate line is gcc-2.96 workaround
          return detail::get(mpl::int_<pre_n>(), args);
      }
  };
  template <>
  struct get_prev<0>
  {
      template <class ArgumentPackage>
      static PyObject* execute(ArgumentPackage const&, PyObject* zeroth)
      {
          return zeroth;
      }
  };
}
template <
    std::size_t custodian
  , std::size_t ward
  , class BasePolicy_ = default_call_policies
>
struct with_custodian_and_ward : BasePolicy_
{
    BOOST_STATIC_ASSERT(custodian != ward);
    BOOST_STATIC_ASSERT(custodian > 0);
    BOOST_STATIC_ASSERT(ward > 0);

    template <class ArgumentPackage>
    static bool precall(ArgumentPackage const& args_)
    {
        unsigned arity_ = detail::arity(args_);
        if (custodian > arity_ || ward > arity_)
        {
            PyErr_SetString(
                PyExc_IndexError
              , "boost::python::with_custodian_and_ward: argument index out of range"
            );
            return false;
        }

        PyObject* patient = detail::get_prev<ward>::execute(args_);
        PyObject* nurse = detail::get_prev<custodian>::execute(args_);

        PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient);
        if (life_support == 0)
            return false;

        bool result = BasePolicy_::precall(args_);

        if (!result) {
            Py_DECREF(life_support);
        }

        return result;
    }
};

template <std::size_t custodian, std::size_t ward, class BasePolicy_ = default_call_policies>
struct with_custodian_and_ward_postcall : BasePolicy_
{
    BOOST_STATIC_ASSERT(custodian != ward);

    template <class ArgumentPackage>
    static PyObject* postcall(ArgumentPackage const& args_, PyObject* result)
    {
        std::size_t arity_ = detail::arity(args_);
        // check if either custodian or ward exceeds the arity
        // (this weird formulation avoids "always false" warnings
        // for arity_ = 0)
        if ( (std::max)(custodian, ward) > arity_ )
        {
            PyErr_SetString(
                PyExc_IndexError
              , "boost::python::with_custodian_and_ward_postcall: argument index out of range"
            );
            return 0;
        }

        PyObject* patient = detail::get_prev<ward>::execute(args_, result);
        PyObject* nurse = detail::get_prev<custodian>::execute(args_, result);

        if (nurse == 0) return 0;

        result = BasePolicy_::postcall(args_, result);
        if (result == 0)
            return 0;

        if (python::objects::make_nurse_and_patient(nurse, patient) == 0)
        {
            Py_XDECREF(result);
            return 0;
        }
        return result;
    }
};

}} // namespace boost::python

#endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP


code:
// Copyright David Abrahams 2004. 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 WRAPPER_DWA2004720_HPP
# define WRAPPER_DWA2004720_HPP

# include <boost/python/detail/wrapper_base.hpp>
# include <boost/python/override.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/sfinae.hpp>

namespace boost { namespace python {

template <class T>
class wrapper : public detail::wrapper_base
{
 public:
    // Do not touch this implementation detail!
    typedef T _wrapper_wrapped_type_;

 protected:
    override get_override(char const* name) const
    {
        typedef detail::wrapper_base base;
        converter::registration const& r
            = converter::registered<T>::converters;
        PyTypeObject* type = r.get_class_object();

        return this->base::get_override(name, type);
    }
};

}} // namespace boost::python

#endif // WRAPPER_DWA2004720_HPP


code:
/* boost random.hpp header file
 *
 * Copyright Jens Maurer 2000-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)
 *
 * See http://www.boost.org/libs/random for documentation.
 *
 * $Id$
 *
 * Revision history
 *  2000-02-18  portability fixes (thanks to Beman Dawes)
 *  2000-02-21  shuffle_output, inversive_congruential_schrage,
 *              generator_iterator, uniform_smallint
 *  2000-02-23  generic modulus arithmetic helper, removed *_schrage classes,
 *              implemented Streamable and EqualityComparable concepts for
 *              generators, added Bernoulli distribution and Box-Muller
 *              transform
 *  2000-03-01  cauchy, lognormal, triangle distributions; fixed
 *              uniform_smallint; renamed gaussian to normal distribution
 *  2000-03-05  implemented iterator syntax for distribution functions
 *  2000-04-21  removed some optimizations for better BCC/MSVC compatibility
 *  2000-05-10  adapted to BCC and MSVC
 *  2000-06-13  incorporated review results
 *  2000-07-06  moved basic templates from namespace detail to random
 *  2000-09-23  warning removals and int64 fixes (Ed Brey)
 *  2000-09-24  added lagged_fibonacci generator (Matthias Troyer)
 *  2001-02-18  moved to individual header files
 */

#ifndef BOOST_RANDOM_HPP
#define BOOST_RANDOM_HPP

// generators
#include <boost/random/additive_combine.hpp>
#include <boost/random/discard_block.hpp>
#include <boost/random/independent_bits.hpp>
#include <boost/random/inversive_congruential.hpp>
#include <boost/random/lagged_fibonacci.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/linear_feedback_shift.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/ranlux.hpp>
#include <boost/random/shuffle_order.hpp>
#include <boost/random/shuffle_output.hpp>
#include <boost/random/subtract_with_carry.hpp>
#include <boost/random/taus88.hpp>
#include <boost/random/xor_combine.hpp>

// misc
#include <boost/random/generate_canonical.hpp>
#include <boost/random/seed_seq.hpp>
#include <boost/random/random_number_generator.hpp>
#include <boost/random/variate_generator.hpp>

// distributions
#include <boost/random/bernoulli_distribution.hpp>
#include <boost/random/beta_distribution.hpp>
#include <boost/random/binomial_distribution.hpp>
#include <boost/random/cauchy_distribution.hpp>
#include <boost/random/chi_squared_distribution.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
#include <boost/random/extreme_value_distribution.hpp>
#include <boost/random/fisher_f_distribution.hpp>
#include <boost/random/gamma_distribution.hpp>
#include <boost/random/geometric_distribution.hpp>
#include <boost/random/hyperexponential_distribution.hpp>
#include <boost/random/laplace_distribution.hpp>
#include <boost/random/lognormal_distribution.hpp>
#include <boost/random/negative_binomial_distribution.hpp>
#include <boost/random/non_central_chi_squared_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/piecewise_constant_distribution.hpp>
#include <boost/random/piecewise_linear_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/student_t_distribution.hpp>
#include <boost/random/triangle_distribution.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/uniform_on_sphere.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/weibull_distribution.hpp>

#include <boost/random/generate_canonical.hpp>

#endif // BOOST_RANDOM_HPP