summaryrefslogtreecommitdiff
path: root/boost/python/converter
diff options
context:
space:
mode:
Diffstat (limited to 'boost/python/converter')
-rw-r--r--boost/python/converter/arg_from_python.hpp336
-rw-r--r--boost/python/converter/arg_to_python.hpp261
-rw-r--r--boost/python/converter/arg_to_python_base.hpp32
-rw-r--r--boost/python/converter/as_to_python_function.hpp49
-rw-r--r--boost/python/converter/builtin_converters.hpp190
-rw-r--r--boost/python/converter/constructor_function.hpp17
-rw-r--r--boost/python/converter/context_result_converter.hpp17
-rw-r--r--boost/python/converter/convertible_function.hpp14
-rw-r--r--boost/python/converter/from_python.hpp41
-rw-r--r--boost/python/converter/implicit.hpp46
-rw-r--r--boost/python/converter/obj_mgr_arg_from_python.hpp121
-rw-r--r--boost/python/converter/object_manager.hpp230
-rw-r--r--boost/python/converter/pointer_type_id.hpp68
-rw-r--r--boost/python/converter/pyobject_traits.hpp46
-rw-r--r--boost/python/converter/pyobject_type.hpp37
-rw-r--r--boost/python/converter/pytype_function.hpp132
-rw-r--r--boost/python/converter/pytype_object_mgr_traits.hpp42
-rw-r--r--boost/python/converter/registered.hpp111
-rw-r--r--boost/python/converter/registered_pointee.hpp62
-rw-r--r--boost/python/converter/registrations.hpp99
-rw-r--r--boost/python/converter/registry.hpp55
-rw-r--r--boost/python/converter/return_from_python.hpp162
-rw-r--r--boost/python/converter/rvalue_from_python_data.hpp140
-rw-r--r--boost/python/converter/shared_ptr_deleter.hpp22
-rw-r--r--boost/python/converter/shared_ptr_from_python.hpp63
-rw-r--r--boost/python/converter/shared_ptr_to_python.hpp28
-rw-r--r--boost/python/converter/to_python_function_type.hpp19
27 files changed, 2440 insertions, 0 deletions
diff --git a/boost/python/converter/arg_from_python.hpp b/boost/python/converter/arg_from_python.hpp
new file mode 100644
index 0000000000..e2edce7e1c
--- /dev/null
+++ b/boost/python/converter/arg_from_python.hpp
@@ -0,0 +1,336 @@
+// 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 ARG_FROM_PYTHON_DWA2002127_HPP
+# define ARG_FROM_PYTHON_DWA2002127_HPP
+
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/converter/from_python.hpp>
+# include <boost/python/detail/indirect_traits.hpp>
+# include <boost/type_traits/transform_traits.hpp>
+# include <boost/type_traits/cv_traits.hpp>
+# include <boost/python/converter/rvalue_from_python_data.hpp>
+# include <boost/mpl/eval_if.hpp>
+# include <boost/mpl/if.hpp>
+# include <boost/mpl/identity.hpp>
+# include <boost/mpl/and.hpp>
+# include <boost/mpl/or.hpp>
+# include <boost/mpl/not.hpp>
+# include <boost/python/converter/registry.hpp>
+# include <boost/python/converter/registered.hpp>
+# include <boost/python/converter/registered_pointee.hpp>
+# include <boost/python/detail/void_ptr.hpp>
+# include <boost/python/back_reference.hpp>
+# include <boost/python/detail/referent_storage.hpp>
+# include <boost/python/converter/obj_mgr_arg_from_python.hpp>
+
+namespace boost { namespace python
+{
+ template <class T> struct arg_from_python;
+}}
+
+// This header defines Python->C++ function argument converters,
+// parametrized on the argument type.
+
+namespace boost { namespace python { namespace converter {
+
+//
+// lvalue converters
+//
+// These require that an lvalue of the type U is stored somewhere in
+// the Python object being converted.
+
+// Used when T == U*const&
+template <class T>
+struct pointer_cref_arg_from_python
+{
+ typedef T result_type;
+
+ pointer_cref_arg_from_python(PyObject*);
+ T operator()() const;
+ bool convertible() const;
+
+ private: // storage for a U*
+ // needed because not all compilers will let us declare U* as the
+ // return type of operator() -- we return U*const& instead
+ typename python::detail::referent_storage<T>::type m_result;
+};
+
+// Base class for pointer and reference converters
+struct arg_lvalue_from_python_base
+{
+ public: // member functions
+ arg_lvalue_from_python_base(void* result);
+ bool convertible() const;
+
+ protected: // member functions
+ void*const& result() const;
+
+ private: // data members
+ void* m_result;
+};
+
+// Used when T == U*
+template <class T>
+struct pointer_arg_from_python : arg_lvalue_from_python_base
+{
+ typedef T result_type;
+
+ pointer_arg_from_python(PyObject*);
+ T operator()() const;
+};
+
+// Used when T == U& and (T != V const& or T == W volatile&)
+template <class T>
+struct reference_arg_from_python : arg_lvalue_from_python_base
+{
+ typedef T result_type;
+
+ reference_arg_from_python(PyObject*);
+ T operator()() const;
+};
+
+// ===================
+
+//
+// rvalue converters
+//
+// These require only that an object of type T can be created from
+// the given Python object, but not that the T object exist
+// somewhere in storage.
+//
+
+// Used when T is a plain value (non-pointer, non-reference) type or
+// a (non-volatile) const reference to a plain value type.
+template <class T>
+struct arg_rvalue_from_python
+{
+ typedef typename boost::add_reference<
+ T
+ // We can't add_const here, or it would be impossible to pass
+ // auto_ptr<U> args from Python to C++
+ >::type result_type;
+
+ arg_rvalue_from_python(PyObject*);
+ bool convertible() const;
+
+# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
+ typename arg_rvalue_from_python<T>::
+# endif
+ result_type operator()();
+
+ private:
+ rvalue_from_python_data<result_type> m_data;
+ PyObject* m_source;
+};
+
+
+// ==================
+
+// Converts to a (PyObject*,T) bundle, for when you need a reference
+// back to the Python object
+template <class T>
+struct back_reference_arg_from_python
+ : boost::python::arg_from_python<typename T::type>
+{
+ typedef T result_type;
+
+ back_reference_arg_from_python(PyObject*);
+ T operator()();
+ private:
+ typedef boost::python::arg_from_python<typename T::type> base;
+ PyObject* m_source;
+};
+
+
+// ==================
+
+template <class C, class T, class F>
+struct if_2
+{
+ typedef typename mpl::eval_if<C, mpl::identity<T>, F>::type type;
+};
+
+// This metafunction selects the appropriate arg_from_python converter
+// type for an argument of type T.
+template <class T>
+struct select_arg_from_python
+{
+ typedef typename if_2<
+ is_object_manager<T>
+ , object_manager_value_arg_from_python<T>
+ , if_2<
+ is_reference_to_object_manager<T>
+ , object_manager_ref_arg_from_python<T>
+ , if_2<
+ is_pointer<T>
+ , pointer_arg_from_python<T>
+ , if_2<
+ mpl::and_<
+ indirect_traits::is_reference_to_pointer<T>
+ , indirect_traits::is_reference_to_const<T>
+ , mpl::not_<indirect_traits::is_reference_to_volatile<T> >
+ >
+ , pointer_cref_arg_from_python<T>
+ , if_2<
+ mpl::or_<
+ indirect_traits::is_reference_to_non_const<T>
+ , indirect_traits::is_reference_to_volatile<T>
+ >
+ , reference_arg_from_python<T>
+ , mpl::if_<
+ boost::python::is_back_reference<T>
+ , back_reference_arg_from_python<T>
+ , arg_rvalue_from_python<T>
+ >
+ >
+ >
+ >
+ >
+ >::type type;
+};
+
+// ==================
+
+//
+// implementations
+//
+
+// arg_lvalue_from_python_base
+//
+inline arg_lvalue_from_python_base::arg_lvalue_from_python_base(void* result)
+ : m_result(result)
+{
+}
+
+inline bool arg_lvalue_from_python_base::convertible() const
+{
+ return m_result != 0;
+}
+
+inline void*const& arg_lvalue_from_python_base::result() const
+{
+ return m_result;
+}
+
+// pointer_cref_arg_from_python
+//
+namespace detail
+{
+ // null_ptr_reference -- a function returning a reference to a null
+ // pointer of type U. Needed so that extractors for T*const& can
+ // convert Python's None.
+ template <class T>
+ struct null_ptr_owner
+ {
+ static T value;
+ };
+ template <class T> T null_ptr_owner<T>::value = 0;
+
+ template <class U>
+ inline U& null_ptr_reference(U&(*)())
+ {
+ return null_ptr_owner<U>::value;
+ }
+}
+
+template <class T>
+inline pointer_cref_arg_from_python<T>::pointer_cref_arg_from_python(PyObject* p)
+{
+ // T == U*const&: store a U* in the m_result storage. Nonzero
+ // indicates success. If find returns nonzero, it's a pointer to
+ // a U object.
+ python::detail::write_void_ptr_reference(
+ m_result.bytes
+ , p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters)
+ , (T(*)())0);
+}
+
+template <class T>
+inline bool pointer_cref_arg_from_python<T>::convertible() const
+{
+ return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0;
+}
+template <class T>
+inline T pointer_cref_arg_from_python<T>::operator()() const
+{
+ return (*(void**)m_result.bytes == Py_None) // None ==> 0
+ ? detail::null_ptr_reference((T(*)())0)
+ // Otherwise, return a U*const& to the m_result storage.
+ : python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
+}
+
+// pointer_arg_from_python
+//
+template <class T>
+inline pointer_arg_from_python<T>::pointer_arg_from_python(PyObject* p)
+ : arg_lvalue_from_python_base(
+ p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters))
+{
+}
+
+template <class T>
+inline T pointer_arg_from_python<T>::operator()() const
+{
+ return (result() == Py_None) ? 0 : T(result());
+}
+
+// reference_arg_from_python
+//
+template <class T>
+inline reference_arg_from_python<T>::reference_arg_from_python(PyObject* p)
+ : arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered<T>::converters))
+{
+}
+
+template <class T>
+inline T reference_arg_from_python<T>::operator()() const
+{
+ return python::detail::void_ptr_to_reference(result(), (T(*)())0);
+}
+
+
+// arg_rvalue_from_python
+//
+template <class T>
+inline arg_rvalue_from_python<T>::arg_rvalue_from_python(PyObject* obj)
+ : m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters))
+ , m_source(obj)
+{
+}
+
+template <class T>
+inline bool arg_rvalue_from_python<T>::convertible() const
+{
+ return m_data.stage1.convertible != 0;
+}
+
+template <class T>
+inline typename arg_rvalue_from_python<T>::result_type
+arg_rvalue_from_python<T>::operator()()
+{
+ if (m_data.stage1.construct != 0)
+ m_data.stage1.construct(m_source, &m_data.stage1);
+
+ return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
+}
+
+// back_reference_arg_from_python
+//
+template <class T>
+back_reference_arg_from_python<T>::back_reference_arg_from_python(PyObject* x)
+ : base(x), m_source(x)
+{
+}
+
+template <class T>
+inline T
+back_reference_arg_from_python<T>::operator()()
+{
+ return T(m_source, base::operator()());
+}
+
+}}} // namespace boost::python::converter
+
+#endif // ARG_FROM_PYTHON_DWA2002127_HPP
diff --git a/boost/python/converter/arg_to_python.hpp b/boost/python/converter/arg_to_python.hpp
new file mode 100644
index 0000000000..3a19ec4395
--- /dev/null
+++ b/boost/python/converter/arg_to_python.hpp
@@ -0,0 +1,261 @@
+// 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 ARG_TO_PYTHON_DWA200265_HPP
+# define ARG_TO_PYTHON_DWA200265_HPP
+
+# include <boost/python/ptr.hpp>
+# include <boost/python/tag.hpp>
+# include <boost/python/to_python_indirect.hpp>
+
+# include <boost/python/converter/registered.hpp>
+# include <boost/python/converter/registered_pointee.hpp>
+# include <boost/python/converter/arg_to_python_base.hpp>
+# include <boost/python/converter/shared_ptr_to_python.hpp>
+// Bring in specializations
+# include <boost/python/converter/builtin_converters.hpp>
+
+# include <boost/python/object/function_handle.hpp>
+
+# include <boost/python/base_type_traits.hpp>
+
+# include <boost/python/detail/indirect_traits.hpp>
+# include <boost/python/detail/convertible.hpp>
+# include <boost/python/detail/string_literal.hpp>
+# include <boost/python/detail/value_is_shared_ptr.hpp>
+
+# include <boost/type_traits/cv_traits.hpp>
+# include <boost/type_traits/composite_traits.hpp>
+# include <boost/type_traits/function_traits.hpp>
+
+
+# include <boost/mpl/or.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+template <class T> struct is_object_manager;
+
+namespace detail
+{
+ template <class T>
+ struct function_arg_to_python : handle<>
+ {
+ function_arg_to_python(T const& x);
+ };
+
+ template <class T>
+ struct reference_arg_to_python : handle<>
+ {
+ reference_arg_to_python(T& x);
+ private:
+ static PyObject* get_object(T& x);
+ };
+
+ template <class T>
+ struct shared_ptr_arg_to_python : handle<>
+ {
+ shared_ptr_arg_to_python(T const& x);
+ private:
+ static PyObject* get_object(T& x);
+ };
+
+ template <class T>
+ struct value_arg_to_python : arg_to_python_base
+ {
+ // Throw an exception if the conversion can't succeed
+ value_arg_to_python(T const&);
+ };
+
+ template <class Ptr>
+ struct pointer_deep_arg_to_python : arg_to_python_base
+ {
+ // Throw an exception if the conversion can't succeed
+ pointer_deep_arg_to_python(Ptr);
+ };
+
+ template <class Ptr>
+ struct pointer_shallow_arg_to_python : handle<>
+ {
+ // Throw an exception if the conversion can't succeed
+ pointer_shallow_arg_to_python(Ptr);
+ private:
+ static PyObject* get_object(Ptr p);
+ };
+
+ // Convert types that manage a Python object to_python
+ template <class T>
+ struct object_manager_arg_to_python
+ {
+ object_manager_arg_to_python(T const& x) : m_src(x) {}
+
+ PyObject* get() const
+ {
+ return python::upcast<PyObject>(get_managed_object(m_src, tag));
+ }
+
+ private:
+ T const& m_src;
+ };
+
+ template <class T>
+ struct select_arg_to_python
+ {
+ typedef typename unwrap_reference<T>::type unwrapped_referent;
+ typedef typename unwrap_pointer<T>::type unwrapped_ptr;
+
+ typedef typename mpl::if_<
+ // Special handling for char const[N]; interpret them as char
+ // const* for the sake of conversion
+ python::detail::is_string_literal<T const>
+ , arg_to_python<char const*>
+
+ , typename mpl::if_<
+ python::detail::value_is_shared_ptr<T>
+ , shared_ptr_arg_to_python<T>
+
+ , typename mpl::if_<
+ mpl::or_<
+ is_function<T>
+ , indirect_traits::is_pointer_to_function<T>
+ , is_member_function_pointer<T>
+ >
+ , function_arg_to_python<T>
+
+ , typename mpl::if_<
+ is_object_manager<T>
+ , object_manager_arg_to_python<T>
+
+ , typename mpl::if_<
+ is_pointer<T>
+ , pointer_deep_arg_to_python<T>
+
+ , typename mpl::if_<
+ is_pointer_wrapper<T>
+ , pointer_shallow_arg_to_python<unwrapped_ptr>
+
+ , typename mpl::if_<
+ is_reference_wrapper<T>
+ , reference_arg_to_python<unwrapped_referent>
+ , value_arg_to_python<T>
+ >::type
+ >::type
+ >::type
+ >::type
+ >::type
+ >::type
+ >::type
+
+ type;
+ };
+}
+
+template <class T>
+struct arg_to_python
+ : detail::select_arg_to_python<T>::type
+{
+ typedef typename detail::select_arg_to_python<T>::type base;
+ public: // member functions
+ // Throw an exception if the conversion can't succeed
+ arg_to_python(T const& x);
+};
+
+//
+// implementations
+//
+namespace detail
+{
+ // reject_raw_object_ptr -- cause a compile-time error if the user
+ // should pass a raw Python object pointer
+ using python::detail::yes_convertible;
+ using python::detail::no_convertible;
+ using python::detail::unspecialized;
+
+ template <class T> struct cannot_convert_raw_PyObject;
+
+ template <class T, class Convertibility>
+ struct reject_raw_object_helper
+ {
+ static void error(Convertibility)
+ {
+ cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
+ }
+ static void error(...) {}
+ };
+
+ template <class T>
+ inline void reject_raw_object_ptr(T*)
+ {
+ reject_raw_object_helper<T,yes_convertible>::error(
+ python::detail::convertible<PyObject const volatile*>::check((T*)0));
+
+ typedef typename remove_cv<T>::type value_type;
+
+ reject_raw_object_helper<T,no_convertible>::error(
+ python::detail::convertible<unspecialized*>::check(
+ (base_type_traits<value_type>*)0
+ ));
+ }
+ // ---------
+
+ template <class T>
+ inline function_arg_to_python<T>::function_arg_to_python(T const& x)
+ : handle<>(python::objects::make_function_handle(x))
+ {
+ }
+
+ template <class T>
+ inline value_arg_to_python<T>::value_arg_to_python(T const& x)
+ : arg_to_python_base(&x, registered<T>::converters)
+ {
+ }
+
+ template <class Ptr>
+ inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
+ : arg_to_python_base(x, registered_pointee<Ptr>::converters)
+ {
+ detail::reject_raw_object_ptr((Ptr)0);
+ }
+
+ template <class T>
+ inline PyObject* reference_arg_to_python<T>::get_object(T& x)
+ {
+ to_python_indirect<T&,python::detail::make_reference_holder> convert;
+ return convert(x);
+ }
+
+ template <class T>
+ inline reference_arg_to_python<T>::reference_arg_to_python(T& x)
+ : handle<>(reference_arg_to_python<T>::get_object(x))
+ {
+ }
+
+ template <class T>
+ inline shared_ptr_arg_to_python<T>::shared_ptr_arg_to_python(T const& x)
+ : handle<>(shared_ptr_to_python(x))
+ {
+ }
+
+ template <class Ptr>
+ inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x)
+ : handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x))
+ {
+ detail::reject_raw_object_ptr((Ptr)0);
+ }
+
+ template <class Ptr>
+ inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)
+ {
+ to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
+ return convert(x);
+ }
+}
+
+template <class T>
+inline arg_to_python<T>::arg_to_python(T const& x)
+ : base(x)
+{}
+
+}}} // namespace boost::python::converter
+
+#endif // ARG_TO_PYTHON_DWA200265_HPP
diff --git a/boost/python/converter/arg_to_python_base.hpp b/boost/python/converter/arg_to_python_base.hpp
new file mode 100644
index 0000000000..d85b302e48
--- /dev/null
+++ b/boost/python/converter/arg_to_python_base.hpp
@@ -0,0 +1,32 @@
+// 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 ARG_TO_PYTHON_BASE_DWA200237_HPP
+# define ARG_TO_PYTHON_BASE_DWA200237_HPP
+# include <boost/python/handle.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+struct registration;
+
+namespace detail
+{
+ struct BOOST_PYTHON_DECL arg_to_python_base
+# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179
+ : handle<>
+# endif
+ {
+ arg_to_python_base(void const volatile* source, registration const&);
+# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102179
+ PyObject* get() const { return m_ptr.get(); }
+ PyObject* release() { return m_ptr.release(); }
+ private:
+ handle<> m_ptr;
+# endif
+ };
+}
+
+}}} // namespace boost::python::converter
+
+#endif // ARG_TO_PYTHON_BASE_DWA200237_HPP
diff --git a/boost/python/converter/as_to_python_function.hpp b/boost/python/converter/as_to_python_function.hpp
new file mode 100644
index 0000000000..19a3efaafc
--- /dev/null
+++ b/boost/python/converter/as_to_python_function.hpp
@@ -0,0 +1,49 @@
+// 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 AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
+# define AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
+# include <boost/python/converter/to_python_function_type.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+// Given a typesafe to_python conversion function, produces a
+// to_python_function_t which can be registered in the usual way.
+template <class T, class ToPython>
+struct as_to_python_function
+{
+ // Assertion functions used to prevent wrapping of converters
+ // which take non-const reference parameters. The T* argument in
+ // the first overload ensures it isn't used in case T is a
+ // reference.
+ template <class U>
+ static void convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0) {}
+ template <class U>
+ static void convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...) {}
+
+ static PyObject* convert(void const* x)
+ {
+ convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L);
+
+ // Yes, the const_cast below opens a hole in const-correctness,
+ // but it's needed to convert auto_ptr<U> to python.
+ //
+ // How big a hole is it? It allows ToPython::convert() to be
+ // a function which modifies its argument. The upshot is that
+ // client converters applied to const objects may invoke
+ // undefined behavior. The damage, however, is limited by the
+ // use of the assertion function. Thus, the only way this can
+ // modify its argument is if T is an auto_ptr-like type. There
+ // is still a const-correctness hole w.r.t. auto_ptr<U> const,
+ // but c'est la vie.
+ return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
+ }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const * get_pytype() { return ToPython::get_pytype(); }
+#endif
+};
+
+}}} // namespace boost::python::converter
+
+#endif // AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
diff --git a/boost/python/converter/builtin_converters.hpp b/boost/python/converter/builtin_converters.hpp
new file mode 100644
index 0000000000..c2e01c03d3
--- /dev/null
+++ b/boost/python/converter/builtin_converters.hpp
@@ -0,0 +1,190 @@
+// 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 BUILTIN_CONVERTERS_DWA2002124_HPP
+# define BUILTIN_CONVERTERS_DWA2002124_HPP
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/detail/none.hpp>
+# include <boost/python/handle.hpp>
+# include <boost/python/ssize_t.hpp>
+# include <boost/implicit_cast.hpp>
+# include <string>
+# include <complex>
+# include <boost/limits.hpp>
+
+// Since all we can use to decide how to convert an object to_python
+// is its C++ type, there can be only one such converter for each
+// type. Therefore, for built-in conversions we can bypass registry
+// lookups using explicit specializations of arg_to_python and
+// result_to_python.
+
+namespace boost { namespace python {
+
+namespace converter
+{
+ template <class T> struct arg_to_python;
+ BOOST_PYTHON_DECL PyObject* do_return_to_python(char);
+ BOOST_PYTHON_DECL PyObject* do_return_to_python(char const*);
+ BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject*);
+ BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject*);
+}
+
+// Provide specializations of to_python_value
+template <class T> struct to_python_value;
+
+namespace detail
+{
+ // Since there's no registry lookup, always report the existence of
+ // a converter.
+ struct builtin_to_python
+ {
+ // 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);
+ };
+}
+
+// Use expr to create the PyObject corresponding to x
+# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr, pytype)\
+ template <> struct to_python_value<T&> \
+ : detail::builtin_to_python \
+ { \
+ inline PyObject* operator()(T const& x) const \
+ { \
+ return (expr); \
+ } \
+ inline PyTypeObject const* get_pytype() const \
+ { \
+ return (pytype); \
+ } \
+ }; \
+ template <> struct to_python_value<T const&> \
+ : detail::builtin_to_python \
+ { \
+ inline PyObject* operator()(T const& x) const \
+ { \
+ return (expr); \
+ } \
+ inline PyTypeObject const* get_pytype() const \
+ { \
+ return (pytype); \
+ } \
+ };
+
+# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
+ namespace converter \
+ { \
+ template <> struct arg_to_python< T > \
+ : handle<> \
+ { \
+ arg_to_python(T const& x) \
+ : python::handle<>(expr) {} \
+ }; \
+ }
+
+// Specialize argument and return value converters for T using expr
+# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr, pytype) \
+ BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr, pytype) \
+ BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
+
+// Specialize converters for signed and unsigned T to Python Int
+#if PY_VERSION_HEX >= 0x03000000
+
+# define BOOST_PYTHON_TO_INT(T) \
+ BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyLong_FromLong(x), &PyLong_Type) \
+ BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, ::PyLong_FromUnsignedLong(x), &PyLong_Type)
+
+#else
+
+# define BOOST_PYTHON_TO_INT(T) \
+ BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x), &PyInt_Type) \
+ BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
+ unsigned T \
+ , static_cast<unsigned long>(x) > static_cast<unsigned long>( \
+ (std::numeric_limits<long>::max)()) \
+ ? ::PyLong_FromUnsignedLong(x) \
+ : ::PyInt_FromLong(x), &PyInt_Type)
+#endif
+
+// Bool is not signed.
+#if PY_VERSION_HEX >= 0x02030000
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type)
+#else
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x), &PyInt_Type)
+#endif
+
+// note: handles signed char and unsigned char, but not char (see below)
+BOOST_PYTHON_TO_INT(char)
+
+BOOST_PYTHON_TO_INT(short)
+BOOST_PYTHON_TO_INT(int)
+BOOST_PYTHON_TO_INT(long)
+
+# if defined(_MSC_VER) && defined(_WIN64) && PY_VERSION_HEX < 0x03000000
+/* Under 64-bit Windows std::size_t is "unsigned long long". To avoid
+ getting a Python long for each std::size_t the value is checked before
+ the conversion. A std::size_t is converted to a simple Python int
+ if possible; a Python long appears only if the value is too small or
+ too large to fit into a simple int. */
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(
+ signed BOOST_PYTHON_LONG_LONG,
+ ( x < static_cast<signed BOOST_PYTHON_LONG_LONG>(
+ (std::numeric_limits<long>::min)())
+ || x > static_cast<signed BOOST_PYTHON_LONG_LONG>(
+ (std::numeric_limits<long>::max)()))
+ ? ::PyLong_FromLongLong(x)
+ : ::PyInt_FromLong(static_cast<long>(x)), &PyInt_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(
+ unsigned BOOST_PYTHON_LONG_LONG,
+ x > static_cast<unsigned BOOST_PYTHON_LONG_LONG>(
+ (std::numeric_limits<long>::max)())
+ ? ::PyLong_FromUnsignedLongLong(x)
+ : ::PyInt_FromLong(static_cast<long>(x)), &PyInt_Type)
+//
+# elif defined(HAVE_LONG_LONG) // using Python's macro instead of Boost's
+ // - we don't seem to get the config right
+ // all the time.
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyLong_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyLong_Type)
+# endif
+
+# undef BOOST_TO_PYTHON_INT
+
+#if PY_VERSION_HEX >= 0x03000000
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyUnicode_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyUnicode_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyUnicode_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
+#else
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
+#endif
+
+#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
+# endif
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x), &PyFloat_Type)
+BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x), 0)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()), &PyComplex_Type)
+
+# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
+# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE
+# undef BOOST_PYTHON_TO_PYTHON_BY_VALUE
+# undef BOOST_PYTHON_TO_INT
+
+namespace converter
+{
+
+ void initialize_builtin_converters();
+
+}
+
+}} // namespace boost::python::converter
+
+#endif // BUILTIN_CONVERTERS_DWA2002124_HPP
diff --git a/boost/python/converter/constructor_function.hpp b/boost/python/converter/constructor_function.hpp
new file mode 100644
index 0000000000..814aa7d763
--- /dev/null
+++ b/boost/python/converter/constructor_function.hpp
@@ -0,0 +1,17 @@
+// 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 CONSTRUCTOR_FUNCTION_DWA200278_HPP
+# define CONSTRUCTOR_FUNCTION_DWA200278_HPP
+
+namespace boost { namespace python { namespace converter {
+
+// Declares the type of functions used to construct C++ objects for
+// rvalue from_python conversions.
+struct rvalue_from_python_stage1_data;
+typedef void (*constructor_function)(PyObject* source, rvalue_from_python_stage1_data*);
+
+}}} // namespace boost::python::converter
+
+#endif // CONSTRUCTOR_FUNCTION_DWA200278_HPP
diff --git a/boost/python/converter/context_result_converter.hpp b/boost/python/converter/context_result_converter.hpp
new file mode 100644
index 0000000000..beb7e9f098
--- /dev/null
+++ b/boost/python/converter/context_result_converter.hpp
@@ -0,0 +1,17 @@
+// Copyright David Abrahams 2003.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
+# define CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
+
+namespace boost { namespace python { namespace converter {
+
+// A ResultConverter base class used to indicate that this result
+// converter should be constructed with the original Python argument
+// list.
+struct context_result_converter {};
+
+}}} // namespace boost::python::converter
+
+#endif // CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
diff --git a/boost/python/converter/convertible_function.hpp b/boost/python/converter/convertible_function.hpp
new file mode 100644
index 0000000000..4b29fbb00b
--- /dev/null
+++ b/boost/python/converter/convertible_function.hpp
@@ -0,0 +1,14 @@
+// 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 CONVERTIBLE_FUNCTION_DWA200278_HPP
+# define CONVERTIBLE_FUNCTION_DWA200278_HPP
+
+namespace boost { namespace python { namespace converter {
+
+typedef void* (*convertible_function)(PyObject*);
+
+}}} // namespace boost::python::converter
+
+#endif // CONVERTIBLE_FUNCTION_DWA200278_HPP
diff --git a/boost/python/converter/from_python.hpp b/boost/python/converter/from_python.hpp
new file mode 100644
index 0000000000..b2f24b3519
--- /dev/null
+++ b/boost/python/converter/from_python.hpp
@@ -0,0 +1,41 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef FIND_FROM_PYTHON_DWA2002223_HPP
+# define FIND_FROM_PYTHON_DWA2002223_HPP
+
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/converter/rvalue_from_python_data.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+struct registration;
+
+
+BOOST_PYTHON_DECL void* get_lvalue_from_python(
+ PyObject* source, registration const&);
+
+BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python(
+ PyObject* source, registration const&);
+
+BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
+ PyObject* source, registration const&);
+
+BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
+ PyObject* source, rvalue_from_python_stage1_data&, registration const&);
+
+BOOST_PYTHON_DECL void* rvalue_result_from_python(
+ PyObject*, rvalue_from_python_stage1_data&);
+
+BOOST_PYTHON_DECL void* reference_result_from_python(PyObject*, registration const&);
+BOOST_PYTHON_DECL void* pointer_result_from_python(PyObject*, registration const&);
+
+BOOST_PYTHON_DECL void void_result_from_python(PyObject*);
+
+BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject*, registration const&);
+BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject*, registration const&);
+
+}}} // namespace boost::python::converter
+
+#endif // FIND_FROM_PYTHON_DWA2002223_HPP
diff --git a/boost/python/converter/implicit.hpp b/boost/python/converter/implicit.hpp
new file mode 100644
index 0000000000..8bbbfd5ac1
--- /dev/null
+++ b/boost/python/converter/implicit.hpp
@@ -0,0 +1,46 @@
+// 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 IMPLICIT_DWA2002326_HPP
+# define IMPLICIT_DWA2002326_HPP
+
+# include <boost/python/converter/rvalue_from_python_data.hpp>
+# include <boost/python/converter/registrations.hpp>
+# include <boost/python/converter/registered.hpp>
+
+# include <boost/python/extract.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+template <class Source, class Target>
+struct implicit
+{
+ static void* convertible(PyObject* obj)
+ {
+ // Find a converter which can produce a Source instance from
+ // obj. The user has told us that Source can be converted to
+ // Target, and instantiating construct() below, ensures that
+ // at compile-time.
+ return implicit_rvalue_convertible_from_python(obj, registered<Source>::converters)
+ ? obj : 0;
+ }
+
+ static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
+ {
+ void* storage = ((rvalue_from_python_storage<Target>*)data)->storage.bytes;
+
+ arg_from_python<Source> get_source(obj);
+ bool convertible = get_source.convertible();
+ BOOST_VERIFY(convertible);
+
+ new (storage) Target(get_source());
+
+ // record successful construction
+ data->convertible = storage;
+ }
+};
+
+}}} // namespace boost::python::converter
+
+#endif // IMPLICIT_DWA2002326_HPP
diff --git a/boost/python/converter/obj_mgr_arg_from_python.hpp b/boost/python/converter/obj_mgr_arg_from_python.hpp
new file mode 100644
index 0000000000..cd4e1e0ea8
--- /dev/null
+++ b/boost/python/converter/obj_mgr_arg_from_python.hpp
@@ -0,0 +1,121 @@
+// 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 OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
+# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
+
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/detail/referent_storage.hpp>
+# include <boost/python/detail/destroy.hpp>
+# include <boost/python/detail/construct.hpp>
+# include <boost/python/converter/object_manager.hpp>
+# include <boost/python/detail/raw_pyobject.hpp>
+# include <boost/python/tag.hpp>
+
+//
+// arg_from_python converters for Python type wrappers, to be used as
+// base classes for specializations.
+//
+namespace boost { namespace python { namespace converter {
+
+template <class T>
+struct object_manager_value_arg_from_python
+{
+ typedef T result_type;
+
+ object_manager_value_arg_from_python(PyObject*);
+ bool convertible() const;
+ T operator()() const;
+ private:
+ PyObject* m_source;
+};
+
+// Used for converting reference-to-object-manager arguments from
+// python. The process used here is a little bit odd. Upon
+// construction, we build the object manager object in the m_result
+// object, *forcing* it to accept the source Python object by casting
+// its pointer to detail::borrowed_reference. This is supposed to
+// bypass any type checking of the source object. The convertible
+// check then extracts the owned object and checks it. If the check
+// fails, nothing else in the program ever gets to touch this strange
+// "forced" object.
+template <class Ref>
+struct object_manager_ref_arg_from_python
+{
+ typedef Ref result_type;
+
+ object_manager_ref_arg_from_python(PyObject*);
+ bool convertible() const;
+ Ref operator()() const;
+ ~object_manager_ref_arg_from_python();
+ private:
+ typename python::detail::referent_storage<Ref>::type m_result;
+};
+
+//
+// implementations
+//
+
+template <class T>
+inline object_manager_value_arg_from_python<T>::object_manager_value_arg_from_python(PyObject* x)
+ : m_source(x)
+{
+}
+
+template <class T>
+inline bool object_manager_value_arg_from_python<T>::convertible() const
+{
+ return object_manager_traits<T>::check(m_source);
+}
+
+template <class T>
+inline T object_manager_value_arg_from_python<T>::operator()() const
+{
+ return T(python::detail::borrowed_reference(m_source));
+}
+
+template <class Ref>
+inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_python(PyObject* x)
+{
+# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
+ // needed for warning suppression
+ python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x);
+ python::detail::construct_referent<Ref>(&m_result.bytes, x_);
+# else
+ python::detail::construct_referent<Ref>(&m_result.bytes, (python::detail::borrowed_reference)x);
+# endif
+}
+
+template <class Ref>
+inline object_manager_ref_arg_from_python<Ref>::~object_manager_ref_arg_from_python()
+{
+ python::detail::destroy_referent<Ref>(this->m_result.bytes);
+}
+
+namespace detail
+{
+ template <class T>
+ inline bool object_manager_ref_check(T const& x)
+ {
+ return object_manager_traits<T>::check(get_managed_object(x, tag));
+ }
+}
+
+template <class Ref>
+inline bool object_manager_ref_arg_from_python<Ref>::convertible() const
+{
+ return detail::object_manager_ref_check(
+ python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0));
+}
+
+template <class Ref>
+inline Ref object_manager_ref_arg_from_python<Ref>::operator()() const
+{
+ return python::detail::void_ptr_to_reference(
+ this->m_result.bytes, (Ref(*)())0);
+}
+
+}}} // namespace boost::python::converter
+
+#endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
diff --git a/boost/python/converter/object_manager.hpp b/boost/python/converter/object_manager.hpp
new file mode 100644
index 0000000000..84e44d475b
--- /dev/null
+++ b/boost/python/converter/object_manager.hpp
@@ -0,0 +1,230 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef OBJECT_MANAGER_DWA2002614_HPP
+# define OBJECT_MANAGER_DWA2002614_HPP
+
+# include <boost/python/handle.hpp>
+# include <boost/python/cast.hpp>
+# include <boost/python/converter/pyobject_traits.hpp>
+# include <boost/type_traits/object_traits.hpp>
+# include <boost/mpl/if.hpp>
+# include <boost/python/detail/indirect_traits.hpp>
+# include <boost/mpl/bool.hpp>
+
+// Facilities for dealing with types which always manage Python
+// objects. Some examples are object, list, str, et. al. Different
+// to_python/from_python conversion rules apply here because in
+// contrast to other types which are typically embedded inside a
+// Python object, these are wrapped around a Python object. For most
+// object managers T, a C++ non-const T reference argument does not
+// imply the existence of a T lvalue embedded in the corresponding
+// Python argument, since mutating member functions on T actually only
+// modify the held Python object.
+//
+// handle<T> is an object manager, though strictly speaking it should
+// not be. In other words, even though mutating member functions of
+// hanlde<T> actually modify the handle<T> and not the T object,
+// handle<T>& arguments of wrapped functions will bind to "rvalues"
+// wrapping the actual Python argument, just as with other object
+// manager classes. Making an exception for handle<T> is simply not
+// worth the trouble.
+//
+// borrowed<T> cv* is an object manager so that we can use the general
+// to_python mechanisms to convert raw Python object pointers to
+// python, without the usual semantic problems of using raw pointers.
+
+
+// Object Manager Concept requirements:
+//
+// T is an Object Manager
+// p is a PyObject*
+// x is a T
+//
+// * object_manager_traits<T>::is_specialized == true
+//
+// * T(detail::borrowed_reference(p))
+// Manages p without checking its type
+//
+// * get_managed_object(x, boost::python::tag)
+// Convertible to PyObject*
+//
+// Additional requirements if T can be converted from_python:
+//
+// * T(object_manager_traits<T>::adopt(p))
+// steals a reference to p, or throws a TypeError exception if
+// p doesn't have an appropriate type. May assume p is non-null
+//
+// * X::check(p)
+// convertible to bool. True iff T(X::construct(p)) will not
+// throw.
+
+// Forward declarations
+//
+namespace boost { namespace python
+{
+ namespace api
+ {
+ class object;
+ }
+}}
+
+namespace boost { namespace python { namespace converter {
+
+
+// Specializations for handle<T>
+template <class T>
+struct handle_object_manager_traits
+ : pyobject_traits<typename T::element_type>
+{
+ private:
+ typedef pyobject_traits<typename T::element_type> base;
+
+ public:
+ BOOST_STATIC_CONSTANT(bool, is_specialized = true);
+
+ // Initialize with a null_ok pointer for efficiency, bypassing the
+ // null check since the source is always non-null.
+ static null_ok<typename T::element_type>* adopt(PyObject* p)
+ {
+ return python::allow_null(base::checked_downcast(p));
+ }
+};
+
+template <class T>
+struct default_object_manager_traits
+{
+ BOOST_STATIC_CONSTANT(
+ bool, is_specialized = python::detail::is_borrowed_ptr<T>::value
+ );
+};
+
+template <class T>
+struct object_manager_traits
+ : mpl::if_c<
+ is_handle<T>::value
+ , handle_object_manager_traits<T>
+ , default_object_manager_traits<T>
+ >::type
+{
+};
+
+//
+// Traits for detecting whether a type is an object manager or a
+// (cv-qualified) reference to an object manager.
+//
+
+template <class T>
+struct is_object_manager
+ : mpl::bool_<object_manager_traits<T>::is_specialized>
+{
+};
+
+# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template <class T>
+struct is_reference_to_object_manager
+ : mpl::false_
+{
+};
+
+template <class T>
+struct is_reference_to_object_manager<T&>
+ : is_object_manager<T>
+{
+};
+
+template <class T>
+struct is_reference_to_object_manager<T const&>
+ : is_object_manager<T>
+{
+};
+
+template <class T>
+struct is_reference_to_object_manager<T volatile&>
+ : is_object_manager<T>
+{
+};
+
+template <class T>
+struct is_reference_to_object_manager<T const volatile&>
+ : is_object_manager<T>
+{
+};
+# else
+
+namespace detail
+{
+ typedef char (&yes_reference_to_object_manager)[1];
+ typedef char (&no_reference_to_object_manager)[2];
+
+ // A number of nastinesses go on here in order to work around MSVC6
+ // bugs.
+ template <class T>
+ struct is_object_manager_help
+ {
+ typedef typename mpl::if_<
+ is_object_manager<T>
+ , yes_reference_to_object_manager
+ , no_reference_to_object_manager
+ >::type type;
+
+ // If we just use the type instead of the result of calling this
+ // function, VC6 will ICE.
+ static type call();
+ };
+
+ // A set of overloads for each cv-qualification. The same argument
+ // is passed twice: the first one is used to unwind the cv*, and the
+ // second one is used to avoid relying on partial ordering for
+ // overload resolution.
+ template <class U>
+ typename is_object_manager_help<U>
+ is_object_manager_helper(U*, void*);
+
+ template <class U>
+ typename is_object_manager_help<U>
+ is_object_manager_helper(U const*, void const*);
+
+ template <class U>
+ typename is_object_manager_help<U>
+ is_object_manager_helper(U volatile*, void volatile*);
+
+ template <class U>
+ typename is_object_manager_help<U>
+ is_object_manager_helper(U const volatile*, void const volatile*);
+
+ template <class T>
+ struct is_reference_to_object_manager_nonref
+ : mpl::false_
+ {
+ };
+
+ template <class T>
+ struct is_reference_to_object_manager_ref
+ {
+ static T sample_object;
+ BOOST_STATIC_CONSTANT(
+ bool, value
+ = (sizeof(is_object_manager_helper(&sample_object, &sample_object).call())
+ == sizeof(detail::yes_reference_to_object_manager)
+ )
+ );
+ typedef mpl::bool_<value> type;
+ };
+}
+
+template <class T>
+struct is_reference_to_object_manager
+ : mpl::if_<
+ is_reference<T>
+ , detail::is_reference_to_object_manager_ref<T>
+ , detail::is_reference_to_object_manager_nonref<T>
+ >::type
+{
+};
+# endif
+
+}}} // namespace boost::python::converter
+
+#endif // OBJECT_MANAGER_DWA2002614_HPP
diff --git a/boost/python/converter/pointer_type_id.hpp b/boost/python/converter/pointer_type_id.hpp
new file mode 100644
index 0000000000..963f58f717
--- /dev/null
+++ b/boost/python/converter/pointer_type_id.hpp
@@ -0,0 +1,68 @@
+// 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 POINTER_TYPE_ID_DWA2002222_HPP
+# define POINTER_TYPE_ID_DWA2002222_HPP
+
+# include <boost/python/type_id.hpp>
+# include <boost/type_traits/composite_traits.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+namespace detail
+{
+ template <bool is_ref = false>
+ struct pointer_typeid_select
+ {
+ template <class T>
+ static inline type_info execute(T*(*)() = 0)
+ {
+ return type_id<T>();
+ }
+ };
+
+ template <>
+ struct pointer_typeid_select<true>
+ {
+ template <class T>
+ static inline type_info execute(T* const volatile&(*)() = 0)
+ {
+ return type_id<T>();
+ }
+
+ template <class T>
+ static inline type_info execute(T*volatile&(*)() = 0)
+ {
+ return type_id<T>();
+ }
+
+ template <class T>
+ static inline type_info execute(T*const&(*)() = 0)
+ {
+ return type_id<T>();
+ }
+
+ template <class T>
+ static inline type_info execute(T*&(*)() = 0)
+ {
+ return type_id<T>();
+ }
+ };
+}
+
+// Usage: pointer_type_id<T>()
+//
+// Returns a type_info associated with the type pointed
+// to by T, which may be a pointer or a reference to a pointer.
+template <class T>
+type_info pointer_type_id(T(*)() = 0)
+{
+ return detail::pointer_typeid_select<
+ is_reference<T>::value
+ >::execute((T(*)())0);
+}
+
+}}} // namespace boost::python::converter
+
+#endif // POINTER_TYPE_ID_DWA2002222_HPP
diff --git a/boost/python/converter/pyobject_traits.hpp b/boost/python/converter/pyobject_traits.hpp
new file mode 100644
index 0000000000..43e384af8d
--- /dev/null
+++ b/boost/python/converter/pyobject_traits.hpp
@@ -0,0 +1,46 @@
+// 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 PYOBJECT_TRAITS_DWA2002720_HPP
+# define PYOBJECT_TRAITS_DWA2002720_HPP
+
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/converter/pyobject_type.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+template <class> struct pyobject_traits;
+
+template <>
+struct pyobject_traits<PyObject>
+{
+ // All objects are convertible to PyObject
+ static bool check(PyObject*) { return true; }
+ static PyObject* checked_downcast(PyObject* x) { return x; }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const* get_pytype() { return 0; }
+#endif
+};
+
+//
+// Specializations
+//
+
+# define BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(T) \
+ template <> struct pyobject_traits<Py##T##Object> \
+ : pyobject_type<Py##T##Object, &Py##T##_Type> {}
+
+// This is not an exhaustive list; should be expanded.
+BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type);
+BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List);
+#if PY_VERSION_HEX < 0x03000000
+BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int);
+#endif
+BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long);
+BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict);
+BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple);
+
+}}} // namespace boost::python::converter
+
+#endif // PYOBJECT_TRAITS_DWA2002720_HPP
diff --git a/boost/python/converter/pyobject_type.hpp b/boost/python/converter/pyobject_type.hpp
new file mode 100644
index 0000000000..526f9f9dba
--- /dev/null
+++ b/boost/python/converter/pyobject_type.hpp
@@ -0,0 +1,37 @@
+// 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 PYOBJECT_TYPE_DWA2002720_HPP
+# define PYOBJECT_TYPE_DWA2002720_HPP
+
+# include <boost/python/cast.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*);
+
+// Used as a base class for specializations which need to provide
+// Python type checking capability.
+template <class Object, PyTypeObject* pytype>
+struct pyobject_type
+{
+ static bool check(PyObject* x)
+ {
+ return ::PyObject_IsInstance(x, (PyObject*)pytype);
+ }
+
+ static Object* checked_downcast(PyObject* x)
+ {
+ return python::downcast<Object>(
+ (checked_downcast_impl)(x, pytype)
+ );
+ }
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ static PyTypeObject const* get_pytype() { return pytype; }
+#endif
+};
+
+}}} // namespace boost::python::converter
+
+#endif // PYOBJECT_TYPE_DWA2002720_HPP
diff --git a/boost/python/converter/pytype_function.hpp b/boost/python/converter/pytype_function.hpp
new file mode 100644
index 0000000000..95d0f66d46
--- /dev/null
+++ b/boost/python/converter/pytype_function.hpp
@@ -0,0 +1,132 @@
+// Copyright David Abrahams 2002, Nikolay Mladenov 2007.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef WRAP_PYTYPE_NM20070606_HPP
+# define WRAP_PYTYPE_NM20070606_HPP
+
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/converter/registered.hpp>
+# include <boost/python/detail/unwind_type.hpp>
+
+
+namespace boost { namespace python {
+
+namespace converter
+{
+template <PyTypeObject const* python_type>
+struct wrap_pytype
+{
+ static PyTypeObject const* get_pytype()
+ {
+ return python_type;
+ }
+};
+
+typedef PyTypeObject const* (*pytype_function)();
+
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+
+
+
+namespace detail
+{
+struct unwind_type_id_helper{
+ typedef python::type_info result_type;
+ template <class U>
+ static result_type execute(U* ){
+ return python::type_id<U>();
+ }
+};
+
+template <class T>
+inline python::type_info unwind_type_id_(boost::type<T>* = 0, mpl::false_ * =0)
+{
+ return boost::python::detail::unwind_type<unwind_type_id_helper, T> ();
+}
+
+inline python::type_info unwind_type_id_(boost::type<void>* = 0, mpl::true_* =0)
+{
+ return type_id<void>();
+}
+
+template <class T>
+inline python::type_info unwind_type_id(boost::type<T>* p= 0)
+{
+ return unwind_type_id_(p, (mpl::bool_<boost::is_void<T>::value >*)0 );
+}
+}
+
+
+template <class T>
+struct expected_pytype_for_arg
+{
+ static PyTypeObject const *get_pytype()
+ {
+ const converter::registration *r=converter::registry::query(
+ detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
+ );
+ return r ? r->expected_from_python_type(): 0;
+ }
+};
+
+
+template <class T>
+struct registered_pytype
+{
+ static PyTypeObject const *get_pytype()
+ {
+ const converter::registration *r=converter::registry::query(
+ detail::unwind_type_id_((boost::type<T>*) 0, (mpl::bool_<boost::is_void<T>::value >*)0 )
+ );
+ return r ? r->m_class_object: 0;
+ }
+};
+
+
+template <class T>
+struct registered_pytype_direct
+{
+ static PyTypeObject const* get_pytype()
+ {
+ return registered<T>::converters.m_class_object;
+ }
+};
+
+template <class T>
+struct expected_from_python_type : expected_pytype_for_arg<T>{};
+
+template <class T>
+struct expected_from_python_type_direct
+{
+ static PyTypeObject const* get_pytype()
+ {
+ return registered<T>::converters.expected_from_python_type();
+ }
+};
+
+template <class T>
+struct to_python_target_type
+{
+ static PyTypeObject const *get_pytype()
+ {
+ const converter::registration *r=converter::registry::query(
+ detail::unwind_type_id_((boost::type<T>*)0, (mpl::bool_<boost::is_void<T>::value >*)0 )
+ );
+ return r ? r->to_python_target_type(): 0;
+ }
+};
+
+template <class T>
+struct to_python_target_type_direct
+{
+ static PyTypeObject const *get_pytype()
+ {
+ return registered<T>::converters.to_python_target_type();
+ }
+};
+#endif
+
+}}} // namespace boost::python
+
+#endif // WRAP_PYTYPE_NM20070606_HPP
diff --git a/boost/python/converter/pytype_object_mgr_traits.hpp b/boost/python/converter/pytype_object_mgr_traits.hpp
new file mode 100644
index 0000000000..8f5b2b7677
--- /dev/null
+++ b/boost/python/converter/pytype_object_mgr_traits.hpp
@@ -0,0 +1,42 @@
+// 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 PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
+# define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
+
+# include <boost/python/detail/prefix.hpp>
+# include <boost/python/detail/raw_pyobject.hpp>
+# include <boost/python/cast.hpp>
+# include <boost/python/converter/pyobject_type.hpp>
+# include <boost/python/errors.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+// Provide a forward declaration as a convenience for clients, who all
+// need it.
+template <class T> struct object_manager_traits;
+
+// Derive specializations of object_manager_traits from this class
+// when T is an object manager for a particular Python type hierarchy.
+//
+template <PyTypeObject* pytype, class T>
+struct pytype_object_manager_traits
+ : pyobject_type<T, pytype> // provides check()
+{
+ BOOST_STATIC_CONSTANT(bool, is_specialized = true);
+ static inline python::detail::new_reference adopt(PyObject*);
+};
+
+//
+// implementations
+//
+template <PyTypeObject* pytype, class T>
+inline python::detail::new_reference pytype_object_manager_traits<pytype,T>::adopt(PyObject* x)
+{
+ return python::detail::new_reference(python::pytype_check(pytype, x));
+}
+
+}}} // namespace boost::python::converter
+
+#endif // PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
diff --git a/boost/python/converter/registered.hpp b/boost/python/converter/registered.hpp
new file mode 100644
index 0000000000..2404cb0ff2
--- /dev/null
+++ b/boost/python/converter/registered.hpp
@@ -0,0 +1,111 @@
+// 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 REGISTERED_DWA2002710_HPP
+# define REGISTERED_DWA2002710_HPP
+# include <boost/python/type_id.hpp>
+# include <boost/python/converter/registry.hpp>
+# include <boost/python/converter/registrations.hpp>
+# include <boost/type_traits/transform_traits.hpp>
+# include <boost/type_traits/cv_traits.hpp>
+# include <boost/type_traits/is_void.hpp>
+# include <boost/detail/workaround.hpp>
+# include <boost/python/type_id.hpp>
+# include <boost/type.hpp>
+
+namespace boost {
+
+// You'll see shared_ptr mentioned in this header because we need to
+// note which types are shared_ptrs in their registrations, to
+// implement special shared_ptr handling for rvalue conversions.
+template <class T> class shared_ptr;
+
+namespace python { namespace converter {
+
+struct registration;
+
+namespace detail
+{
+ template <class T>
+ struct registered_base
+ {
+ static registration const& converters;
+ };
+}
+
+template <class T>
+struct registered
+ : detail::registered_base<
+ typename add_reference<
+ typename add_cv<T>::type
+ >::type
+ >
+{
+};
+
+# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+ && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
+// collapses a few more types to the same static instance. MSVC7.1
+// fails to strip cv-qualification from array types in typeid. For
+// some reason we can't use this collapse there or array converters
+// will not be found.
+template <class T>
+struct registered<T&>
+ : registered<T> {};
+# endif
+
+//
+// implementations
+//
+namespace detail
+{
+ inline void
+ register_shared_ptr0(...)
+ {
+ }
+
+ template <class T>
+ inline void
+ register_shared_ptr0(shared_ptr<T>*)
+ {
+ registry::lookup_shared_ptr(type_id<shared_ptr<T> >());
+ }
+
+ template <class T>
+ inline void
+ register_shared_ptr1(T const volatile*)
+ {
+ detail::register_shared_ptr0((T*)0);
+ }
+
+ template <class T>
+ inline registration const&
+ registry_lookup2(T&(*)())
+ {
+ detail::register_shared_ptr1((T*)0);
+ return registry::lookup(type_id<T&>());
+ }
+
+ template <class T>
+ inline registration const&
+ registry_lookup1(type<T>)
+ {
+ return registry_lookup2((T(*)())0);
+ }
+
+ inline registration const&
+ registry_lookup1(type<const volatile void>)
+ {
+ detail::register_shared_ptr1((void*)0);
+ return registry::lookup(type_id<void>());
+ }
+
+ template <class T>
+ registration const& registered_base<T>::converters = detail::registry_lookup1(type<T>());
+
+}
+
+}}} // namespace boost::python::converter
+
+#endif // REGISTERED_DWA2002710_HPP
diff --git a/boost/python/converter/registered_pointee.hpp b/boost/python/converter/registered_pointee.hpp
new file mode 100644
index 0000000000..d9e7ac75a8
--- /dev/null
+++ b/boost/python/converter/registered_pointee.hpp
@@ -0,0 +1,62 @@
+// 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 REGISTERED_POINTEE_DWA2002710_HPP
+# define REGISTERED_POINTEE_DWA2002710_HPP
+# include <boost/python/converter/registered.hpp>
+# include <boost/python/converter/pointer_type_id.hpp>
+# include <boost/python/converter/registry.hpp>
+# include <boost/type_traits/transform_traits.hpp>
+# include <boost/type_traits/cv_traits.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+struct registration;
+
+# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template <class T>
+struct registered_pointee
+ : registered<
+ typename remove_pointer<
+ typename remove_cv<
+ typename remove_reference<T>::type
+ >::type
+ >::type
+ >
+{
+};
+# else
+namespace detail
+{
+ template <class T>
+ struct registered_pointee_base
+ {
+ static registration const& converters;
+ };
+}
+
+template <class T>
+struct registered_pointee
+ : detail::registered_pointee_base<
+ typename add_reference<
+ typename add_cv<T>::type
+ >::type
+ >
+{
+};
+
+//
+// implementations
+//
+namespace detail
+{
+ template <class T>
+ registration const& registered_pointee_base<T>::converters
+ = registry::lookup(pointer_type_id<T>());
+}
+
+# endif
+}}} // namespace boost::python::converter
+
+#endif // REGISTERED_POINTEE_DWA2002710_HPP
diff --git a/boost/python/converter/registrations.hpp b/boost/python/converter/registrations.hpp
new file mode 100644
index 0000000000..7ef74e8f40
--- /dev/null
+++ b/boost/python/converter/registrations.hpp
@@ -0,0 +1,99 @@
+// 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 REGISTRATIONS_DWA2002223_HPP
+# define REGISTRATIONS_DWA2002223_HPP
+
+# include <boost/python/detail/prefix.hpp>
+
+# include <boost/python/type_id.hpp>
+
+# include <boost/python/converter/convertible_function.hpp>
+# include <boost/python/converter/constructor_function.hpp>
+# include <boost/python/converter/to_python_function_type.hpp>
+
+# include <boost/detail/workaround.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+struct lvalue_from_python_chain
+{
+ convertible_function convert;
+ lvalue_from_python_chain* next;
+};
+
+struct rvalue_from_python_chain
+{
+ convertible_function convertible;
+ constructor_function construct;
+ PyTypeObject const* (*expected_pytype)();
+ rvalue_from_python_chain* next;
+};
+
+struct BOOST_PYTHON_DECL registration
+{
+ public: // member functions
+ explicit registration(type_info target, bool is_shared_ptr = false);
+ ~registration();
+
+ // Convert the appropriately-typed data to Python
+ PyObject* to_python(void const volatile*) const;
+
+ // Return the class object, or raise an appropriate Python
+ // exception if no class has been registered.
+ PyTypeObject* get_class_object() const;
+
+ // Return common denominator of the python class objects,
+ // convertable to target. Inspects the m_class_object and the value_chains.
+ PyTypeObject const* expected_from_python_type() const;
+ PyTypeObject const* to_python_target_type() const;
+
+ public: // data members. So sue me.
+ const python::type_info target_type;
+
+ // The chain of eligible from_python converters when an lvalue is required
+ lvalue_from_python_chain* lvalue_chain;
+
+ // The chain of eligible from_python converters when an rvalue is acceptable
+ rvalue_from_python_chain* rvalue_chain;
+
+ // The class object associated with this type
+ PyTypeObject* m_class_object;
+
+ // The unique to_python converter for the associated C++ type.
+ to_python_function_t m_to_python;
+ PyTypeObject const* (*m_to_python_target_type)();
+
+
+ // True iff this type is a shared_ptr. Needed for special rvalue
+ // from_python handling.
+ const bool is_shared_ptr;
+
+# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+ private:
+ void operator=(registration); // This is not defined, and just keeps MWCW happy.
+# endif
+};
+
+//
+// implementations
+//
+inline registration::registration(type_info target_type, bool is_shared_ptr)
+ : target_type(target_type)
+ , lvalue_chain(0)
+ , rvalue_chain(0)
+ , m_class_object(0)
+ , m_to_python(0)
+ , m_to_python_target_type(0)
+ , is_shared_ptr(is_shared_ptr)
+{}
+
+inline bool operator<(registration const& lhs, registration const& rhs)
+{
+ return lhs.target_type < rhs.target_type;
+}
+
+}}} // namespace boost::python::converter
+
+#endif // REGISTRATIONS_DWA2002223_HPP
diff --git a/boost/python/converter/registry.hpp b/boost/python/converter/registry.hpp
new file mode 100644
index 0000000000..368adcc61d
--- /dev/null
+++ b/boost/python/converter/registry.hpp
@@ -0,0 +1,55 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef REGISTRY_DWA20011127_HPP
+# define REGISTRY_DWA20011127_HPP
+# include <boost/python/type_id.hpp>
+# include <boost/python/converter/to_python_function_type.hpp>
+# include <boost/python/converter/rvalue_from_python_data.hpp>
+# include <boost/python/converter/constructor_function.hpp>
+# include <boost/python/converter/convertible_function.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+struct registration;
+
+// This namespace acts as a sort of singleton
+namespace registry
+{
+ // Get the registration corresponding to the type, creating it if necessary
+ BOOST_PYTHON_DECL registration const& lookup(type_info);
+
+ // Get the registration corresponding to the type, creating it if
+ // necessary. Use this first when the type is a shared_ptr.
+ BOOST_PYTHON_DECL registration const& lookup_shared_ptr(type_info);
+
+ // Return a pointer to the corresponding registration, if one exists
+ BOOST_PYTHON_DECL registration const* query(type_info);
+
+ BOOST_PYTHON_DECL void insert(to_python_function_t, type_info, PyTypeObject const* (*to_python_target_type)() = 0);
+
+ // Insert an lvalue from_python converter
+ BOOST_PYTHON_DECL void insert(convertible_function, type_info, PyTypeObject const* (*expected_pytype)() = 0);
+
+ // Insert an rvalue from_python converter
+ BOOST_PYTHON_DECL void insert(
+ convertible_function
+ , constructor_function
+ , type_info
+ , PyTypeObject const* (*expected_pytype)() = 0
+ );
+
+ // Insert an rvalue from_python converter at the tail of the
+ // chain. Used for implicit conversions
+ BOOST_PYTHON_DECL void push_back(
+ convertible_function
+ , constructor_function
+ , type_info
+ , PyTypeObject const* (*expected_pytype)() = 0
+ );
+}
+
+}}} // namespace boost::python::converter
+
+#endif // REGISTRY_DWA20011127_HPP
diff --git a/boost/python/converter/return_from_python.hpp b/boost/python/converter/return_from_python.hpp
new file mode 100644
index 0000000000..5db9748545
--- /dev/null
+++ b/boost/python/converter/return_from_python.hpp
@@ -0,0 +1,162 @@
+// 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 RETURN_FROM_PYTHON_DWA200265_HPP
+# define RETURN_FROM_PYTHON_DWA200265_HPP
+
+# include <boost/python/converter/from_python.hpp>
+# include <boost/python/converter/rvalue_from_python_data.hpp>
+# include <boost/python/converter/registered.hpp>
+# include <boost/python/converter/registered_pointee.hpp>
+# include <boost/python/converter/object_manager.hpp>
+# include <boost/python/detail/void_ptr.hpp>
+# include <boost/python/detail/void_return.hpp>
+# include <boost/python/errors.hpp>
+# include <boost/python/handle.hpp>
+# include <boost/type_traits/has_trivial_copy.hpp>
+# include <boost/mpl/and.hpp>
+# include <boost/mpl/bool.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+template <class T> struct is_object_manager;
+
+namespace detail
+{
+ template <class T>
+ struct return_pointer_from_python
+ {
+ typedef T result_type;
+ T operator()(PyObject*) const;
+ };
+
+ template <class T>
+ struct return_reference_from_python
+ {
+ typedef T result_type;
+ T operator()(PyObject*) const;
+ };
+
+ template <class T>
+ struct return_rvalue_from_python
+ {
+ typedef T result_type;
+
+ return_rvalue_from_python();
+ result_type operator()(PyObject*);
+ private:
+ rvalue_from_python_data<T> m_data;
+ };
+
+ template <class T>
+ struct return_object_manager_from_python
+ {
+ typedef T result_type;
+ result_type operator()(PyObject*) const;
+ };
+
+ template <class T>
+ struct select_return_from_python
+ {
+ BOOST_STATIC_CONSTANT(
+ bool, obj_mgr = is_object_manager<T>::value);
+
+ BOOST_STATIC_CONSTANT(
+ bool, ptr = is_pointer<T>::value);
+
+ BOOST_STATIC_CONSTANT(
+ bool, ref = is_reference<T>::value);
+
+ typedef typename mpl::if_c<
+ obj_mgr
+ , return_object_manager_from_python<T>
+ , typename mpl::if_c<
+ ptr
+ , return_pointer_from_python<T>
+ , typename mpl::if_c<
+ ref
+ , return_reference_from_python<T>
+ , return_rvalue_from_python<T>
+ >::type
+ >::type
+ >::type type;
+ };
+}
+
+template <class T>
+struct return_from_python
+ : detail::select_return_from_python<T>::type
+{
+};
+
+// Specialization as a convenience for call and call_method
+template <>
+struct return_from_python<void>
+{
+ typedef python::detail::returnable<void>::type result_type;
+
+ result_type operator()(PyObject* x) const
+ {
+ (void_result_from_python)(x);
+# ifdef BOOST_NO_VOID_RETURNS
+ return result_type();
+# endif
+ }
+};
+
+//
+// Implementations
+//
+namespace detail
+{
+ template <class T>
+ inline return_rvalue_from_python<T>::return_rvalue_from_python()
+ : m_data(
+ const_cast<registration*>(&registered<T>::converters)
+ )
+ {
+ }
+
+ template <class T>
+ inline typename return_rvalue_from_python<T>::result_type
+ return_rvalue_from_python<T>::operator()(PyObject* obj)
+ {
+ // Take possession of the source object here. If the result is in
+ // fact going to be a copy of an lvalue embedded in the object,
+ // and we take possession inside rvalue_result_from_python, it
+ // will be destroyed too early.
+ handle<> holder(obj);
+
+ return *(T*)
+ (rvalue_result_from_python)(obj, m_data.stage1);
+ }
+
+ template <class T>
+ inline T return_reference_from_python<T>::operator()(PyObject* obj) const
+ {
+ return python::detail::void_ptr_to_reference(
+ (reference_result_from_python)(obj, registered<T>::converters)
+ , (T(*)())0);
+ }
+
+ template <class T>
+ inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
+ {
+ return T(
+ (pointer_result_from_python)(obj, registered_pointee<T>::converters)
+ );
+ }
+
+ template <class T>
+ inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const
+ {
+ return T(
+ object_manager_traits<T>::adopt(expect_non_null(obj))
+ );
+ }
+}
+
+}}} // namespace boost::python::converter
+
+#endif // RETURN_FROM_PYTHON_DWA200265_HPP
diff --git a/boost/python/converter/rvalue_from_python_data.hpp b/boost/python/converter/rvalue_from_python_data.hpp
new file mode 100644
index 0000000000..471a5255b6
--- /dev/null
+++ b/boost/python/converter/rvalue_from_python_data.hpp
@@ -0,0 +1,140 @@
+// 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 FROM_PYTHON_AUX_DATA_DWA2002128_HPP
+# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP
+
+# include <boost/python/converter/constructor_function.hpp>
+# include <boost/python/detail/referent_storage.hpp>
+# include <boost/python/detail/destroy.hpp>
+# include <boost/static_assert.hpp>
+# include <boost/type_traits/add_reference.hpp>
+# include <boost/type_traits/add_cv.hpp>
+# include <cstddef>
+
+// Data management for potential rvalue conversions from Python to C++
+// types. When a client requests a conversion to T* or T&, we
+// generally require that an object of type T exists in the source
+// Python object, and the code here does not apply**. This implements
+// conversions which may create new temporaries of type T. The classic
+// example is a conversion which converts a Python tuple to a
+// std::vector. Since no std::vector lvalue exists in the Python
+// object -- it must be created "on-the-fly" by the converter, and
+// which must manage the lifetime of the created object.
+//
+// Note that the client is not precluded from using a registered
+// lvalue conversion to T in this case. In other words, we will
+// happily accept a Python object which /does/ contain a std::vector
+// lvalue, provided an appropriate converter is registered. So, while
+// this is an rvalue conversion from the client's point-of-view, the
+// converter registry may serve up lvalue or rvalue conversions for
+// the target type.
+//
+// ** C++ argument from_python conversions to T const& are an
+// exception to the rule for references: since in C++, const
+// references can bind to temporary rvalues, we allow rvalue
+// converters to be chosen when the target type is T const& for some
+// T.
+namespace boost { namespace python { namespace converter {
+
+// Conversions begin by filling in and returning a copy of this
+// structure. The process looks up a converter in the rvalue converter
+// registry for the target type. It calls the convertible() function
+// of each registered converter, passing the source PyObject* as an
+// argument, until a non-null result is returned. This result goes in
+// the convertible field, and the converter's construct() function is
+// stored in the construct field.
+//
+// If no appropriate converter is found, conversion fails and the
+// convertible field is null. When used in argument conversion for
+// wrapped C++ functions, it causes overload resolution to reject the
+// current function but not to fail completely. If an exception is
+// thrown, overload resolution stops and the exception propagates back
+// through the caller.
+//
+// If an lvalue converter is matched, its convertible() function is
+// expected to return a pointer to the stored T object; its
+// construct() function will be NULL. The convertible() function of
+// rvalue converters may return any non-singular pointer; the actual
+// target object will only be available once the converter's
+// construct() function is called.
+struct rvalue_from_python_stage1_data
+{
+ void* convertible;
+ constructor_function construct;
+};
+
+// Augments rvalue_from_python_stage1_data by adding storage for
+// constructing an object of remove_reference<T>::type. The
+// construct() function of rvalue converters (stored in m_construct
+// above) will cast the rvalue_from_python_stage1_data to an
+// appropriate instantiation of this template in order to access that
+// storage.
+template <class T>
+struct rvalue_from_python_storage
+{
+ rvalue_from_python_stage1_data stage1;
+
+ // Storage for the result, in case an rvalue must be constructed
+ typename python::detail::referent_storage<
+ typename add_reference<T>::type
+ >::type storage;
+};
+
+// Augments rvalue_from_python_storage<T> with a destructor. If
+// stage1.convertible == storage.bytes, it indicates that an object of
+// remove_reference<T>::type has been constructed in storage and
+// should will be destroyed in ~rvalue_from_python_data(). It is
+// crucial that successful rvalue conversions establish this equality
+// and that unsuccessful ones do not.
+template <class T>
+struct rvalue_from_python_data : rvalue_from_python_storage<T>
+{
+# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \
+ && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \
+ && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \
+ && !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */
+ // This must always be a POD struct with m_data its first member.
+ BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0);
+# endif
+
+ // The usual constructor
+ rvalue_from_python_data(rvalue_from_python_stage1_data const&);
+
+ // This constructor just sets m_convertible -- used by
+ // implicitly_convertible<> to perform the final step of the
+ // conversion, where the construct() function is already known.
+ rvalue_from_python_data(void* convertible);
+
+ // Destroys any object constructed in the storage.
+ ~rvalue_from_python_data();
+ private:
+ typedef typename add_reference<typename add_cv<T>::type>::type ref_type;
+};
+
+//
+// Implementataions
+//
+template <class T>
+inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& _stage1)
+{
+ this->stage1 = _stage1;
+}
+
+template <class T>
+inline rvalue_from_python_data<T>::rvalue_from_python_data(void* convertible)
+{
+ this->stage1.convertible = convertible;
+}
+
+template <class T>
+inline rvalue_from_python_data<T>::~rvalue_from_python_data()
+{
+ if (this->stage1.convertible == this->storage.bytes)
+ python::detail::destroy_referent<ref_type>(this->storage.bytes);
+}
+
+}}} // namespace boost::python::converter
+
+#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP
diff --git a/boost/python/converter/shared_ptr_deleter.hpp b/boost/python/converter/shared_ptr_deleter.hpp
new file mode 100644
index 0000000000..926508d00e
--- /dev/null
+++ b/boost/python/converter/shared_ptr_deleter.hpp
@@ -0,0 +1,22 @@
+// 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 SHARED_PTR_DELETER_DWA2002121_HPP
+# define SHARED_PTR_DELETER_DWA2002121_HPP
+
+namespace boost { namespace python { namespace converter {
+
+struct BOOST_PYTHON_DECL shared_ptr_deleter
+{
+ shared_ptr_deleter(handle<> owner);
+ ~shared_ptr_deleter();
+
+ void operator()(void const*);
+
+ handle<> owner;
+};
+
+}}} // namespace boost::python::converter
+
+#endif // SHARED_PTR_DELETER_DWA2002121_HPP
diff --git a/boost/python/converter/shared_ptr_from_python.hpp b/boost/python/converter/shared_ptr_from_python.hpp
new file mode 100644
index 0000000000..c09107765c
--- /dev/null
+++ b/boost/python/converter/shared_ptr_from_python.hpp
@@ -0,0 +1,63 @@
+// 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 SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
+# define SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
+
+# include <boost/python/handle.hpp>
+# include <boost/python/converter/shared_ptr_deleter.hpp>
+# include <boost/python/converter/from_python.hpp>
+# include <boost/python/converter/rvalue_from_python_data.hpp>
+# include <boost/python/converter/registered.hpp>
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+# include <boost/python/converter/pytype_function.hpp>
+#endif
+# include <boost/shared_ptr.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+template <class T>
+struct shared_ptr_from_python
+{
+ shared_ptr_from_python()
+ {
+ converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &converter::expected_from_python_type_direct<T>::get_pytype
+#endif
+ );
+ }
+
+ private:
+ static void* convertible(PyObject* p)
+ {
+ if (p == Py_None)
+ return p;
+
+ return converter::get_lvalue_from_python(p, registered<T>::converters);
+ }
+
+ static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
+ {
+ void* const storage = ((converter::rvalue_from_python_storage<shared_ptr<T> >*)data)->storage.bytes;
+ // Deal with the "None" case.
+ if (data->convertible == source)
+ new (storage) shared_ptr<T>();
+ else
+ {
+ boost::shared_ptr<void> hold_convertible_ref_count(
+ (void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
+ // use aliasing constructor
+ new (storage) shared_ptr<T>(
+ hold_convertible_ref_count,
+ static_cast<T*>(data->convertible));
+ }
+
+ data->convertible = storage;
+ }
+};
+
+}}} // namespace boost::python::converter
+
+#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
diff --git a/boost/python/converter/shared_ptr_to_python.hpp b/boost/python/converter/shared_ptr_to_python.hpp
new file mode 100644
index 0000000000..fe867ace13
--- /dev/null
+++ b/boost/python/converter/shared_ptr_to_python.hpp
@@ -0,0 +1,28 @@
+// Copyright David Abrahams 2003.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef SHARED_PTR_TO_PYTHON_DWA2003224_HPP
+# define SHARED_PTR_TO_PYTHON_DWA2003224_HPP
+
+# include <boost/python/refcount.hpp>
+# include <boost/python/converter/shared_ptr_deleter.hpp>
+# include <boost/shared_ptr.hpp>
+# include <boost/get_pointer.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+template <class T>
+PyObject* shared_ptr_to_python(shared_ptr<T> const& x)
+{
+ if (!x)
+ return python::detail::none();
+ else if (shared_ptr_deleter* d = boost::get_deleter<shared_ptr_deleter>(x))
+ return incref( get_pointer( d->owner ) );
+ else
+ return converter::registered<shared_ptr<T> const&>::converters.to_python(&x);
+}
+
+}}} // namespace boost::python::converter
+
+#endif // SHARED_PTR_TO_PYTHON_DWA2003224_HPP
diff --git a/boost/python/converter/to_python_function_type.hpp b/boost/python/converter/to_python_function_type.hpp
new file mode 100644
index 0000000000..cccd014d68
--- /dev/null
+++ b/boost/python/converter/to_python_function_type.hpp
@@ -0,0 +1,19 @@
+// 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_FUNCTION_TYPE_DWA200236_HPP
+# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
+# include <boost/python/detail/prefix.hpp>
+# include <boost/static_assert.hpp>
+
+namespace boost { namespace python { namespace converter {
+
+// The type of stored function pointers which actually do conversion
+// by-value. The void* points to the object to be converted, and
+// type-safety is preserved through runtime registration.
+typedef PyObject* (*to_python_function_t)(void const*);
+
+}}} // namespace boost::python::converter
+
+#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP