mirror of
https://github.com/boostorg/python.git
synced 2026-01-21 17:12:22 +00:00
generalized the new def_raw() feature
[SVN r8168]
This commit is contained in:
@@ -30,7 +30,10 @@ class ClassWrapper
|
||||
// to C++ verbatim (as a 'Tuple const &' and 'Dict const &'
|
||||
// respectively). This is useful for manual argument passing.
|
||||
// It's also the only possibility to pass keyword arguments to C++.
|
||||
void def_raw(RawArgumentsFunction::PtrFun fn, const char* name)
|
||||
// Fn must have a signatur that is compatible to
|
||||
// PyObject * (*)(PyObject * aTuple, PyObject * aDictionary)
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{ m_class->def_raw(fn, name); }
|
||||
|
||||
// define member functions. In fact this works for free functions, too -
|
||||
|
||||
@@ -374,9 +374,12 @@ class ExtensionClass
|
||||
// to C++ verbatim (as a 'Tuple const &' and 'Dict const &'
|
||||
// respectively). This is useful for manual argument passing.
|
||||
// It's also the only possibility to pass keyword arguments to C++.
|
||||
void def_raw(RawArgumentsFunction::PtrFun fn, const char* name)
|
||||
// Fn must have a signatur that is compatible to
|
||||
// PyObject * (*)(PyObject * aTuple, PyObject * aDictionary)
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
this->add_method(new RawArgumentsFunction(fn), name);
|
||||
this->add_method(py::detail::new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
// define member functions. In fact this works for free functions, too -
|
||||
|
||||
@@ -563,25 +563,20 @@ struct RawTest
|
||||
int i_;
|
||||
};
|
||||
|
||||
template class py::ExtensionClass<RawTest>;
|
||||
PyObject * raw(py::Tuple const & args, py::Dict const & keywords);
|
||||
|
||||
PyObject * raw(py::Tuple const & args, py::Dict const & keywords)
|
||||
int raw1(PyObject * args, PyObject * keywords)
|
||||
{
|
||||
if(args.size() != 2 || keywords.size() != 2)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw py::ArgumentError();
|
||||
}
|
||||
|
||||
RawTest * first = from_python(args[0].get(), py::Type<RawTest *>());
|
||||
int second = from_python(args[1].get(), py::Type<int>());
|
||||
|
||||
int third = from_python(keywords[py::String("third")].get(), py::Type<int>());
|
||||
int fourth = from_python(keywords[py::String("fourth")].get(), py::Type<int>());
|
||||
|
||||
return to_python(first->i_ + second + third + fourth);
|
||||
return PyTuple_Size(args) + PyDict_Size(keywords);
|
||||
}
|
||||
|
||||
int raw2(py::Ptr args, py::Ptr keywords)
|
||||
{
|
||||
return PyTuple_Size(args.get()) + PyDict_Size(keywords.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************/
|
||||
/* */
|
||||
/* Ratio */
|
||||
@@ -853,6 +848,25 @@ void init_module(py::Module& m)
|
||||
rawtest_class.def_raw(&raw, "raw");
|
||||
|
||||
m.def_raw(&raw, "raw");
|
||||
m.def_raw(&raw1, "raw1");
|
||||
m.def_raw(&raw2, "raw2");
|
||||
}
|
||||
|
||||
PyObject * raw(py::Tuple const & args, py::Dict const & keywords)
|
||||
{
|
||||
if(args.size() != 2 || keywords.size() != 2)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||
throw py::ArgumentError();
|
||||
}
|
||||
|
||||
RawTest * first = from_python(args[0].get(), py::Type<RawTest *>());
|
||||
int second = from_python(args[1].get(), py::Type<int>());
|
||||
|
||||
int third = from_python(keywords[py::String("third")].get(), py::Type<int>());
|
||||
int fourth = from_python(keywords[py::String("fourth")].get(), py::Type<int>());
|
||||
|
||||
return to_python(first->i_ + second + third + fourth);
|
||||
}
|
||||
|
||||
void init_module()
|
||||
|
||||
27
functions.h
27
functions.h
@@ -75,24 +75,28 @@ struct WrappedFunctionPointer : Function
|
||||
const PtrFun m_pf;
|
||||
};
|
||||
|
||||
// RawArgumentsFunction
|
||||
// raw_arguments_function
|
||||
// A function that passes the Python argument tuple and keyword dictionary
|
||||
// verbatim to C++ (useful for customized argument parsing and variable
|
||||
// argument lists)
|
||||
struct RawArgumentsFunction : Function
|
||||
template <class Ret, class Args, class Keywords>
|
||||
struct raw_arguments_function : Function
|
||||
{
|
||||
typedef PyObject * (*PtrFun)(Tuple const &, Dict const &);
|
||||
typedef Ret (*PtrFun)(Args, Keywords);
|
||||
|
||||
RawArgumentsFunction(PtrFun pf)
|
||||
raw_arguments_function(PtrFun pf)
|
||||
: m_pf(pf) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
return (*m_pf)(Tuple(Ptr(args, Ptr::new_ref)),
|
||||
keywords ?
|
||||
Dict(Ptr(keywords, Ptr::new_ref)) :
|
||||
Dict());
|
||||
Ptr dict(keywords ?
|
||||
Ptr(keywords, Ptr::new_ref) :
|
||||
PyDict_New());
|
||||
|
||||
return to_python(
|
||||
(*m_pf)(from_python(args, py::Type<Args>()),
|
||||
from_python(dict.get(), py::Type<Keywords>())));
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
@@ -155,6 +159,13 @@ inline Function* new_wrapped_function(F pmf)
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <class R, class Args, class Keywords>
|
||||
Function* new_raw_arguments_function(R (*pmf)(Args, Keywords))
|
||||
{
|
||||
return new raw_arguments_function<R, Args, Keywords>(pmf);
|
||||
}
|
||||
|
||||
|
||||
// A helper function for new_virtual_function(), below. Implements the core
|
||||
// functionality once the return type has already been deduced. R is expected to
|
||||
// be Type<X>, where X is the actual return type of V.
|
||||
|
||||
@@ -379,9 +379,12 @@ class ExtensionClass
|
||||
// to C++ verbatim (as a 'Tuple const &' and 'Dict const &'
|
||||
// respectively). This is useful for manual argument passing.
|
||||
// It's also the only possibility to pass keyword arguments to C++.
|
||||
void def_raw(RawArgumentsFunction::PtrFun fn, const char* name)
|
||||
// Fn must have a signatur that is compatible to
|
||||
// PyObject * (*)(PyObject * aTuple, PyObject * aDictionary)
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
this->add_method(new RawArgumentsFunction(fn), name);
|
||||
this->add_method(py::detail::new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
// define member functions. In fact this works for free functions, too -
|
||||
|
||||
@@ -34,11 +34,6 @@ void Module::add(PyTypeObject* x, const char* name /*= 0*/)
|
||||
name ? name : x->tp_name);
|
||||
}
|
||||
|
||||
void Module::def_raw(RawFunctionPtr fn, const char* name)
|
||||
{
|
||||
add(new RawArgumentsFunction(fn), name);
|
||||
}
|
||||
|
||||
PyMethodDef Module::initial_methods[] = { { 0, 0, 0, 0 } };
|
||||
|
||||
}
|
||||
|
||||
6
module.h
6
module.h
@@ -30,7 +30,11 @@ public:
|
||||
|
||||
void add(Ptr x, const char*name);
|
||||
|
||||
void def_raw(RawFunctionPtr fn, const char* name);
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
add(py::detail::new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
void def(Fn fn, const char* name)
|
||||
|
||||
4
pyptr.h
4
pyptr.h
@@ -28,10 +28,10 @@ template <class T, class Base>
|
||||
struct PyPtrConversions : Base
|
||||
{
|
||||
inline friend T from_python(PyObject* x, py::Type<const T&>)
|
||||
{ return T(py::Downcast<T::value_type>(x).get(), T::new_ref); }
|
||||
{ return T(py::Downcast<typename T::value_type>(x).get(), T::new_ref); }
|
||||
|
||||
inline friend T from_python(PyObject* x, py::Type<T>)
|
||||
{ return T(py::Downcast<T::value_type>(x).get(), T::new_ref); }
|
||||
{ return T(py::Downcast<typename T::value_type>(x).get(), T::new_ref); }
|
||||
|
||||
inline friend PyObject* to_python(T x)
|
||||
{ return py::as_object(x.release()); }
|
||||
|
||||
@@ -858,6 +858,25 @@ test inheritB2
|
||||
>>> raw(r,1)
|
||||
Traceback (innermost last):
|
||||
TypeError: wrong number of arguments
|
||||
>>> raw()
|
||||
Traceback (innermost last):
|
||||
TypeError: wrong number of arguments
|
||||
>>> raw1(1,second=1)
|
||||
2
|
||||
>>> raw1(1)
|
||||
1
|
||||
>>> raw1(second=1)
|
||||
1
|
||||
>>> raw1()
|
||||
0
|
||||
>>> raw2(1,second=1)
|
||||
2
|
||||
>>> raw2(1)
|
||||
1
|
||||
>>> raw2(second=1)
|
||||
1
|
||||
>>> raw2()
|
||||
0
|
||||
|
||||
|
||||
========= Prove that the "phantom base class" issue is resolved ==========
|
||||
|
||||
Reference in New Issue
Block a user