mirror of
https://github.com/boostorg/python.git
synced 2026-01-26 18:52:26 +00:00
Preparation for delivering nicely-formatted error messages in
Boost.Python. The major change is that, instead of being
boost::function2<PyObject*,PyObject*,PyObject*>, py_function is now a
runtime-polymorphic wrapper for compile-time polymorphic
behavior (just like function) of our own which carries more
information/behaviors. In particular, you can retrieve an array of
c-strings describing the types in the function signature.
Additionally, the minimum and maximum arity are stored in the
py_function object instead of in the 'function' object which wraps it.
* data_members.hpp -
Adjustments for the new py_function. Workarounds for CodeWarrior
Pro 8.3 bugs in function template argument deduction with
pointers-to-members.
* has_back_reference.hpp, test/back_reference.cpp,
test/select_holder.cpp -
Updated to follow the metafunction protocol
* init.hpp, detail/defaults_gen.hpp -
Make Keywords a more-specific type in function signatures to
prevent string literals that show up as char[N] from binding to
the wrong argument (at least Intel 7.1 for Windows does this).
* make_function.hpp -
Adjustments for the new py_function. Arities are now computed
by caller<>.
* opaque_pointer_converter.hpp, type_id.hpp -
Use BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS facilities;
generate specializations that all compilers can handle.
* raw_function.hpp -
Adjustments for the new py_function.
* caller.hpp -
Added arity and signature type name reporting.
* detail/config.hpp
Enable __declspec(dllexport) for Cygwin, thereby fixing the
recent horrible Cygwin linking problems.
* detail/msvc_typeinfo.hpp -
Always pass boost::type<T>* explicitly, thereby working around
incompatible notions of how to specialize function templates with
default arguments on various compilers.
* object/function.hpp
, object/function_handle.hpp
, object/function_object.hpp
, object/function_object.cpp
Adjustments for the new py_function. Arities are carried by
py_function.
* object/iterator.hpp, object/iterator.cpp
Adjustments for the new py_function; we have to compute a
signature of types to construct it with.
* object/py_function.hpp
Removed dependency on boost::function; see the comment at the
top of this entry for more details.
* object/select_holder.hpp
Clean up to more closely follow MPL idioms.
* test/Jamfile -
Adjust the embedding test for the new Cygwin use of declspec.
Update bases and pointee tests with missing properties.
* test/input_iterator.cpp -
Updates for the new iterator adaptors.
* test/opaque.py -
Add Python encoding comment to suppress PendinDeprecationWarning
with recent Python builds.
* test/str.cpp
Pass a Python long instead of a float to string.expandtabs,
suppressing a PendinDeprecationWarning with recent Python builds.
* libs/utility/counting_iterator_example.cpp
Borland workaround
* libs/utility/indirect_iterator_example.cpp
const-correctness fix.
*
[SVN r19247]
This commit is contained in:
@@ -20,20 +20,40 @@
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/add_const.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# include <boost/type_traits/is_member_pointer.hpp>
|
||||
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/vector/vector10.hpp>
|
||||
|
||||
# include <boost/bind.hpp>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
//
|
||||
// This file defines the make_getter and make_setter function
|
||||
// families, which are responsible for turning pointers, references,
|
||||
// and pointers-to-data-members into callable Python objects which
|
||||
// can be used for attribute access on wrapped classes.
|
||||
//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
// Raw Getter and Setter function generators. These class templates
|
||||
// generate static functions which can be bound together with
|
||||
// policies and wrapped to generate the python callable objects
|
||||
// mentioned above.
|
||||
//
|
||||
|
||||
//
|
||||
// Generates get and set functions for access through
|
||||
// pointers-to-data-members
|
||||
//
|
||||
template <class Data, class Class, class Policies>
|
||||
struct member
|
||||
{
|
||||
@@ -74,6 +94,12 @@ namespace detail
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Generates get and set functions for access through ordinary
|
||||
// pointers. These are generally used to wrap static data members,
|
||||
// but can also be used to expose namespace-scope data as class
|
||||
// attributes.
|
||||
//
|
||||
template <class Data, class Policies>
|
||||
struct datum
|
||||
{
|
||||
@@ -108,6 +134,17 @@ namespace detail
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Helper metafunction for determining the default CallPolicy to use
|
||||
// for attribute access. If T is a [reference to a] class type X
|
||||
// whose conversion to python would normally produce a new copy of X
|
||||
// in a wrapped X class instance (as opposed to types such as
|
||||
// std::string, which are converted to native Python types, and
|
||||
// smart pointer types which produce a wrapped class instance of the
|
||||
// pointee type), to-python conversions will attempt to produce an
|
||||
// object which refers to the original C++ object, rather than a
|
||||
// copy. See default_member_getter_policy for rationale.
|
||||
//
|
||||
template <class T>
|
||||
struct default_getter_by_ref
|
||||
: mpl::and_<
|
||||
@@ -123,6 +160,9 @@ namespace detail
|
||||
{
|
||||
};
|
||||
|
||||
// Metafunction computing the default CallPolicy to use for reading
|
||||
// data members
|
||||
//
|
||||
// If it's a regular class type (not an object manager or other
|
||||
// type for which we have to_python specializations, use
|
||||
// return_internal_reference so that we can do things like
|
||||
@@ -130,82 +170,124 @@ namespace detail
|
||||
// and get the right result.
|
||||
template <class T>
|
||||
struct default_member_getter_policy
|
||||
: mpl::if_<
|
||||
default_getter_by_ref<T>
|
||||
, return_internal_reference<>
|
||||
, return_value_policy<return_by_value>
|
||||
>
|
||||
: mpl::if_<
|
||||
default_getter_by_ref<T>
|
||||
, return_internal_reference<>
|
||||
, return_value_policy<return_by_value>
|
||||
>
|
||||
{};
|
||||
|
||||
// Metafunction computing the default CallPolicy to use for reading
|
||||
// non-member data.
|
||||
template <class T>
|
||||
struct default_datum_getter_policy
|
||||
: mpl::if_<
|
||||
default_getter_by_ref<T>
|
||||
, return_value_policy<reference_existing_object>
|
||||
, return_value_policy<return_by_value>
|
||||
>
|
||||
: mpl::if_<
|
||||
default_getter_by_ref<T>
|
||||
, return_value_policy<reference_existing_object>
|
||||
, return_value_policy<return_by_value>
|
||||
>
|
||||
{};
|
||||
|
||||
//
|
||||
// make_getter helper function family -- These helpers to
|
||||
// boost::python::make_getter are used to dispatch behavior. The
|
||||
// third argument is a workaround for a CWPro8 partial ordering bug
|
||||
// with pointers to data members. It should be convertible to
|
||||
// mpl::true_ iff the first argument is a pointer-to-member, and
|
||||
// mpl::false_ otherwise. The fourth argument is for compilers
|
||||
// which don't support partial ordering at all and should always be
|
||||
// passed 0L.
|
||||
//
|
||||
|
||||
// Handle non-member pointers with policies
|
||||
template <class D, class Policies>
|
||||
inline object make_getter(D* p, Policies const& policies, int)
|
||||
inline object make_getter(D* d, Policies const& policies, mpl::false_, int)
|
||||
{
|
||||
return objects::function_object(
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::datum<D,Policies>::get, p, _1, _2
|
||||
&detail::datum<D,Policies>::get, d, _1, _2
|
||||
, policies)
|
||||
, 0);
|
||||
, mpl::vector1<D>()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Handle non-member pointers without policies
|
||||
template <class D>
|
||||
inline object make_getter(D* p, not_specified, long)
|
||||
inline object make_getter(D* d, not_specified, mpl::false_, long)
|
||||
{
|
||||
typedef typename default_datum_getter_policy<D>::type policies;
|
||||
return make_getter(p, policies(), 0L);
|
||||
return detail::make_getter(d, policies(), mpl::false_(), 0);
|
||||
}
|
||||
|
||||
// Handle pointers-to-members with policies
|
||||
template <class C, class D, class Policies>
|
||||
inline object make_getter(D C::*pm, Policies const& policies, int)
|
||||
inline object make_getter(D C::*pm, Policies const& policies, mpl::true_, int)
|
||||
{
|
||||
return objects::function_object(
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,Policies>::get, pm, _1, _2
|
||||
, policies)
|
||||
, 1);
|
||||
, mpl::vector2<D, C const*>()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Handle pointers-to-members without policies
|
||||
template <class C, class D>
|
||||
inline object make_getter(D C::*pm, not_specified, long)
|
||||
inline object make_getter(D C::*pm, not_specified, mpl::true_, long)
|
||||
{
|
||||
typedef typename default_member_getter_policy<D>::type policies;
|
||||
return make_getter(pm, policies(), 0L);
|
||||
}
|
||||
|
||||
template <class D, class Policies>
|
||||
inline object make_getter(D& d, Policies const& policies, ...)
|
||||
{
|
||||
return detail::make_getter(&d, policies, 0L);
|
||||
return detail::make_getter(pm, policies(), mpl::true_(), 0);
|
||||
}
|
||||
|
||||
// Handle references
|
||||
template <class D, class P>
|
||||
inline object make_getter(D& d, P& p, mpl::false_, ...)
|
||||
{
|
||||
// Just dispatch to the handler for pointer types.
|
||||
return detail::make_getter(&d, p, mpl::false_(), 0L);
|
||||
}
|
||||
|
||||
//
|
||||
// make_setter helper function family -- These helpers to
|
||||
// boost::python::make_setter are used to dispatch behavior. The
|
||||
// third argument is for compilers which don't support partial
|
||||
// ordering at all and should always be passed 0.
|
||||
//
|
||||
|
||||
|
||||
// Handle non-member pointers
|
||||
template <class D, class Policies>
|
||||
inline object make_setter(D* p, Policies const& policies, long)
|
||||
inline object make_setter(D* p, Policies const& policies, int)
|
||||
{
|
||||
return objects::function_object(
|
||||
::boost::bind(
|
||||
&detail::datum<D,Policies>::set, p, _1, _2
|
||||
, policies)
|
||||
, 1);
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::datum<D,Policies>::set, p, _1, _2
|
||||
, policies)
|
||||
, mpl::vector2<void, D const&>()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Handle pointers-to-members
|
||||
template <class C, class D, class Policies>
|
||||
inline object make_setter(D C::*pm, Policies const& policies, long)
|
||||
inline object make_setter(D C::*pm, Policies const& policies, int)
|
||||
{
|
||||
return objects::function_object(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,Policies>::set, pm, _1, _2
|
||||
, policies)
|
||||
, 2);
|
||||
objects::py_function(
|
||||
::boost::bind(
|
||||
&detail::member<D,C,Policies>::set, pm, _1, _2
|
||||
, policies)
|
||||
, mpl::vector3<void, C*, D const&>()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Handle references
|
||||
template <class D, class Policies>
|
||||
inline object make_setter(D& x, Policies const& policies, ...)
|
||||
{
|
||||
@@ -213,55 +295,71 @@ namespace detail
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// make_getter function family -- build a callable object which
|
||||
// retrieves data through the first argument and is appropriate for
|
||||
// use as the `get' function in Python properties . The second,
|
||||
// policies argument, is optional. We need both D& and D const&
|
||||
// overloads in order be able to handle rvalues.
|
||||
//
|
||||
template <class D, class Policies>
|
||||
inline object make_getter(D& d, Policies const& policies)
|
||||
{
|
||||
return detail::make_getter(d, policies, 0L);
|
||||
return detail::make_getter(d, policies, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
|
||||
template <class D, class Policies>
|
||||
inline object make_getter(D const& d, Policies const& policies)
|
||||
{
|
||||
return detail::make_getter(d, policies, 0L);
|
||||
return detail::make_getter(d, policies, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
|
||||
template <class D>
|
||||
inline object make_getter(D& x)
|
||||
{
|
||||
return detail::make_getter(x, detail::not_specified(), 0L);
|
||||
detail::not_specified policy;
|
||||
return detail::make_getter(x, policy, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
|
||||
# if !(BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__EDG_VERSION__, <= 238))
|
||||
# if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
template <class D>
|
||||
inline object make_getter(D const& x)
|
||||
inline object make_getter(D const& d)
|
||||
{
|
||||
return detail::make_getter(x, detail::not_specified(), 0L);
|
||||
detail::not_specified policy;
|
||||
return detail::make_getter(d, policy, is_member_pointer<D>(), 0L);
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
//
|
||||
// make_setter function family -- build a callable object which
|
||||
// writes data through the first argument and is appropriate for
|
||||
// use as the `set' function in Python properties . The second,
|
||||
// policies argument, is optional. We need both D& and D const&
|
||||
// overloads in order be able to handle rvalues.
|
||||
//
|
||||
template <class D, class Policies>
|
||||
inline object make_setter(D& x, Policies const& policies)
|
||||
{
|
||||
return detail::make_setter(x, policies, 0L);
|
||||
return detail::make_setter(x, policies, 0);
|
||||
}
|
||||
|
||||
template <class D, class Policies>
|
||||
inline object make_setter(D const& x, Policies const& policies)
|
||||
{
|
||||
return detail::make_setter(x, policies, 0L);
|
||||
return detail::make_setter(x, policies, 0);
|
||||
}
|
||||
|
||||
template <class D>
|
||||
inline object make_setter(D& x)
|
||||
{
|
||||
return detail::make_setter(x, default_call_policies(), 0L);
|
||||
return detail::make_setter(x, default_call_policies(), 0);
|
||||
}
|
||||
|
||||
# if !(BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__EDG_VERSION__, <= 238))
|
||||
template <class D>
|
||||
inline object make_setter(D const& x)
|
||||
{
|
||||
return detail::make_setter(x, default_call_policies(), 0L);
|
||||
return detail::make_setter(x, default_call_policies(), 0);
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/mpl/at.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
@@ -25,7 +26,9 @@
|
||||
# include <boost/preprocessor/dec.hpp>
|
||||
# include <boost/preprocessor/if.hpp>
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/detail/invoke.hpp>
|
||||
# include <boost/python/detail/signature.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
@@ -58,15 +61,18 @@ struct select_result_converter
|
||||
|
||||
template <unsigned> struct caller_arity;
|
||||
|
||||
template <class F, class ConverterGenerators, class CallPolicies, class Sig>
|
||||
struct caller;
|
||||
|
||||
# define BOOST_PYTHON_NEXT(init,name,n) \
|
||||
typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n;
|
||||
|
||||
# define BOOST_PYTHON_ARG_CONVERTER(n) \
|
||||
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
|
||||
BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \
|
||||
typedef typename apply_iter1<conv_iter##n,arg_iter##n>::type c_t##n; \
|
||||
c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \
|
||||
if (!c##n.convertible()) \
|
||||
# define BOOST_PYTHON_ARG_CONVERTER(n) \
|
||||
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
|
||||
BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \
|
||||
typedef typename apply_iter1<conv_iter##n,arg_iter##n>::type c_t##n; \
|
||||
c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \
|
||||
if (!c##n.convertible()) \
|
||||
return 0;
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
@@ -119,8 +125,8 @@ struct caller
|
||||
typedef PyObject* result_type;
|
||||
|
||||
caller(F f, CallPolicies p) : base(f,p) {}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -163,6 +169,14 @@ struct caller_arity<N>
|
||||
|
||||
return m_data.second().postcall(args_, result);
|
||||
}
|
||||
|
||||
static unsigned min_arity() { return N; }
|
||||
|
||||
static char const*const* type_names()
|
||||
{
|
||||
return signature<Sig>::type_names();
|
||||
}
|
||||
|
||||
private:
|
||||
compressed_pair<F,Policies> m_data;
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) || defined(__CYGWIN__)
|
||||
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
# if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_DECL __declspec(dllexport)
|
||||
# define BOOST_PYTHON_BUILD_DLL
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <boost/mpl/begin_end.hpp>
|
||||
#include <boost/mpl/next.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
@@ -203,26 +204,26 @@ namespace detail
|
||||
}; \
|
||||
};
|
||||
|
||||
#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
||||
fstubs_name(char const* doc = 0) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>(doc) {} \
|
||||
template <class Keywords> \
|
||||
fstubs_name(char const* doc, Keywords const& keywords) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>( \
|
||||
doc, keywords.range()) \
|
||||
{ \
|
||||
typedef typename ::boost::python::detail:: \
|
||||
error::more_keywords_than_function_arguments< \
|
||||
Keywords::size,n_args>::too_many_keywords assertion; \
|
||||
} \
|
||||
template <class Keywords> \
|
||||
fstubs_name(Keywords const& keywords, char const* doc = 0) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>( \
|
||||
doc, keywords.range()) \
|
||||
{ \
|
||||
typedef typename ::boost::python::detail:: \
|
||||
error::more_keywords_than_function_arguments< \
|
||||
Keywords::size,n_args>::too_many_keywords assertion; \
|
||||
#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
||||
fstubs_name(char const* doc = 0) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>(doc) {} \
|
||||
template <std::size_t N> \
|
||||
fstubs_name(char const* doc, ::boost::python::detail::keywords<N> const& keywords) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>( \
|
||||
doc, keywords.range()) \
|
||||
{ \
|
||||
typedef typename ::boost::python::detail:: \
|
||||
error::more_keywords_than_function_arguments< \
|
||||
N,n_args>::too_many_keywords assertion; \
|
||||
} \
|
||||
template <std::size_t N> \
|
||||
fstubs_name(::boost::python::detail::keywords<N> const& keywords, char const* doc = 0) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>( \
|
||||
doc, keywords.range()) \
|
||||
{ \
|
||||
typedef typename ::boost::python::detail:: \
|
||||
error::more_keywords_than_function_arguments< \
|
||||
N,n_args>::too_many_keywords assertion; \
|
||||
}
|
||||
|
||||
# if defined(BOOST_NO_VOID_RETURNS)
|
||||
|
||||
@@ -49,17 +49,24 @@ template< typename T > T&(* is_ref_tester1(type<T>) )(type<T>) { return 0; }
|
||||
inline char BOOST_TT_DECL is_ref_tester1(...) { return 0; }
|
||||
|
||||
template <class T>
|
||||
inline typeinfo msvc_typeid(boost::type<T>* = 0)
|
||||
inline typeinfo msvc_typeid(boost::type<T>*)
|
||||
{
|
||||
return detail::typeid_ref(
|
||||
(boost::type<T>*)0, detail::is_ref_tester1(type<T>())
|
||||
);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline typeinfo msvc_typeid<void>(boost::type<void>*)
|
||||
{
|
||||
return typeid(void);
|
||||
}
|
||||
|
||||
# ifndef NDEBUG
|
||||
inline typeinfo assert_array_typeid_compiles()
|
||||
{
|
||||
return msvc_typeid<char const[3]>(), msvc_typeid<char[3]>();
|
||||
return msvc_typeid((boost::type<char const[3]>*)0)
|
||||
, msvc_typeid((boost::type<char[3]>*)0);
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# define HAS_BACK_REFERENCE_DWA2002323_HPP
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
@@ -14,8 +15,8 @@ namespace boost { namespace python {
|
||||
// contains a back-reference to its owning PyObject*
|
||||
template <class T>
|
||||
struct has_back_reference
|
||||
: mpl::false_
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -203,22 +203,22 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
|
||||
: base(doc_)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Keywords>
|
||||
init(char const* doc_, Keywords const& kw)
|
||||
: base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size))
|
||||
{
|
||||
typedef typename detail::error::more_keywords_than_init_arguments<
|
||||
Keywords::size, n_arguments::value
|
||||
>::too_many_keywords assertion;
|
||||
}
|
||||
|
||||
template <class Keywords>
|
||||
init(Keywords const& kw, char const* doc_ = 0)
|
||||
template <std::size_t N>
|
||||
init(char const* doc_, detail::keywords<N> const& kw)
|
||||
: base(doc_, kw.range())
|
||||
{
|
||||
typedef typename detail::error::more_keywords_than_init_arguments<
|
||||
Keywords::size, n_arguments::value
|
||||
N, n_arguments::value
|
||||
>::too_many_keywords assertion;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
init(detail::keywords<N> const& kw, char const* doc_ = 0)
|
||||
: base(doc_, kw.range())
|
||||
{
|
||||
typedef typename detail::error::more_keywords_than_init_arguments<
|
||||
N, n_arguments::value
|
||||
>::too_many_keywords assertion;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace detail
|
||||
{
|
||||
return objects::function_object(
|
||||
detail::caller<F,ConverterGenerators,CallPolicies,Sig>(f, p)
|
||||
, mpl::size<Sig>::value - 1);
|
||||
);
|
||||
}
|
||||
|
||||
// As above, except that it accepts argument keywords. NumKeywords
|
||||
@@ -62,8 +62,7 @@ namespace detail
|
||||
|
||||
return objects::function_object(
|
||||
detail::caller<F,ConverterGenerators,CallPolicies,Sig>(f, p)
|
||||
, arity
|
||||
, kw);
|
||||
, kw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ struct BOOST_PYTHON_DECL function : PyObject
|
||||
{
|
||||
function(
|
||||
py_function const&
|
||||
, unsigned min_arity
|
||||
, unsigned max_arity
|
||||
, python::detail::keyword const* names_and_defaults
|
||||
, unsigned num_keywords);
|
||||
|
||||
@@ -48,8 +46,6 @@ struct BOOST_PYTHON_DECL function : PyObject
|
||||
|
||||
private: // data members
|
||||
py_function m_fn;
|
||||
unsigned m_min_arity;
|
||||
unsigned m_max_arity;
|
||||
handle<function> m_overloads;
|
||||
object m_name;
|
||||
object m_doc;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
BOOST_PYTHON_DECL handle<> function_handle_impl(py_function const& f, unsigned min_args, unsigned max_args = 0);
|
||||
BOOST_PYTHON_DECL handle<> function_handle_impl(py_function const& f);
|
||||
|
||||
// Just like function_object, but returns a handle<> instead. Using
|
||||
// this for arg_to_python<> allows us to break a circular dependency
|
||||
@@ -26,9 +26,11 @@ inline handle<> function_handle(F const& f, Signature)
|
||||
|
||||
return objects::function_handle_impl(
|
||||
python::detail::caller<
|
||||
F,python::detail::args_from_python,default_call_policies,Signature>(
|
||||
f, default_call_policies())
|
||||
, n_arguments, n_arguments);
|
||||
F,python::detail::args_from_python,default_call_policies,Signature
|
||||
>(
|
||||
f, default_call_policies()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Just like make_function, but returns a handle<> intead. Same
|
||||
|
||||
@@ -17,15 +17,13 @@ namespace objects
|
||||
{
|
||||
BOOST_PYTHON_DECL api::object function_object(
|
||||
py_function const& f
|
||||
, unsigned min_arity, unsigned max_arity
|
||||
, python::detail::keyword_range const&);
|
||||
|
||||
BOOST_PYTHON_DECL api::object function_object(
|
||||
py_function const& f
|
||||
, unsigned arity
|
||||
, python::detail::keyword_range const&);
|
||||
|
||||
BOOST_PYTHON_DECL api::object function_object(py_function const& f, unsigned arity);
|
||||
BOOST_PYTHON_DECL api::object function_object(py_function const& f);
|
||||
|
||||
// Add an attribute to the name_space with the given name. If it is
|
||||
// a Boost.Python function object
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/python/arg_from_python.hpp>
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/mpl/vector/vector10.hpp>
|
||||
# include <boost/bind.hpp>
|
||||
# include <boost/bind/protect.hpp>
|
||||
# include <boost/python/detail/raw_pyobject.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# include <boost/type_traits/add_const.hpp>
|
||||
|
||||
# include <boost/detail/iterator.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
// CallPolicies for the next() method of iterators. We don't want
|
||||
@@ -118,8 +121,18 @@ namespace detail
|
||||
// Make a callable object which can be used as the iterator's next() function.
|
||||
object next_function =
|
||||
objects::function_object(
|
||||
py_function(
|
||||
bind(&detail::iterator_next<Iterator,NextPolicies>::execute, _1, _2, policies)
|
||||
, 1);
|
||||
, mpl::vector2<
|
||||
# if defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
object
|
||||
# else
|
||||
typename boost::detail::iterator_traits<Iterator>::value_type
|
||||
# endif
|
||||
, Iterator
|
||||
>()
|
||||
)
|
||||
);
|
||||
|
||||
return class_<range_>(name, no_init)
|
||||
.def("__iter__", identity_function())
|
||||
@@ -164,16 +177,25 @@ namespace detail
|
||||
|
||||
template <class NextPolicies, class Target, class Iterator, class Accessor1, class Accessor2>
|
||||
inline object make_iterator_function(
|
||||
Accessor1 const& get_start, Accessor2 const& get_finish, Iterator const& (*)(), boost::type<Target>*, NextPolicies*, int)
|
||||
Accessor1 const& get_start
|
||||
, Accessor2 const& get_finish
|
||||
, Iterator const& (*)()
|
||||
, boost::type<Target>*
|
||||
, NextPolicies*
|
||||
, int
|
||||
)
|
||||
{
|
||||
return
|
||||
objects::function_object(
|
||||
boost::bind(
|
||||
&make_iterator_help<
|
||||
Target,Iterator,Accessor1,Accessor2,NextPolicies
|
||||
>::create
|
||||
, get_start, get_finish, _1, _2)
|
||||
, 1 );
|
||||
py_function(
|
||||
boost::bind(
|
||||
&make_iterator_help<
|
||||
Target,Iterator,Accessor1,Accessor2,NextPolicies
|
||||
>::create
|
||||
, get_start, get_finish, _1, _2)
|
||||
, mpl::vector2<object, Target>()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template <class NextPolicies, class Target, class Iterator, class Accessor1, class Accessor2>
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
// to its suitability for any purpose.
|
||||
#ifndef PY_FUNCTION_DWA200286_HPP
|
||||
# define PY_FUNCTION_DWA200286_HPP
|
||||
# include <boost/function/function2.hpp>
|
||||
|
||||
# include <boost/python/detail/signature.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <memory>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
@@ -13,9 +17,142 @@ namespace boost { namespace python { namespace objects {
|
||||
// function signature:
|
||||
//
|
||||
// PyObject* (PyObject* args, PyObject* keywords)
|
||||
//
|
||||
// We use boost::function to avoid generating lots of virtual tables
|
||||
typedef boost::function2<PyObject*, PyObject*, PyObject*> py_function;
|
||||
|
||||
struct BOOST_PYTHON_DECL py_function_impl_base
|
||||
{
|
||||
virtual ~py_function_impl_base();
|
||||
virtual PyObject* operator()(PyObject*, PyObject*) = 0;
|
||||
virtual unsigned min_arity() const = 0;
|
||||
virtual unsigned max_arity() const;
|
||||
virtual char const* const* type_names() const = 0;
|
||||
};
|
||||
|
||||
template <class Caller>
|
||||
struct caller_py_function_impl : py_function_impl_base
|
||||
{
|
||||
caller_py_function_impl(Caller const& caller)
|
||||
: m_caller(caller)
|
||||
{}
|
||||
|
||||
PyObject* operator()(PyObject* args, PyObject* kw)
|
||||
{
|
||||
return m_caller(args, kw);
|
||||
}
|
||||
|
||||
virtual unsigned min_arity() const
|
||||
{
|
||||
return m_caller.min_arity();
|
||||
}
|
||||
|
||||
virtual char const* const* type_names() const
|
||||
{
|
||||
return m_caller.type_names();
|
||||
}
|
||||
|
||||
private:
|
||||
Caller m_caller;
|
||||
};
|
||||
|
||||
template <class Caller, class Sig>
|
||||
struct signature_py_function_impl : py_function_impl_base
|
||||
{
|
||||
signature_py_function_impl(Caller const& caller)
|
||||
: m_caller(caller)
|
||||
{}
|
||||
|
||||
PyObject* operator()(PyObject* args, PyObject* kw)
|
||||
{
|
||||
return m_caller(args, kw);
|
||||
}
|
||||
|
||||
virtual unsigned min_arity() const
|
||||
{
|
||||
return mpl::size<Sig>::value - 1;
|
||||
}
|
||||
|
||||
virtual char const* const* type_names() const
|
||||
{
|
||||
return python::detail::signature<Sig>::type_names();
|
||||
}
|
||||
|
||||
private:
|
||||
Caller m_caller;
|
||||
};
|
||||
|
||||
template <class Caller, class Sig>
|
||||
struct full_py_function_impl : py_function_impl_base
|
||||
{
|
||||
full_py_function_impl(Caller const& caller, unsigned min_arity, unsigned max_arity)
|
||||
: m_caller(caller)
|
||||
, m_min_arity(min_arity)
|
||||
, m_max_arity(max_arity > min_arity ? max_arity : min_arity)
|
||||
{}
|
||||
|
||||
PyObject* operator()(PyObject* args, PyObject* kw)
|
||||
{
|
||||
return m_caller(args, kw);
|
||||
}
|
||||
|
||||
virtual unsigned min_arity() const
|
||||
{
|
||||
return m_min_arity;
|
||||
}
|
||||
|
||||
virtual unsigned max_arity() const
|
||||
{
|
||||
return m_max_arity;
|
||||
}
|
||||
|
||||
virtual char const* const* type_names() const
|
||||
{
|
||||
return python::detail::signature<Sig>::type_names();
|
||||
}
|
||||
|
||||
private:
|
||||
Caller m_caller;
|
||||
unsigned m_min_arity;
|
||||
unsigned m_max_arity;
|
||||
};
|
||||
|
||||
struct py_function
|
||||
{
|
||||
template <class Caller>
|
||||
py_function(Caller const& caller)
|
||||
: m_impl(new caller_py_function_impl<Caller>(caller))
|
||||
{}
|
||||
|
||||
template <class Caller, class Sig>
|
||||
py_function(Caller const& caller, Sig)
|
||||
: m_impl(new signature_py_function_impl<Caller, Sig>(caller))
|
||||
{}
|
||||
|
||||
template <class Caller, class Sig>
|
||||
py_function(Caller const& caller, Sig, int min_arity, int max_arity = 0)
|
||||
: m_impl(new full_py_function_impl<Caller, Sig>(caller, min_arity, max_arity))
|
||||
{}
|
||||
|
||||
py_function(py_function const& rhs)
|
||||
: m_impl(rhs.m_impl)
|
||||
{}
|
||||
|
||||
PyObject* operator()(PyObject* args, PyObject* kw) const
|
||||
{
|
||||
return (*m_impl)(args, kw);
|
||||
}
|
||||
|
||||
unsigned min_arity() const
|
||||
{
|
||||
return m_impl->min_arity();
|
||||
}
|
||||
|
||||
unsigned max_arity() const
|
||||
{
|
||||
return m_impl->max_arity();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::auto_ptr<py_function_impl_base> m_impl;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type_traits/is_base_and_derived.hpp>
|
||||
@@ -49,7 +50,7 @@ namespace detail
|
||||
// constructor. Normally this means U is a virtual function
|
||||
// dispatcher subclass for T.
|
||||
template <class T, class U>
|
||||
void check_default_constructible(T*, U*, mpl::bool_<true>)
|
||||
void check_default_constructible(T*, U*, mpl::true_)
|
||||
{
|
||||
python::detail::force_instantiate(
|
||||
sizeof(specify_init_arguments_or_no_init_for_class_<T>(U((::PyObject*)0)))
|
||||
@@ -59,7 +60,7 @@ namespace detail
|
||||
// Handles the "normal" case where T is held directly and
|
||||
// has_back_reference<T> is not specialized.
|
||||
template <class T>
|
||||
void check_default_constructible(T*, T*, mpl::bool_<false>)
|
||||
void check_default_constructible(T*, T*, mpl::false_)
|
||||
{
|
||||
python::detail::force_instantiate(
|
||||
sizeof(specify_init_arguments_or_no_init_for_class_<T>(T()))
|
||||
@@ -90,17 +91,22 @@ namespace detail
|
||||
template <class T, class Held>
|
||||
struct select_value_holder
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same<T,Held>::value) | has_back_reference<T>::value);
|
||||
|
||||
private:
|
||||
typedef mpl::or_<
|
||||
mpl::not_<is_same<T,Held> >
|
||||
, has_back_reference<T>
|
||||
> use_back_ref;
|
||||
|
||||
public:
|
||||
static void assert_default_constructible()
|
||||
{
|
||||
detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_<back_ref>());
|
||||
detail::check_default_constructible((T*)0,(Held*)0, use_back_ref());
|
||||
}
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
back_ref
|
||||
, value_holder_back_reference<T,Held>
|
||||
, value_holder<T>
|
||||
typedef typename mpl::if_<
|
||||
use_back_ref
|
||||
, value_holder_back_reference<T,Held>
|
||||
, value_holder<T>
|
||||
>::type type;
|
||||
|
||||
static inline void register_() {}
|
||||
@@ -111,23 +117,28 @@ namespace detail
|
||||
template <class T,class Ptr>
|
||||
struct select_pointer_holder
|
||||
{
|
||||
typedef typename python::pointee<Ptr>::type pointee;
|
||||
BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same<T,pointee>::value) | has_back_reference<T>::value);
|
||||
|
||||
private:
|
||||
typedef typename python::pointee<Ptr>::type wrapper;
|
||||
typedef mpl::or_<
|
||||
mpl::not_<is_same<T,wrapper> >
|
||||
, has_back_reference<T>
|
||||
> use_back_ref;
|
||||
|
||||
public:
|
||||
static void assert_default_constructible()
|
||||
{
|
||||
detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_<back_ref>());
|
||||
detail::check_default_constructible((T*)0,(wrapper*)0, use_back_ref());
|
||||
}
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
back_ref
|
||||
typedef typename mpl::if_<
|
||||
use_back_ref
|
||||
, pointer_holder_back_reference<Ptr,T>
|
||||
, pointer_holder<Ptr,T>
|
||||
>::type type;
|
||||
|
||||
static inline void register_()
|
||||
{
|
||||
select_pointer_holder::register_(mpl::bool_<back_ref>());
|
||||
select_pointer_holder::register_(use_back_ref());
|
||||
}
|
||||
|
||||
static type* get() { return 0; }
|
||||
|
||||
@@ -113,22 +113,24 @@ PyTypeObject opaque_pointer_converter<Pointer>::type_object =
|
||||
::boost::python::detail::dealloc
|
||||
};
|
||||
}} // namespace boost::python
|
||||
# ifdef BOOST_MSVC
|
||||
# ifdef BOOST_MSVC
|
||||
// MSC works without this workaround, but needs another one ...
|
||||
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(Pointee)
|
||||
# else
|
||||
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
|
||||
namespace boost { namespace python { \
|
||||
template<> \
|
||||
inline type_info type_id(boost::type<Pointee>*) { \
|
||||
return type_info (typeid (Pointee *)); \
|
||||
} \
|
||||
template<> \
|
||||
inline type_info type_id( \
|
||||
boost::type<const volatile Pointee &>*) { \
|
||||
return type_info (typeid (Pointee *)); \
|
||||
} \
|
||||
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(Pointee)
|
||||
# else
|
||||
# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \
|
||||
namespace boost { namespace python { \
|
||||
template<> \
|
||||
inline type_info type_id<Pointee>(BOOST_PYTHON_EXPLICIT_TT_DEF(Pointee)) \
|
||||
{ \
|
||||
return type_info (typeid (Pointee *)); \
|
||||
} \
|
||||
template<> \
|
||||
inline type_info type_id<const volatile Pointee&>( \
|
||||
BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile Pointee&)) \
|
||||
{ \
|
||||
return type_info (typeid (Pointee *)); \
|
||||
} \
|
||||
}}
|
||||
# endif
|
||||
# endif
|
||||
# endif // OPAQUE_POINTER_CONVERTER_HPP_
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
# include <boost/python/tuple.hpp>
|
||||
# include <boost/python/dict.hpp>
|
||||
# include <boost/python/object/py_function.hpp>
|
||||
# include <boost/mpl/vector/vector10.hpp>
|
||||
|
||||
# include <boost/limits.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
namespace boost { namespace python {
|
||||
@@ -31,17 +33,25 @@ namespace detail
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
F f;
|
||||
};
|
||||
|
||||
object BOOST_PYTHON_DECL make_raw_function(objects::py_function, std::size_t min_args);
|
||||
object BOOST_PYTHON_DECL make_raw_function(objects::py_function);
|
||||
}
|
||||
|
||||
template <class F>
|
||||
object raw_function(F f, std::size_t min_args = 0)
|
||||
{
|
||||
return detail::make_raw_function(detail::raw_dispatcher<F>(f), min_args);
|
||||
return detail::make_raw_function(
|
||||
objects::py_function(
|
||||
detail::raw_dispatcher<F>(f)
|
||||
, mpl::vector1<PyObject*>()
|
||||
, min_args
|
||||
, std::numeric_limits<unsigned>::max()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -57,14 +57,20 @@ struct type_info : private totally_ordered<type_info>
|
||||
base_id_t m_base_type;
|
||||
};
|
||||
|
||||
# ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
|
||||
# define BOOST_PYTHON_EXPLICIT_TT_DEF(T) ::boost::type<T>*
|
||||
# else
|
||||
# define BOOST_PYTHON_EXPLICIT_TT_DEF(T)
|
||||
# endif
|
||||
|
||||
template <class T>
|
||||
inline type_info type_id(boost::type<T>* = 0)
|
||||
inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T))
|
||||
{
|
||||
return type_info(
|
||||
# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 700)
|
||||
typeid(T)
|
||||
# else // strip the decoration which msvc and Intel mistakenly leave in
|
||||
python::detail::msvc_typeid<T>()
|
||||
python::detail::msvc_typeid((boost::type<T>*)0)
|
||||
# endif
|
||||
);
|
||||
}
|
||||
@@ -76,11 +82,11 @@ inline type_info type_id(boost::type<T>* = 0)
|
||||
// down into template instantiations. Explicit specialization stops
|
||||
// that from taking hold.
|
||||
|
||||
# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \
|
||||
template <> \
|
||||
inline type_info type_id<T>(boost::type<T>*) \
|
||||
{ \
|
||||
return type_info(typeid(T)); \
|
||||
# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \
|
||||
template <> \
|
||||
inline type_info type_id<T>(BOOST_PYTHON_EXPLICIT_TT_DEF(T)) \
|
||||
{ \
|
||||
return type_info(typeid(T)); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short)
|
||||
|
||||
@@ -14,33 +14,42 @@
|
||||
#include <boost/python/refcount.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
|
||||
#include <boost/python/detail/signature.hpp>
|
||||
#include <boost/mpl/vector/vector10.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
py_function_impl_base::~py_function_impl_base()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned py_function_impl_base::max_arity() const
|
||||
{
|
||||
return this->min_arity();
|
||||
}
|
||||
|
||||
extern PyTypeObject function_type;
|
||||
|
||||
function::function(
|
||||
py_function const& implementation
|
||||
, unsigned min_arity
|
||||
, unsigned max_arity
|
||||
, python::detail::keyword const* names_and_defaults
|
||||
, unsigned num_keywords
|
||||
)
|
||||
: m_fn(implementation)
|
||||
, m_min_arity(min_arity)
|
||||
// was using std::max here, but a problem with MinGW-2.95 and
|
||||
// our <boost/numeric/...> directory prevents it.
|
||||
, m_max_arity(max_arity > min_arity ? max_arity : min_arity)
|
||||
{
|
||||
if (names_and_defaults != 0)
|
||||
{
|
||||
unsigned keyword_offset
|
||||
= m_max_arity > num_keywords ? m_max_arity - num_keywords : 0;
|
||||
unsigned int max_arity = m_fn.max_arity();
|
||||
unsigned int keyword_offset
|
||||
= max_arity > num_keywords ? max_arity - num_keywords : 0;
|
||||
|
||||
|
||||
unsigned tuple_size = num_keywords ? m_max_arity : 0;
|
||||
unsigned tuple_size = num_keywords ? max_arity : 0;
|
||||
m_arg_names = object(handle<>(PyTuple_New(tuple_size)));
|
||||
|
||||
if (num_keywords != 0)
|
||||
@@ -86,7 +95,8 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
do
|
||||
{
|
||||
// Check for a plausible number of arguments
|
||||
if (total_args >= f->m_min_arity && total_args <= f->m_max_arity)
|
||||
if (total_args >= f->m_fn.min_arity()
|
||||
&& total_args <= f->m_fn.max_arity())
|
||||
{
|
||||
// This will be the args that actually get passed
|
||||
handle<> args2(allow_null(borrowed(args)));
|
||||
@@ -242,7 +252,7 @@ namespace
|
||||
}
|
||||
|
||||
// Something for the end of the chain of binary operators
|
||||
PyObject* not_implemented_impl(PyObject*, PyObject*)
|
||||
PyObject* not_implemented(PyObject*, PyObject*)
|
||||
{
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
@@ -250,9 +260,11 @@ namespace
|
||||
|
||||
handle<function> not_implemented_function()
|
||||
{
|
||||
|
||||
static object keeper(
|
||||
function_object(¬_implemented_impl, 2, 3
|
||||
, python::detail::keyword_range())
|
||||
function_object(
|
||||
py_function(¬_implemented, mpl::vector1<void>(), 2)
|
||||
, python::detail::keyword_range())
|
||||
);
|
||||
return handle<function>(borrowed(downcast<function>(keeper.ptr())));
|
||||
}
|
||||
@@ -478,48 +490,38 @@ PyTypeObject function_type = {
|
||||
};
|
||||
|
||||
object function_object(
|
||||
py_function const& f, unsigned min_arity, unsigned max_arity
|
||||
py_function const& f
|
||||
, python::detail::keyword_range const& keywords)
|
||||
{
|
||||
return python::object(
|
||||
python::detail::new_non_null_reference(
|
||||
new function(
|
||||
f, min_arity, max_arity, keywords.first, keywords.second - keywords.first)));
|
||||
f, keywords.first, keywords.second - keywords.first)));
|
||||
}
|
||||
|
||||
object function_object(
|
||||
py_function const& f
|
||||
, unsigned arity
|
||||
, python::detail::keyword_range const& kw)
|
||||
object function_object(py_function const& f)
|
||||
{
|
||||
return function_object(f, arity, arity, kw);
|
||||
}
|
||||
|
||||
object function_object(py_function const& f, unsigned arity)
|
||||
{
|
||||
return function_object(f, arity, arity, python::detail::keyword_range());
|
||||
return function_object(f, python::detail::keyword_range());
|
||||
}
|
||||
|
||||
|
||||
handle<> function_handle_impl(py_function const& f, unsigned min_arity, unsigned max_arity)
|
||||
handle<> function_handle_impl(py_function const& f)
|
||||
{
|
||||
return python::handle<>(
|
||||
allow_null(
|
||||
new function(f, min_arity, max_arity, 0, 0)));
|
||||
new function(f, 0, 0)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
object BOOST_PYTHON_DECL make_raw_function(objects::py_function f, std::size_t min_args)
|
||||
object BOOST_PYTHON_DECL make_raw_function(objects::py_function f)
|
||||
{
|
||||
static keyword k;
|
||||
|
||||
return objects::function_object(
|
||||
f
|
||||
, min_args
|
||||
, std::numeric_limits<std::size_t>::max()
|
||||
, keyword_range(&k,&k));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,19 +7,27 @@
|
||||
#include <boost/python/object/iterator_core.hpp>
|
||||
#include <boost/python/object/function_object.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/mpl/vector/vector10.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
static PyObject* identity(PyObject* args_, PyObject*)
|
||||
namespace
|
||||
{
|
||||
PyObject* x = PyTuple_GET_ITEM(args_,0);
|
||||
Py_INCREF(x);
|
||||
return x;
|
||||
PyObject* identity(PyObject* args_, PyObject*)
|
||||
{
|
||||
PyObject* x = PyTuple_GET_ITEM(args_,0);
|
||||
Py_INCREF(x);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object const& identity_function()
|
||||
{
|
||||
static object result(function_object(&identity, 1));
|
||||
static object result(
|
||||
function_object(
|
||||
py_function(&identity, mpl::vector2<PyObject*,PyObject*>())
|
||||
)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ run ../test/embedding.cpp <lib>../build/boost_python
|
||||
: # requirements
|
||||
$(PYTHON_PROPERTIES)
|
||||
<define>BOOST_PYTHON_STATIC_LIB
|
||||
<define>BOOST_PYTHON_STATIC_MODULE
|
||||
<library-path>$(PYTHON_LIB_PATH)
|
||||
<$(gcc-compilers)><debug-python><library-path>$(CYGWIN_PYTHON_DEBUG_DLL_PATH)
|
||||
<$(gcc-compilers)><*><library-path>$(CYGWIN_PYTHON_DLL_PATH)
|
||||
@@ -151,9 +152,9 @@ run indirect_traits_test.cpp ;
|
||||
run destroy_test.cpp ;
|
||||
run pointer_type_id_test.cpp <lib>../../test/build/boost_test_exec_monitor : : : $(UNIT_TEST_PROPERTIES) ;
|
||||
run member_function_cast.cpp ;
|
||||
run bases.cpp ;
|
||||
run bases.cpp : : : $(UNIT_TEST_PROPERTIES) ;
|
||||
run if_else.cpp ;
|
||||
run pointee.cpp ;
|
||||
run pointee.cpp : : : $(UNIT_TEST_PROPERTIES) ;
|
||||
run result.cpp ;
|
||||
|
||||
compile string_literal.cpp ;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <cassert>
|
||||
#include <boost/python/copy_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
// This test shows that a class can be wrapped "as itself" but also
|
||||
// acquire a back-reference iff has_back_reference<> is appropriately
|
||||
@@ -64,14 +65,14 @@ namespace boost { namespace python
|
||||
{
|
||||
template <>
|
||||
struct has_back_reference<Y>
|
||||
: mpl::true_
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct has_back_reference<Z>
|
||||
: mpl::true_
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
}}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/iterator.hpp>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <list>
|
||||
|
||||
using namespace boost::python;
|
||||
@@ -21,7 +21,7 @@ struct doubler
|
||||
int operator()(int x) const { return x * 2; }
|
||||
};
|
||||
|
||||
typedef boost::transform_iterator_generator<doubler, list_int::iterator>::type doubling_iterator;
|
||||
typedef boost::transform_iterator<doubler, list_int::iterator> doubling_iterator;
|
||||
typedef std::pair<doubling_iterator,doubling_iterator> list_range2;
|
||||
|
||||
list_range2 range2(list_int& x)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# -*- coding: iso-latin-1 -*-
|
||||
# Copyright Gottfried Ganßauge 2003. Permission to copy, use,
|
||||
# modify, sell and distribute this software is granted provided this
|
||||
# copyright notice appears in all copies. This software is provided
|
||||
# "as is" without express or implied warranty, and with no claim as
|
||||
# to its suitability for any purpose.
|
||||
|
||||
"""
|
||||
>>> from opaque_ext import *
|
||||
>>> #
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#include <boost/function/function0.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <memory>
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
@@ -24,8 +25,8 @@ namespace boost { namespace python
|
||||
// specialization
|
||||
template <>
|
||||
struct has_back_reference<BR>
|
||||
: mpl::true_
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
}} // namespace boost::python
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ void work_with_string(object print)
|
||||
str tabstr("\t\ttab\tdemo\t!");
|
||||
print(tabstr.expandtabs());
|
||||
print(tabstr.expandtabs(4));
|
||||
print(tabstr.expandtabs(7.9));
|
||||
print(tabstr.expandtabs(7L));
|
||||
|
||||
print("operators");
|
||||
print( str("part1") + str("part2") );
|
||||
|
||||
Reference in New Issue
Block a user