2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-19 04:22:16 +00:00

Full merge from trunk at revision 41356 of entire boost-root tree.

[SVN r41369]
This commit is contained in:
Beman Dawes
2007-11-25 18:07:19 +00:00
parent bf33b54638
commit f5df393360
43 changed files with 918 additions and 144 deletions

View File

@@ -39,6 +39,9 @@ struct as_to_python_function
// 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

View File

@@ -47,7 +47,7 @@ namespace detail
}
// Use expr to create the PyObject corresponding to x
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr, pytype)\
template <> struct to_python_value<T&> \
: detail::builtin_to_python \
{ \
@@ -55,6 +55,10 @@ namespace detail
{ \
return (expr); \
} \
inline PyTypeObject const* get_pytype() const \
{ \
return (pytype); \
} \
}; \
template <> struct to_python_value<T const&> \
: detail::builtin_to_python \
@@ -63,6 +67,10 @@ namespace detail
{ \
return (expr); \
} \
inline PyTypeObject const* get_pytype() const \
{ \
return (pytype); \
} \
};
# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
@@ -77,25 +85,25 @@ namespace detail
}
// Specialize argument and return value converters for T using expr
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,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
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x)) \
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_FromLong(x), &PyInt_Type)
// Bool is not signed.
#if PY_VERSION_HEX >= 0x02030000
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyBool_FromLong(x), &PyBool_Type)
#else
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
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)
@@ -108,25 +116,25 @@ BOOST_PYTHON_TO_INT(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_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
# endif
# undef BOOST_TO_PYTHON_INT
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())))
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)
#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())))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
# endif
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
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

View File

@@ -18,6 +18,9 @@ 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
};
//

View File

@@ -14,7 +14,7 @@ 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
struct pyobject_type
{
static bool check(PyObject* x)
{
@@ -27,6 +27,9 @@ struct pyobject_type
(checked_downcast_impl)(x, pytype)
);
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const* get_pytype() { return pytype; }
#endif
};
}}} // namespace boost::python::converter

View File

@@ -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

View File

@@ -27,6 +27,7 @@ struct rvalue_from_python_chain
{
convertible_function convertible;
constructor_function construct;
PyTypeObject const* (*expected_pytype)();
rvalue_from_python_chain* next;
};
@@ -34,6 +35,7 @@ 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;
@@ -42,6 +44,11 @@ struct BOOST_PYTHON_DECL registration
// 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;
@@ -56,6 +63,8 @@ struct BOOST_PYTHON_DECL registration
// 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.
@@ -76,6 +85,7 @@ inline registration::registration(type_info target_type, bool is_shared_ptr)
, rvalue_chain(0)
, m_class_object(0)
, m_to_python(0)
, m_to_python_target_type(0)
, is_shared_ptr(is_shared_ptr)
{}

View File

@@ -27,16 +27,17 @@ namespace registry
// 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);
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(void* (*convert)(PyObject*), type_info);
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), 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
@@ -45,6 +46,7 @@ namespace registry
convertible_function
, constructor_function
, type_info
, PyTypeObject const* (*expected_pytype)() = 0
);
}

View File

