2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-23 17:52:17 +00:00

module, class_ .def dispatching

[SVN r14963]
This commit is contained in:
Joel de Guzman
2002-08-19 18:46:44 +00:00
parent 432a9b85e7
commit 9743ad0a69
5 changed files with 98 additions and 59 deletions

View File

@@ -63,7 +63,6 @@ namespace detail
}
// Forward declaration (detail/defaults_def.hpp)
template <typename DerivedT>
struct func_stubs_base;
}
@@ -113,14 +112,10 @@ class class_ : public objects::class_base
return *this;
}
template <class Fn, class CallPolicyOrDoc>
self& def(char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0)
template <class Arg1T, class Arg2T>
self& def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0)
{
typedef detail::def_helper<CallPolicyOrDoc> helper;
this->def_impl(
name, fn, helper::get_policy(policy_or_doc), helper::get_doc(policy_or_doc, doc), &fn);
dispatch_def(name, arg1, arg2, doc, &arg2);
return *this;
}
@@ -131,18 +126,6 @@ class class_ : public objects::class_base
return this->def(op.name(), &op_t::template apply<T>::execute);
}
template <typename DerivedT, typename SigT>
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 detail::get_signature in signature.hpp)
// before calling detail::define_with_defaults.
detail::define_with_defaults(name, stubs.derived(), *this, detail::get_signature(sig), doc);
return *this;
}
// Define the constructor with the given Args, which should be an
// MPL sequence of types.
template <class Args>
@@ -242,7 +225,35 @@ class class_ : public objects::class_base
objects::add_to_namespace(*this, name, f, doc);
}
private: // types
template <class Fn, class CallPolicyOrDoc>
void dispatch_def(
char const* name,
Fn fn,
CallPolicyOrDoc const& policy_or_doc,
char const* doc,
void const*)
{
typedef detail::def_helper<CallPolicyOrDoc> helper;
this->def_impl(
name, fn, helper::get_policy(policy_or_doc), helper::get_doc(policy_or_doc, doc), &fn);
}
template <typename StubsT, typename SigT>
void dispatch_def(
char const* name,
SigT sig,
StubsT const& stubs,
char const* doc,
detail::func_stubs_base const*)
{
// convert sig to a type_list (see detail::get_signature in signature.hpp)
// before calling detail::define_with_defaults.
detail::define_with_defaults(name, stubs, *this, detail::get_signature(sig), doc);
}
private: // types
typedef objects::class_id class_id;
typedef typename detail::select_bases<X1

View File

@@ -26,28 +26,10 @@ namespace boost { namespace python { namespace detail {
///////////////////////////////////////////////////////////////////////////////
//
// func_stubs_base is used as a base class for all function
// stubs. This technique uses the "Curiously recurring template
// pattern" to disambiguate function calls. For instance, the
// interface:
//
// template <typename DerivedT>
// void foo(func_stubs_base<DerivedT> const&);
//
// will accept only subclasses of func_stubs_base.
// func_stubs_base is used as a base class for all function stubs.
//
///////////////////////////////////////////////////////////////////////////////
template <typename DerivedT>
struct func_stubs_base {
typedef DerivedT derived_t;
DerivedT& derived()
{ return *static_cast<DerivedT*>(this); }
DerivedT const& derived() const
{ return *static_cast<DerivedT const*>(this); }
};
struct func_stubs_base {};
}}} // namespace boost::python::detail
@@ -182,7 +164,7 @@ struct func_stubs_base {
BPL_IMPL_GEN_FUNCTION \
(FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \
struct FSTUBS_NAME \
: public boost::python::detail::func_stubs_base<FSTUBS_NAME> { \
: public boost::python::detail::func_stubs_base { \
\
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \
@@ -195,7 +177,7 @@ struct func_stubs_base {
BPL_IMPL_GEN_MEM_FUNCTION \
(FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \
struct FSTUBS_NAME \
: public boost::python::detail::func_stubs_base<FSTUBS_NAME> { \
: public boost::python::detail::func_stubs_base { \
\
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \
@@ -208,7 +190,7 @@ struct func_stubs_base {
BPL_IMPL_GEN_FUNCTION \
(FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \
struct FSTUBS_NAME \
: public boost::python::detail::func_stubs_base<FSTUBS_NAME> { \
: public boost::python::detail::func_stubs_base { \
\
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \
@@ -219,7 +201,7 @@ struct func_stubs_base {
BPL_IMPL_GEN_MEM_FUNCTION \
(FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \
struct FSTUBS_NAME \
: public boost::python::detail::func_stubs_base<FSTUBS_NAME> { \
: public boost::python::detail::func_stubs_base { \
\
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \
@@ -285,7 +267,7 @@ struct func_stubs_base {
// };
//
// struct foo_stubs
// : public boost::python::detail::func_stubs_base<foo_stubs> {
// : public boost::python::detail::func_stubs_base {
//
// typedef foo_stubs_NV nv_type;
// typedef foo_stubs_NV v_type;

View File

@@ -22,8 +22,8 @@ namespace boost { namespace python {
namespace detail
{
// Forward declaration (detail/defaults_def.hpp)
template <typename DerivedT>
struct func_stubs_base;
}
class module : public detail::module_base
@@ -59,28 +59,44 @@ class module : public detail::module_base
return *this;
}
template <class Arg1T, class Arg2T>
module& def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0)
{
dispatch_def(name, arg1, arg2, doc, &arg2);
return *this;
}
private:
template <class Fn, class CallPolicyOrDoc>
module& def(char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0)
void
dispatch_def(
char const* name,
Fn fn,
CallPolicyOrDoc const& policy_or_doc,
char const* doc,
void const*)
{
typedef detail::def_helper<CallPolicyOrDoc> helper;
this->setattr_doc(
name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)),
helper::get_doc(policy_or_doc, doc));
return *this;
}
template <typename DerivedT, typename SigT>
module& def_generator(
template <typename StubsT, typename SigT>
void
dispatch_def(
char const* name,
detail::func_stubs_base<DerivedT> const& stubs,
SigT sig, char const* doc = 0)
SigT sig,
StubsT const& stubs,
char const* doc,
detail::func_stubs_base const*)
{
// convert sig to a type_list (see detail::get_signature in signature.hpp)
// before calling detail::define_with_defaults.
detail::define_with_defaults(name, stubs.derived(), *this, detail::get_signature(sig), doc);
return *this;
detail::define_with_defaults(name, stubs, *this, detail::get_signature(sig), doc);
}
};

View File

@@ -139,6 +139,36 @@ get_signature
>();
}
///////////////////////////////////////
#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300))
template
<
typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM
(
BOOST_PP_ITERATION(),
BPL_IMPL_TEMPLATE_GEN,
BOOST_PP_EMPTY
)
>
inline boost::mpl::type_list
<
RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
>
get_signature
(signature<RT(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))>)
{
return boost::mpl::type_list
<
RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
>();
}
#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300))
///////////////////////////////////////
template
<

View File

@@ -98,14 +98,14 @@ BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4)
BOOST_PYTHON_MODULE_INIT(defaults_ext)
{
module m("defaults_ext");
m.def_generator("foo", foo_stubs(), foo);
m.def_generator("bar", bar_stubs(), signature<object(*)(int, char, std::string, double)>());
m.def("foo", foo, foo_stubs());
m.def("bar", signature<object(*)(int, char, std::string, double)>(), bar_stubs());
class_<X> xc("X");
m.add(xc);
xc.def_init();
xc.def_generator("bar", X_bar_stubs(), X::bar);
xc.def("bar", X::bar, X_bar_stubs());
}
#include "module_tail.cpp"