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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
<
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user