@@ -10,6 +10,9 @@
# 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 {
@@ -19,7 +22,11 @@ struct shared_ptr_from_python
{
shared_ptr_from_python()
{
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >());
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:

View File

@@ -13,6 +13,7 @@
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/mpl/or.hpp>
# include <boost/mpl/front.hpp>
namespace boost { namespace python {
@@ -49,6 +50,12 @@ struct default_call_policies
typedef default_result_converter result_converter;
typedef PyObject* argument_package;
template <class Sig>
struct extract_return_type : mpl::front<Sig>
{
};
};
struct default_result_converter

View File

@@ -11,12 +11,15 @@
# include <boost/python/type_id.hpp>
# include <boost/python/handle.hpp>
# include <boost/detail/indirect_traits.hpp>
# include <boost/python/detail/invoke.hpp>
# include <boost/python/detail/signature.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/python/converter/context_result_converter.hpp>
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/cat.hpp>
@@ -89,6 +92,27 @@ inline ResultConverter create_result_converter(
{
return ResultConverter();
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
template <class ResultConverter>
struct converter_target_type
{
static PyTypeObject const *get_pytype()
{
return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
}
};
template < >
struct converter_target_type <void_result_to_python >
{
static PyTypeObject const *get_pytype()
{
return 0;
}
};
#endif
template <unsigned> struct caller_arity;
@@ -203,11 +227,26 @@ struct caller_arity<N>
static unsigned min_arity() { return N; }
static signature_element const* signature()
static py_func_sig_info signature()
{
return detail::signature<Sig>::elements();
const signature_element * sig = detail::signature<Sig>::elements();
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
typedef typename select_result_converter<Policies, rtype>::type result_converter;
static const signature_element ret = {
(boost::is_void<rtype>::value ? "void" : type_id<rtype>().name())
, &detail::converter_target_type<result_converter>::get_pytype
, boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
};
py_func_sig_info res = {sig, &ret };
#else
py_func_sig_info res = {sig, sig };
#endif
return res;
}
private:
compressed_pair<F,Policies> m_data;
};

View File

@@ -134,4 +134,8 @@
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
#define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition
#endif
#endif // CONFIG_DWA052200_H_

View File

@@ -155,7 +155,7 @@ namespace detail
, T3 const&
, T4 const&
, default_call_policies
, keywords<0>
, detail::keywords<0>
, char const*
, void(not_specified::*)() // A function pointer type which is never an
// appropriate default implementation

View File

@@ -168,7 +168,7 @@ namespace detail
char const* doc)
{
// define the NTH stub function of stubs
define_stub_function<N>::define(name, stubs, kw, policies, name_space, 0);
define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
if (kw.second > kw.first)
--kw.second;

View File

@@ -248,7 +248,7 @@ namespace detail
BOOST_PYTHON_GEN_MEM_FUNCTION( \
fname, void_return_type, n_args, n_dflts, ;) \
\
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
};
# else // !defined(BOOST_NO_VOID_RETURNS)
@@ -273,7 +273,7 @@ namespace detail
fname, non_void_return_type, n_args, n_dflts, return) \
\
typedef non_void_return_type void_return_type; \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts) \
};
# endif // !defined(BOOST_NO_VOID_RETURNS)

View File

@@ -57,6 +57,9 @@ object make_keyword_range_constructor(
, Holder* = 0
, ArgList* = 0, Arity* = 0)
{
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_();
#endif
return detail::make_keyword_range_function(
objects::make_holder<Arity::value>
::template apply<Holder,ArgList>::execute

View File

@@ -47,7 +47,8 @@ enum operator_id
op_ixor,
op_ior,
op_complex,
op_nonzero
op_nonzero,
op_repr
};
}}} // namespace boost::python::detail

View File

@@ -0,0 +1,37 @@
// Copyright Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
#define BOOST_PYTHON_OBJECT_PYTHON_TYPE_H
#include <boost/python/converter/registered.hpp>
namespace boost {namespace python {namespace detail{
template <class T> struct python_class : PyObject
{
typedef python_class<T> this_type;
typedef T type;
static void *converter (PyObject *p){
return p;
}
static void register_()
{
static bool first_time = true;
if ( !first_time ) return;
first_time = false;
converter::registry::insert(&converter, boost::python::type_id<this_type>(), &converter::registered_pytype_direct<T>::get_pytype);
}
};
}}} //namespace boost :: python :: detail
#endif //BOOST_PYTHON_OBJECT_PYTHON_TYPE_H

View File

