mirror of
https://github.com/boostorg/python.git
synced 2026-01-25 06:22:15 +00:00
Misc comments from Dave
[SVN r14815]
This commit is contained in:
@@ -131,17 +131,33 @@ class class_ : public objects::class_base
|
||||
return this->def(op.name(), &op_t::template apply<T>::execute);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedT, typename SigT>
|
||||
self& def(detail::func_stubs_base<DerivedT> const& stubs, signature<SigT> sig)
|
||||
self& def_generator(
|
||||
char const* name,
|
||||
detail::func_stubs_base<DerivedT> const& stubs,
|
||||
SigT sig, char const* doc = 0)
|
||||
{
|
||||
// convert sig to a type_list (see signature.hpp) and call
|
||||
// detail::define_with_defaults passing in the stubs (see defaults_gen.hpp),
|
||||
// this instance, and the converted sig type_list.
|
||||
detail::define_with_defaults(stubs.derived(), *this, detail::get_signature(sig));
|
||||
// convert sig to a type_list (see detail::get_signature in signature.hpp) and
|
||||
// call detail::define_with_defaults passing in the stubs (see defaults_gen.hpp),
|
||||
// this class_ instance, and the converted sig type_list.
|
||||
detail::define_with_defaults(name, stubs.derived(), *this, detail::get_signature(sig), doc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// template <typename DerivedT, typename F>
|
||||
// self& def(detail::func_stubs_base<DerivedT> const& stubs, F)
|
||||
// {
|
||||
// // convert signature<F> to a type_list (see signature.hpp) and call
|
||||
// // detail::define_with_defaults passing in the stubs (see defaults_gen.hpp),
|
||||
// // this class_ instance, and the converted signature<F> type_list.
|
||||
// detail::define_with_defaults(
|
||||
// stubs.derived(),
|
||||
// *this,
|
||||
// detail::get_signature(signature<F>())
|
||||
// );
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
// Define the constructor with the given Args, which should be an
|
||||
// MPL sequence of types.
|
||||
template <class Args>
|
||||
|
||||
@@ -37,11 +37,12 @@ namespace detail {
|
||||
//
|
||||
// The set of overloaded functions (define_stub_function) expects:
|
||||
//
|
||||
// 1. char const* name: a python function name
|
||||
// 1. char const* name: function name that will be visible to python
|
||||
// 2. StubsT: a function stubs struct (see defaults_gen.hpp)
|
||||
// 3. HolderT& holder: a python::class_ or python::module instance
|
||||
// 4. int_t<N>: the Nth overloaded function (StubsT::func_N)
|
||||
// (see defaults_gen.hpp)
|
||||
// 5. char const* name: doc string
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BPL_IMPL_STUB_FUNC_DEF(INDEX, DATA) \
|
||||
@@ -53,10 +54,15 @@ namespace detail {
|
||||
char const* name, \
|
||||
StubsT, \
|
||||
HolderT& holder, \
|
||||
boost::mpl::int_t<INDEX> \
|
||||
boost::mpl::int_t<INDEX>, \
|
||||
char const* doc \
|
||||
) \
|
||||
{ \
|
||||
holder.def(name, &StubsT::BOOST_PP_CAT(func_, INDEX)); \
|
||||
holder.def( \
|
||||
name, \
|
||||
&StubsT::BOOST_PP_CAT(func_, INDEX), \
|
||||
default_call_policies(), \
|
||||
doc); \
|
||||
} \
|
||||
|
||||
BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY)
|
||||
@@ -71,9 +77,10 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY)
|
||||
// terminal case define_with_defaults_helper<0>. The struct and its
|
||||
// specialization has a sole static member function def that expects:
|
||||
//
|
||||
// 1. char const* name: a python function name
|
||||
// 1. char const* name: function name that will be visible to python
|
||||
// 2. StubsT: a function stubs struct (see defaults_gen.hpp)
|
||||
// 3. HolderT& holder: a python::class_ or python::module instance
|
||||
// 4. char const* name: doc string
|
||||
//
|
||||
// The def static member function calls a corresponding
|
||||
// define_stub_function<N>. The general case recursively calls
|
||||
@@ -86,12 +93,12 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY)
|
||||
|
||||
template <typename StubsT, typename HolderT>
|
||||
static void
|
||||
def(char const* name, StubsT stubs, HolderT& holder)
|
||||
def(char const* name, StubsT stubs, HolderT& holder, char const* doc)
|
||||
{
|
||||
// define the NTH stub function of stubs
|
||||
define_stub_function(name, stubs, holder, boost::mpl::int_t<N>());
|
||||
define_stub_function(name, stubs, holder, boost::mpl::int_t<N>(), doc);
|
||||
// call the next define_with_defaults_helper
|
||||
define_with_defaults_helper<N-1>::def(name, stubs, holder);
|
||||
define_with_defaults_helper<N-1>::def(name, stubs, holder, doc);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,10 +108,10 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY)
|
||||
|
||||
template <typename StubsT, typename HolderT>
|
||||
static void
|
||||
def(char const* name, StubsT stubs, HolderT& holder)
|
||||
def(char const* name, StubsT stubs, HolderT& holder, char const* doc)
|
||||
{
|
||||
// define the Oth stub function of stubs
|
||||
define_stub_function(name, stubs, holder, boost::mpl::int_t<0>());
|
||||
define_stub_function(name, stubs, holder, boost::mpl::int_t<0>(), doc);
|
||||
// return
|
||||
}
|
||||
};
|
||||
@@ -113,6 +120,12 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY)
|
||||
//
|
||||
// define_with_defaults
|
||||
//
|
||||
// 1. char const* name: function name that will be visible to python
|
||||
// 2. StubsT: a function stubs struct (see defaults_gen.hpp)
|
||||
// 3. HolderT& holder: a python::class_ or python::module instance
|
||||
// 4. SigT sig: Function signature typelist (see defaults_gen.hpp)
|
||||
// 5. char const* name: doc string
|
||||
//
|
||||
// This is the main entry point. This function recursively defines all
|
||||
// stub functions of StubT (see defaults_gen.hpp) in HolderT holder which
|
||||
// can be either a python::class_ or a python::module. The sig argument
|
||||
@@ -126,7 +139,12 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename StubsT, typename HolderT, typename SigT>
|
||||
inline void
|
||||
define_with_defaults(StubsT, HolderT& holder, SigT sig)
|
||||
define_with_defaults(
|
||||
char const* name,
|
||||
StubsT,
|
||||
HolderT& holder,
|
||||
SigT sig,
|
||||
char const* doc)
|
||||
{
|
||||
typedef typename mpl::select_type
|
||||
<
|
||||
@@ -137,11 +155,11 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY)
|
||||
::type stubs_type;
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(stubs_type::max_args + 1) == boost::mpl::size<SigT>::value);
|
||||
(stubs_type::max_args + 1) <= boost::mpl::size<SigT>::value);
|
||||
|
||||
typedef stubs_type::template gen<SigT> gen_type;
|
||||
define_with_defaults_helper<stubs_type::n_funcs-1>::def
|
||||
(stubs_type::name(), gen_type(), holder);
|
||||
(name, gen_type(), holder, doc);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -99,9 +99,6 @@ struct func_stubs_base {
|
||||
BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(N_DFLTS)); \
|
||||
BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \
|
||||
\
|
||||
static char const* \
|
||||
name() { return BOOST_PP_STRINGIZE(FNAME); } \
|
||||
\
|
||||
template <typename SigT> \
|
||||
struct gen { \
|
||||
\
|
||||
@@ -153,9 +150,6 @@ struct func_stubs_base {
|
||||
BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(N_DFLTS)); \
|
||||
BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \
|
||||
\
|
||||
static char const* \
|
||||
name() { return BOOST_PP_STRINGIZE(FNAME); } \
|
||||
\
|
||||
template <typename SigT> \
|
||||
struct gen { \
|
||||
\
|
||||
@@ -267,8 +261,6 @@ struct func_stubs_base {
|
||||
// static const int n_funcs = 4;
|
||||
// static const int max_args = n_funcs;
|
||||
//
|
||||
// static char const* name() { return "foo"; }
|
||||
//
|
||||
// template <typename SigT>
|
||||
// struct gen {
|
||||
//
|
||||
|
||||
@@ -72,12 +72,15 @@ class module : public detail::module_base
|
||||
}
|
||||
|
||||
template <typename DerivedT, typename SigT>
|
||||
module& def(detail::func_stubs_base<DerivedT> const& stubs, signature<SigT> sig)
|
||||
module& def_generator(
|
||||
char const* name,
|
||||
detail::func_stubs_base<DerivedT> const& stubs,
|
||||
SigT sig, char const* doc = 0)
|
||||
{
|
||||
// convert sig to a type_list (see signature.hpp) and call
|
||||
// detail::define_with_defaults passing in the stubs (see defaults_gen.hpp),
|
||||
// this instance, and the converted sig type_list.
|
||||
detail::define_with_defaults(stubs.derived(), *this, detail::get_signature(sig));
|
||||
// convert sig to a type_list (see detail::get_signature in signature.hpp) and
|
||||
// call detail::define_with_defaults passing in the stubs (see defaults_gen.hpp),
|
||||
// this module instance, and the converted sig type_list.
|
||||
detail::define_with_defaults(name, stubs.derived(), *this, detail::get_signature(sig), doc);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -59,6 +59,13 @@ namespace detail {
|
||||
// return boost::mpl::type_list<RT, T0...TN>();
|
||||
// }
|
||||
//
|
||||
// template <typename RT, typename T0... typename TN>
|
||||
// inline boost::mpl::type_list<RT, T0...TN>
|
||||
// get_signature(RT(*)(T0...TN))
|
||||
// {
|
||||
// return boost::mpl::type_list<RT, T0...TN>();
|
||||
// }
|
||||
//
|
||||
// template <typename RT, typename ClassT, typename T0... typename TN>
|
||||
// inline boost::mpl::type_list<RT, ClassT, T0...TN>
|
||||
// get_signature(signature<RT(ClassT::*)(T0...TN))>)
|
||||
@@ -66,6 +73,20 @@ namespace detail {
|
||||
// return boost::mpl::type_list<RT, ClassT, T0...TN>();
|
||||
// }
|
||||
//
|
||||
// template <typename RT, typename ClassT, typename T0... typename TN>
|
||||
// inline boost::mpl::type_list<RT, ClassT, T0...TN>
|
||||
// get_signature(RT(ClassT::*)(T0...TN)))
|
||||
// {
|
||||
// return boost::mpl::type_list<RT, ClassT, T0...TN>();
|
||||
// }
|
||||
//
|
||||
// template <typename RT, typename ClassT, typename T0... typename TN>
|
||||
// inline boost::mpl::type_list<RT, ClassT, T0...TN>
|
||||
// get_signature(RT(ClassT::*)(T0...TN) const))
|
||||
// {
|
||||
// return boost::mpl::type_list<RT, ClassT const, T0...TN>();
|
||||
// }
|
||||
//
|
||||
// These functions extract the return type, class (for member functions)
|
||||
// and arguments of the input signature and stuffs them in an mpl::type_list.
|
||||
//
|
||||
@@ -90,6 +111,26 @@ namespace detail {
|
||||
RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \
|
||||
> \
|
||||
get_signature(signature<RT(*)(BOOST_PP_ENUM_PARAMS(INDEX, T))>) \
|
||||
{ \
|
||||
return boost::mpl::type_list \
|
||||
<RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T)>(); \
|
||||
} \
|
||||
\
|
||||
template \
|
||||
< \
|
||||
typename RT BOOST_PP_COMMA_IF(INDEX) \
|
||||
BOOST_PP_ENUM \
|
||||
( \
|
||||
INDEX, \
|
||||
BPL_IMPL_TEMPLATE_GEN, \
|
||||
BOOST_PP_EMPTY \
|
||||
) \
|
||||
> \
|
||||
inline boost::mpl::type_list \
|
||||
< \
|
||||
RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \
|
||||
> \
|
||||
get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \
|
||||
{ \
|
||||
return boost::mpl::type_list \
|
||||
<RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T)>(); \
|
||||
@@ -117,6 +158,51 @@ namespace detail {
|
||||
return boost::mpl::type_list \
|
||||
<RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T)>\
|
||||
(); \
|
||||
} \
|
||||
\
|
||||
template \
|
||||
< \
|
||||
typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \
|
||||
BOOST_PP_ENUM \
|
||||
( \
|
||||
INDEX, \
|
||||
BPL_IMPL_TEMPLATE_GEN, \
|
||||
BOOST_PP_EMPTY \
|
||||
) \
|
||||
> \
|
||||
inline boost::mpl::type_list \
|
||||
< \
|
||||
RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \
|
||||
> \
|
||||
get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \
|
||||
{ \
|
||||
return boost::mpl::type_list \
|
||||
<RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T)>\
|
||||
(); \
|
||||
} \
|
||||
\
|
||||
template \
|
||||
< \
|
||||
typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \
|
||||
BOOST_PP_ENUM \
|
||||
( \
|
||||
INDEX, \
|
||||
BPL_IMPL_TEMPLATE_GEN, \
|
||||
BOOST_PP_EMPTY \
|
||||
) \
|
||||
> \
|
||||
inline boost::mpl::type_list \
|
||||
< \
|
||||
RT, ClassT const \
|
||||
BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \
|
||||
> \
|
||||
get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T)) const) \
|
||||
{ \
|
||||
return boost::mpl::type_list \
|
||||
< \
|
||||
RT, ClassT const \
|
||||
BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \
|
||||
>(); \
|
||||
} \
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <sstream>
|
||||
#include <boost/python/list.hpp>
|
||||
|
||||
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
|
||||
# include <iostream> // works around a KCC intermediate code generation bug
|
||||
@@ -15,50 +15,97 @@ using namespace boost::python;
|
||||
using namespace std;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string
|
||||
foo(int a, char b = 'D', std::string c = "default", double d = 0.0)
|
||||
object
|
||||
bar(int a, char b, std::string c, double d)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "int(" << a << "); ";
|
||||
stream << "char(" << b << "); ";
|
||||
stream << "string(" << c << "); ";
|
||||
stream << "double(" << d << "); ";
|
||||
return stream.str();
|
||||
list abcd;
|
||||
abcd.append(a);
|
||||
abcd.append(b);
|
||||
abcd.append(c);
|
||||
abcd.append(d);
|
||||
return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_FUNCTION_GEN(foo_stubs, foo, 1, 4)
|
||||
object
|
||||
bar(int a, char b, std::string c)
|
||||
{
|
||||
list abcd;
|
||||
abcd.append(a);
|
||||
abcd.append(b);
|
||||
abcd.append(c);
|
||||
abcd.append(0.0);
|
||||
return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd);
|
||||
}
|
||||
|
||||
object
|
||||
bar(int a, char b)
|
||||
{
|
||||
list abcd;
|
||||
abcd.append(a);
|
||||
abcd.append(b);
|
||||
abcd.append("default");
|
||||
abcd.append(0.0);
|
||||
return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd);
|
||||
}
|
||||
|
||||
object
|
||||
bar(int a)
|
||||
{
|
||||
list abcd;
|
||||
abcd.append(a);
|
||||
abcd.append('D');
|
||||
abcd.append("default");
|
||||
abcd.append(0.0);
|
||||
return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_FUNCTION_GENERATOR(bar_stubs, bar, 1, 4)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
object
|
||||
foo(int a, char b = 'D', std::string c = "default", double d = 0.0)
|
||||
{
|
||||
list abcd;
|
||||
abcd.append(a);
|
||||
abcd.append(b);
|
||||
abcd.append(c);
|
||||
abcd.append(d);
|
||||
return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct X {
|
||||
|
||||
std::string
|
||||
object
|
||||
bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "int(" << a << "); ";
|
||||
stream << "char(" << b << "); ";
|
||||
stream << "string(" << c << "); ";
|
||||
stream << "double(" << d << "); ";
|
||||
return stream.str();
|
||||
list abcd;
|
||||
abcd.append(a);
|
||||
abcd.append(b);
|
||||
abcd.append(c);
|
||||
abcd.append(d);
|
||||
return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_GEN(X_bar_stubs, bar, 1, 4)
|
||||
BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(defaults_ext)
|
||||
{
|
||||
module m("defaults_ext");
|
||||
m.def(foo_stubs(), signature<std::string(*)(int, char, std::string, double)>());
|
||||
m.def_generator("foo", foo_stubs(), foo);
|
||||
m.def_generator("bar", bar_stubs(), signature<object(*)(int, char, std::string, double)>());
|
||||
|
||||
class_<X> xc("X");
|
||||
m.add(xc);
|
||||
|
||||
xc.def_init();
|
||||
xc.def(X_bar_stubs(), signature<std::string(X::*)(int, char, std::string, double)>());
|
||||
xc.def_generator("bar", X_bar_stubs(), X::bar);
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
"""
|
||||
|
||||
>>> from defaults_ext import *
|
||||
>>> bar(1)
|
||||
'int(1); char(D); string(default); double(0.0); '
|
||||
>>> bar(2, 'X')
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
>>> bar(3, 'Y', "Hello World")
|
||||
'int(3); char(Y); string(Hello World); double(0.0); '
|
||||
>>> bar(4, 'Z', "Hi There", 3.3)
|
||||
'int(4); char(Z); string(Hi There); double(3.3); '
|
||||
>>> foo(1)
|
||||
'int(1); char(D); string(default); double(0); '
|
||||
'int(1); char(D); string(default); double(0.0); '
|
||||
>>> foo(2, 'X')
|
||||
'int(2); char(X); string(default); double(0); '
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
>>> foo(3, 'Y', "Hello World")
|
||||
'int(3); char(Y); string(Hello World); double(0); '
|
||||
'int(3); char(Y); string(Hello World); double(0.0); '
|
||||
>>> foo(4, 'Z', "Hi There", 3.3)
|
||||
'int(4); char(Z); string(Hi There); double(3.3); '
|
||||
>>> x = X()
|
||||
>>> x.bar(1)
|
||||
'int(1); char(D); string(default); double(0); '
|
||||
'int(1); char(D); string(default); double(0.0); '
|
||||
>>> x.bar(2, 'X')
|
||||
'int(2); char(X); string(default); double(0); '
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
>>> x.bar(3, 'Y', "Hello World")
|
||||
'int(3); char(Y); string(Hello World); double(0); '
|
||||
'int(3); char(Y); string(Hello World); double(0.0); '
|
||||
>>> x.bar(4, 'Z', "Hi There", 3.3)
|
||||
'int(4); char(Z); string(Hi There); double(3.3); '
|
||||
>>>
|
||||
|
||||
Reference in New Issue
Block a user