@@ -12,6 +12,7 @@
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/python/converter/pytype_function.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/iteration/local.hpp>
@@ -24,9 +25,16 @@ namespace boost { namespace python { namespace detail {
struct signature_element
{
char const* basename;
converter::pytype_function pytype_f;
bool lvalue;
};
struct py_func_sig_info
{
signature_element const *signature;
signature_element const *ret;
};
template <unsigned> struct signature_arity;
# define BOOST_PP_ITERATION_PARAMS_1 \
@@ -68,15 +76,25 @@ struct signature_arity<N>
{
static signature_element const result[N+2] = {
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# define BOOST_PP_LOCAL_MACRO(i) \
{ \
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
},
{ \
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
, &converter::expected_pytype_for_arg<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::get_pytype \
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
},
#else
# define BOOST_PP_LOCAL_MACRO(i) \
{ \
type_id<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>().name() \
, 0 \
, indirect_traits::is_reference_to_non_const<BOOST_DEDUCED_TYPENAME mpl::at_c<Sig,i>::type>::value \
},
#endif
# define BOOST_PP_LOCAL_LIMITS (0, N)
# include BOOST_PP_LOCAL_ITERATE()
{0,0}
{0,0,0}
};
return result;
}

View File

@@ -0,0 +1,170 @@
// 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 UNWIND_TYPE_DWA200222_HPP
# define UNWIND_TYPE_DWA200222_HPP
# include <boost/python/detail/cv_category.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/type_traits/object_traits.hpp>
namespace boost { namespace python { namespace detail {
#ifndef _MSC_VER //if forward declared, msvc6.5 does not recognize them as inline
// forward declaration, required (at least) by Tru64 cxx V6.5-042
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(U const& p, Generator* = 0);
// forward declaration, required (at least) by Tru64 cxx V6.5-042
template <class Generator, class U>
inline typename Generator::result_type
unwind_type(boost::type<U>*p = 0, Generator* = 0);
#endif
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
{
return Generator::execute(p);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U const* p, const_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
{
return unwind_type(const_cast<U*>(p), (Generator*)0);
}
template <class Generator, class U>
inline typename Generator::result_type
unwind_ptr_type(U* p, Generator* = 0)
{
typedef typename cv_category<U>::type tag;
return unwind_type_cv<Generator>(p, tag());
}
template <bool is_ptr>
struct unwind_helper
{
template <class Generator, class U>
static typename Generator::result_type
execute(U p, Generator* = 0)
{
return unwind_ptr_type(p, (Generator*)0);
}
};
template <>
struct unwind_helper<false>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U& p, Generator* = 0)
{
return unwind_ptr_type(&p, (Generator*)0);
}
};
template <class Generator, class U>
inline typename Generator::result_type
#ifndef _MSC_VER
unwind_type(U const& p, Generator*)
#else
unwind_type(U const& p, Generator* = 0)
#endif
{
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
}
enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
template <int indirection> struct unwind_helper2;
template <>
struct unwind_helper2<direct_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<pointer_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U*(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<reference_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U&(*)(), Generator* = 0)
{
return unwind_ptr_type((U*)0, (Generator*)0);
}
};
template <>
struct unwind_helper2<reference_to_pointer_>
{
template <class Generator, class U>
static typename Generator::result_type
execute(U&(*)(), Generator* = 0)
{
return unwind_ptr_type(U(0), (Generator*)0);
}
};
// Call this one with both template parameters explicitly specified
// and no function arguments:
//
// return unwind_type<my_generator,T>();
//
// Doesn't work if T is an array type; we could handle that case, but
// why bother?
template <class Generator, class U>
inline typename Generator::result_type
#ifndef _MSC_VER
unwind_type(boost::type<U>*p, Generator*)
#else
unwind_type(boost::type<U>*p =0, Generator* =0)
#endif
{
BOOST_STATIC_CONSTANT(int, indirection
= (boost::is_pointer<U>::value ? pointer_ : 0)
+ (indirect_traits::is_reference_to_pointer<U>::value
? reference_to_pointer_
: boost::is_reference<U>::value
? reference_
: 0));
return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
}
}}} // namespace boost::python::detail
#endif // UNWIND_TYPE_DWA200222_HPP

View File

@@ -17,23 +17,38 @@ class BOOST_PYTHON_DECL docstring_options : boost::noncopyable
docstring_options(bool show_all=true)
{
previous_show_user_defined_ = show_user_defined_;
previous_show_signatures_ = show_signatures_;
previous_show_py_signatures_ = show_py_signatures_;
previous_show_cpp_signatures_ = show_cpp_signatures_;
show_user_defined_ = show_all;
show_signatures_ = show_all;
show_cpp_signatures_ = show_all;
show_py_signatures_ = show_all;
}
docstring_options(bool show_user_defined, bool show_signatures)
{
previous_show_user_defined_ = show_user_defined_;
previous_show_signatures_ = show_signatures_;
previous_show_cpp_signatures_ = show_cpp_signatures_;
previous_show_py_signatures_ = show_py_signatures_;
show_user_defined_ = show_user_defined;
show_signatures_ = show_signatures;
show_cpp_signatures_ = show_signatures;
show_py_signatures_ = show_signatures;
}
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures)
{
previous_show_user_defined_ = show_user_defined_;
previous_show_cpp_signatures_ = show_cpp_signatures_;
previous_show_py_signatures_ = show_py_signatures_;
show_user_defined_ = show_user_defined;
show_cpp_signatures_ = show_cpp_signatures;
show_py_signatures_ = show_py_signatures;
}
~docstring_options()
{
show_user_defined_ = previous_show_user_defined_;
show_signatures_ = previous_show_signatures_;
show_cpp_signatures_ = previous_show_cpp_signatures_;
show_py_signatures_ = previous_show_py_signatures_;
}
void
@@ -43,32 +58,68 @@ class BOOST_PYTHON_DECL docstring_options : boost::noncopyable
enable_user_defined() { show_user_defined_ = true; }
void
disable_signatures() { show_signatures_ = false; }
disable_py_signatures()
{
show_py_signatures_ = false;
}
void
enable_signatures() { show_signatures_ = true; }
enable_py_signatures()
{
show_py_signatures_ = true;
}
void
disable_cpp_signatures()
{
show_cpp_signatures_ = false;
}
void
enable_cpp_signatures()
{
show_cpp_signatures_ = true;
}
void
disable_signatures()
{
show_cpp_signatures_ = false;
show_py_signatures_ = false;
}
void
enable_signatures()
{
show_cpp_signatures_ = true;
show_py_signatures_ = true;
}
void
disable_all()
{
show_user_defined_ = false;
show_signatures_ = false;
show_cpp_signatures_ = false;
show_py_signatures_ = false;
}
void
enable_all()
{
show_user_defined_ = true;
show_signatures_ = true;
show_cpp_signatures_ = true;
show_py_signatures_ = true;
}
friend struct objects::function;
private:
static volatile bool show_user_defined_;
static volatile bool show_signatures_;
static volatile bool show_cpp_signatures_;
static volatile bool show_py_signatures_;
bool previous_show_user_defined_;
bool previous_show_signatures_;
bool previous_show_cpp_signatures_;
bool previous_show_py_signatures_;
};
}} // namespace boost::python

View File

@@ -19,7 +19,7 @@ struct enum_ : public objects::enum_base
typedef objects::enum_base base;
// Declare a new enumeration type in the current scope()
enum_(char const* name);
enum_(char const* name, char const* doc = 0);
// Add a new enumeration value with the given name and value.
inline enum_<T>& value(char const* name, T);
@@ -34,13 +34,15 @@ struct enum_ : public objects::enum_base
};
template <class T>
inline enum_<T>::enum_(char const* name)
inline enum_<T>::enum_(char const* name, char const* doc )
: base(
name
, &enum_<T>::to_python
, &enum_<T>::convertible_from_python
, &enum_<T>::construct
, type_id<T>())
, type_id<T>()
, doc
)
{
}

View File

@@ -9,6 +9,9 @@
# include <boost/type.hpp>
# include <boost/python/converter/implicit.hpp>
# include <boost/python/converter/registry.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 {
@@ -21,7 +24,11 @@ void implicitly_convertible(boost::type<Source>* = 0, boost::type<Target>* = 0)
converter::registry::push_back(
&functions::convertible
, &functions::construct
, type_id<Target>());
, type_id<Target>()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &converter::expected_from_python_type_direct<Source>::get_pytype
#endif
);
}
}} // namespace boost::python

View File

@@ -245,7 +245,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
: base(doc_, kw.range())
{
typedef typename detail::error::more_keywords_than_init_arguments<
N, n_arguments::value
N, n_arguments::value + 1
>::too_many_keywords assertion;
}
@@ -254,7 +254,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
: base(doc_, kw.range())
{
typedef typename detail::error::more_keywords_than_init_arguments<
N, n_arguments::value
N, n_arguments::value + 1
>::too_many_keywords assertion;
}
@@ -363,7 +363,7 @@ namespace detail
, char const* doc
, detail::keyword_range keywords)
{
detail::def_init_aux(cl, args, NArgs(), policies, 0, keywords);
detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
if (keywords.second > keywords.first)
--keywords.second;

View File

@@ -6,6 +6,9 @@
# define LVALUE_FROM_PYTYPE_DWA2002130_HPP
# include <boost/python/detail/prefix.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/python/type_id.hpp>
# include <boost/python/converter/registry.hpp>
@@ -81,12 +84,17 @@ struct extract_identity
// Extractor's static execute function from Python objects whose type
// object is python_type.
template <class Extractor, PyTypeObject const* python_type>
struct lvalue_from_pytype
struct lvalue_from_pytype
{
lvalue_from_pytype()
{
converter::registry::insert(
&extract, detail::extractor_type_id(&Extractor::execute));
converter::registry::insert
( &extract
, detail::extractor_type_id(&Extractor::execute)
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &get_pytype
#endif
);
}
private:
static void* extract(PyObject* op)
@@ -98,6 +106,9 @@ struct lvalue_from_pytype
: 0
;
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const*get_pytype() { return python_type; }
#endif
};
}} // namespace boost::python

View File

@@ -23,6 +23,7 @@
# include <boost/mpl/int.hpp>
# include <boost/mpl/push_front.hpp>
# include <boost/mpl/pop_front.hpp>
# include <boost/mpl/assert.hpp>
namespace boost { namespace python {
@@ -103,13 +104,23 @@ namespace detail
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
BOOST_STATIC_ASSERT((
is_same<
#if defined _MSC_VER && _MSC_VER < 1300
typedef is_same<
typename BasePolicy_::result_converter
, default_result_converter
>::value
));
> same_result_converter;
//see above for explanation
BOOST_STATIC_ASSERT(same_result_converter::value) ;
#else
BOOST_MPL_ASSERT_MSG(
(is_same<
typename BasePolicy_::result_converter
, default_result_converter
>::value)
, MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
, (typename BasePolicy_::result_converter)
);
#endif
typedef constructor_result_converter result_converter;
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
};

View File

@@ -92,6 +92,7 @@ namespace aux
{
static bool check(PyObject* obj);
static detail::new_non_null_reference adopt(PyObject* obj);
static PyTypeObject const* get_pytype() ;
};
} // namespace aux

View File

@@ -238,6 +238,14 @@ struct class_metadata
//
inline static void maybe_register_pointer_to_python(void*,void*,void*) {}
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
{
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T &> >());
}
#endif
template <class T2>
inline static void maybe_register_pointer_to_python(T2*, mpl::false_*, mpl::false_*)
{
@@ -247,6 +255,10 @@ struct class_metadata
, make_ptr_instance<T2, pointer_holder<held_type, T2> >
>()
);
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
}
//
// Support for registering to-python converters
@@ -258,6 +270,10 @@ struct class_metadata
inline static void maybe_register_class_to_python(T2*, mpl::false_)
{
python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
}
//

View File

@@ -6,6 +6,9 @@
# define CLASS_WRAPPER_DWA20011221_HPP
# include <boost/python/to_python_converter.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/ref.hpp>
namespace boost { namespace python { namespace objects {
@@ -19,22 +22,28 @@ namespace boost { namespace python { namespace objects {
template <class Src, class MakeInstance>
struct class_cref_wrapper
: to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> >
: to_python_converter<Src,class_cref_wrapper<Src,MakeInstance> ,true>
{
static PyObject* convert(Src const& x)
{
return MakeInstance::execute(boost::ref(x));
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype() { return converter::registered_pytype_direct<Src>::get_pytype(); }
#endif
};
template <class Src, class MakeInstance>
struct class_value_wrapper
: to_python_converter<Src,class_value_wrapper<Src,MakeInstance> >
: to_python_converter<Src,class_value_wrapper<Src,MakeInstance> ,true>
{
static PyObject* convert(Src x)
{
return MakeInstance::execute(x);
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype() { return MakeInstance::get_pytype(); }
#endif
};
}}} // namespace boost::python::objects

View File

@@ -21,7 +21,9 @@ struct BOOST_PYTHON_DECL enum_base : python::api::object
, converter::to_python_function_t
, converter::convertible_function
, converter::constructor_function
, type_info);
, type_info
, const char *doc = 0
);
void add_value(char const* name, long value);
void export_values();

View File

@@ -14,6 +14,7 @@
namespace boost { namespace python { namespace objects {
struct BOOST_PYTHON_DECL function : PyObject
{
function(
@@ -53,6 +54,7 @@ struct BOOST_PYTHON_DECL function : PyObject
object m_doc;
object m_arg_names;
unsigned m_nkeyword_values;
friend class function_doc_signature_generator;
};
//

View File

@@ -0,0 +1,36 @@
// Copyright Nikolay Mladenov 2007.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef FUNCTION_SIGNATURE_20070531_HPP
# define FUNCTION_SIGNATURE_20070531_HPP
#include <boost/python/object/function.hpp>
#include <boost/python/converter/registrations.hpp>
#include <boost/python/str.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/detail/signature.hpp>
#include <vector>
namespace boost { namespace python { namespace objects {
class function_doc_signature_generator{
static const char * py_type_str(const python::detail::signature_element &s);
static bool arity_cmp( function const *f1, function const *f2 );
static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
static std::vector<function const*> flatten(function const *f);
static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
static str raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
static str pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
public:
static list function_doc_signatures( function const * f);
};
}}}//end of namespace boost::python::objects
#endif //FUNCTION_SIGNATURE_20070531_HPP

View File

@@ -11,6 +11,10 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/python/object/instance.hpp>
# include <boost/python/converter/registry.hpp>
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
# include <boost/python/detail/python_type.hpp>
#endif
# include <boost/python/object/forward.hpp>
# include <boost/python/detail/preprocessor.hpp>
@@ -74,7 +78,11 @@ struct make_holder<N>
# endif
static void execute(
PyObject* p
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
#else
PyObject *p
#endif
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a))
{
typedef instance<Holder> instance_t;

View File

@@ -29,7 +29,12 @@ struct make_ptr_instance
{
return get_class_object_impl(get_pointer(x));
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static inline PyTypeObject const* get_pytype()
{
return converter::registered<T>::converters.get_class_object();
}
#endif
private:
template <class U>
static inline PyTypeObject* get_class_object_impl(U const volatile* p)

View File

@@ -23,7 +23,7 @@ struct BOOST_PYTHON_DECL py_function_impl_base
virtual PyObject* operator()(PyObject*, PyObject*) = 0;
virtual unsigned min_arity() const = 0;
virtual unsigned max_arity() const;
virtual python::detail::signature_element const* signature() const = 0;
virtual python::detail::py_func_sig_info signature() const = 0;
};
template <class Caller>
@@ -43,7 +43,7 @@ struct caller_py_function_impl : py_function_impl_base
return m_caller.min_arity();
}
virtual python::detail::signature_element const* signature() const
virtual python::detail::py_func_sig_info signature() const
{
return m_caller.signature();
}
@@ -69,9 +69,11 @@ struct signature_py_function_impl : py_function_impl_base
return mpl::size<Sig>::value - 1;
}
virtual python::detail::signature_element const* signature() const
virtual python::detail::py_func_sig_info signature() const
{
return python::detail::signature<Sig>::elements();
python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
python::detail::py_func_sig_info res = {sig, sig};
return res;
}
private:
@@ -102,9 +104,11 @@ struct full_py_function_impl : py_function_impl_base
return m_max_arity;
}
virtual python::detail::signature_element const* signature() const
virtual python::detail::py_func_sig_info signature() const
{
return python::detail::signature<Sig>::elements();
python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
python::detail::py_func_sig_info res = {sig, sig};
return res;
}
private:
@@ -151,7 +155,12 @@ struct py_function
python::detail::signature_element const* signature() const
{
return m_impl->signature();
return m_impl->signature().signature;
}
python::detail::signature_element const& get_return_type() const
{
return *m_impl->signature().ret;
}
private:

View File

@@ -470,6 +470,9 @@ namespace converter
{
return python::detail::new_non_null_reference(x);
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype() {return 0;}
#endif
};
}

View File

@@ -12,46 +12,55 @@
namespace boost { namespace python { namespace api {
# if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
// attempt to use SFINAE to prevent functions accepting T const& from
// coming up as ambiguous with the one taking a char const* when a
// string literal is passed
# define BOOST_PYTHON_NO_ARRAY_ARG(T) , T (*)() = 0
# else
# define BOOST_PYTHON_NO_ARRAY_ARG(T)
# endif
template <class Target, class Key>
object getattr(Target const& target, Key const& key)
object getattr(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
return getattr(object(target), object(key));
}
template <class Target, class Key, class Default>
object getattr(Target const& target, Key const& key, Default const& default_)
object getattr(Target const& target, Key const& key, Default const& default_ BOOST_PYTHON_NO_ARRAY_ARG(key))
{
return getattr(object(target), object(key), object(default_));
}
template <class Key, class Value>
void setattr(object const& target, Key const& key, Value const& value)
void setattr(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
{
setattr(target, object(key), object(value));
}
template <class Key>
void delattr(object const& target, Key const& key)
void delattr(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
delattr(target, object(key));
}
template <class Target, class Key>
object getitem(Target const& target, Key const& key)
object getitem(Target const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
return getitem(object(target), object(key));
}
template <class Key, class Value>
void setitem(object const& target, Key const& key, Value const& value)
void setitem(object const& target, Key const& key, Value const& value BOOST_PYTHON_NO_ARRAY_ARG(key))
{
setitem(target, object(key), object(value));
}
template <class Key>
void delitem(object const& target, Key const& key)
void delitem(object const& target, Key const& key BOOST_PYTHON_NO_ARRAY_ARG(key))
{
delitem(target, object(key));
}

View File

@@ -1,4 +1,4 @@
// Copyright Gottfried Ganßauge 2003..2006
// Copyright Gottfried Ganßauge 2003..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)
@@ -93,8 +93,13 @@ private:
if ((existing == 0) || (existing->m_to_python == 0))
{
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
converter::registry::insert(&extract, type_id<Pointee>(), &get_pytype);
converter::registry::insert(&wrap, type_id<Pointee*>(), &get_pytype);
#else
converter::registry::insert(&extract, type_id<Pointee>());
converter::registry::insert(&wrap, type_id<Pointee*>());
#endif
}
}
@@ -105,6 +110,9 @@ private:
};
static PyTypeObject type_object;
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static PyTypeObject const *get_pytype(){return &type_object; }
#endif
};
template <class Pointee>

View File

@@ -347,6 +347,7 @@ BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
BOOST_PYTHON_UNARY_OPERATOR(repr, lexical_cast<std::string>, repr)
# undef BOOST_PYTHON_UNARY_OPERATOR
}} // namespace boost::python
@@ -358,6 +359,7 @@ using boost::python::self_ns::long_;
using boost::python::self_ns::float_;
using boost::python::self_ns::complex_;
using boost::python::self_ns::str;
using boost::python::self_ns::repr;
using boost::python::self_ns::pow;
# endif

View File

@@ -8,10 +8,15 @@
# include <boost/python/detail/none.hpp>
# include <boost/python/detail/value_arg.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/at.hpp>
# include <boost/static_assert.hpp>
# include <boost/python/refcount.hpp>
@@ -44,6 +49,9 @@ namespace detail
{
return none();
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
PyTypeObject const *get_pytype() const { return converter::expected_pytype_for_arg<T>::get_pytype() ; }
#endif
};
};
};
@@ -82,6 +90,12 @@ struct return_arg : Base
Py_DECREF(result);
return incref( detail::get(mpl::int_<arg_pos-1>(),args) );
}
template <class Sig>
struct extract_return_type : mpl::at_c<Sig, arg_pos>
{
};
};
template <

View File

@@ -17,73 +17,73 @@
# 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&
// static data_type&
// get_item(Container& container, index_type i);
//
// static object
// static object
// get_slice(Container& container, index_type from, index_type to);
//
// static void
// static void
// set_item(Container& container, index_type i, data_type const& v);
//
// static void
// static void
// set_slice(
// Container& container, index_type from,
// Container& container, index_type from,
// index_type to, data_type const& v
// );
//
// template <class Iter>
// static void
// set_slice(Container& container, index_type from,
// static void
// set_slice(Container& container, index_type from,
// index_type to, Iter first, Iter last
// );
//
// static void
// static void
// delete_item(Container& container, index_type i);
//
// static void
//
// 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,
// 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.
// 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
// 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,
// 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]
@@ -104,7 +104,7 @@ namespace boost { namespace python {
, class Index = typename Container::size_type
, class Key = typename Container::value_type
>
class indexing_suite
class indexing_suite
: public def_visitor<
indexing_suite<
Container
@@ -117,7 +117,7 @@ namespace boost { namespace python {
> >
{
private:
typedef mpl::or_<
mpl::bool_<NoProxy>
, mpl::not_<is_class<Data> >
@@ -127,10 +127,10 @@ namespace boost { namespace python {
, 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;
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
struct return_policy : return_internal_reference<> {};
#else
@@ -142,7 +142,7 @@ namespace boost { namespace python {
, iterator<Container>
, iterator<Container, return_policy> >::type
def_iterator;
typedef typename mpl::if_<
no_proxy
, detail::no_proxy_helper<
@@ -172,15 +172,15 @@ namespace boost { namespace python {
, 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)
@@ -189,12 +189,12 @@ namespace boost { namespace python {
.def("__contains__", &base_contains)
.def("__iter__", def_iterator())
;
DerivedPolicies::extension_def(cl);
}
}
template <class Class>
static void
static void
extension_def(Class& cl)
{
// default.
@@ -202,24 +202,24 @@ namespace boost { namespace python {
}
private:
static object
base_get_item(back_reference<Container&> container, PyObject* i)
{
{
if (PySlice_Check(i))
return slice_handler::base_get_slice(
container.get(), reinterpret_cast<PySliceObject*>(i));
container.get(), static_cast<PySliceObject*>(static_cast<void*>(i)));
return proxy_handler::base_get_item_(container, i);
}
static void
static void
base_set_item(Container& container, PyObject* i, PyObject* v)
{
if (PySlice_Check(i))
{
slice_handler::base_set_slice(container,
reinterpret_cast<PySliceObject*>(i), v);
slice_handler::base_set_slice(container,
static_cast<PySliceObject*>(static_cast<void*>(i)), v);
}
else
{
@@ -228,7 +228,7 @@ namespace boost { namespace python {
if (elem.check())
{
DerivedPolicies::
set_item(container,
set_item(container,
DerivedPolicies::
convert_index(container, i), elem());
}
@@ -239,7 +239,7 @@ namespace boost { namespace python {
if (elem.check())
{
DerivedPolicies::
set_item(container,
set_item(container,
DerivedPolicies::
convert_index(container, i), elem());
}
@@ -252,20 +252,20 @@ namespace boost { namespace python {
}
}
static void
static void
base_delete_item(Container& container, PyObject* i)
{
if (PySlice_Check(i))
{
slice_handler::base_delete_slice(
container, reinterpret_cast<PySliceObject*>(i));
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)
@@ -290,10 +290,10 @@ namespace boost { namespace python {
return DerivedPolicies::contains(container, x());
else
return false;
}
}
}
};
}} // namespace boost::python
}} // namespace boost::python
#endif // INDEXING_SUITE_JDG20036_HPP

View File

@@ -9,13 +9,67 @@
# 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 {
template <class T, class Conversion>
struct to_python_converter
#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
#if 0 //defined _MSC_VER && _MSC_VER >=1310
//probably other compilers could come here as well
typedef typename detail::test_get_pytype<Conversion> HasGetPytype;
#else
typedef boost::mpl::bool_<has_get_pytype> HasGetPytype;
#endif
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();
};
@@ -23,18 +77,23 @@ struct to_python_converter
// implementation
//
template <class T, class Conversion>
to_python_converter<T,Conversion>::to_python_converter()
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>());
, type_id<T>()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
, &get_pytype_impl
#endif
);
}
}} // namespace boost::python
#endif // TO_PYTHON_CONVERTER_DWA200221_HPP

View File

@@ -12,6 +12,10 @@
# 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>
@@ -36,7 +40,13 @@ struct to_python_indirect
{
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

View File

@@ -9,12 +9,12 @@
# 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/object_manager.hpp>
# include <boost/python/converter/shared_ptr_to_python.hpp>
# include <boost/python/detail/value_is_shared_ptr.hpp>
@@ -24,17 +24,57 @@
# 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& (*p)() =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& (*p)() =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,
@@ -49,6 +89,9 @@ namespace detail
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,
@@ -62,11 +105,20 @@ namespace detail
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();}
#endif
};
}