mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 16:32:16 +00:00
Compare commits
11 Commits
tmp
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9743ad0a69 | ||
|
|
432a9b85e7 | ||
|
|
9d51d39d7a | ||
|
|
a33ee22259 | ||
|
|
943b96f902 | ||
|
|
d52bc52515 | ||
|
|
fe19b49273 | ||
|
|
e56f6833e6 | ||
|
|
502e67c114 | ||
|
|
cdf49c6ac0 | ||
|
|
bbc90bcc9c |
@@ -28,16 +28,18 @@
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/object/add_to_namespace.hpp>
|
||||
# include <boost/python/detail/def_helper.hpp>
|
||||
# include <boost/python/detail/defaults_def.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct write_type_id;
|
||||
|
||||
|
||||
template <class T, class Prev = detail::not_specified>
|
||||
struct select_held_type;
|
||||
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
struct has_noncopyable;
|
||||
|
||||
@@ -58,7 +60,10 @@ namespace detail
|
||||
template <class T, class Holder>
|
||||
static inline void register_copy_constructor(mpl::bool_t<false> const&, Holder*, object const&, T* = 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Forward declaration (detail/defaults_def.hpp)
|
||||
struct func_stubs_base;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -79,18 +84,18 @@ class class_ : public objects::class_base
|
||||
|
||||
typedef class_<T,X1,X2,X3> self;
|
||||
BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable<X1,X2,X3>::value));
|
||||
|
||||
|
||||
typedef typename detail::select_held_type<
|
||||
X1, typename detail::select_held_type<
|
||||
X2, typename detail::select_held_type<
|
||||
X3
|
||||
>::type>::type>::type held_type;
|
||||
|
||||
|
||||
public:
|
||||
// Automatically derive the class name - only works on some
|
||||
// compilers because type_info::name is sometimes mangled (gcc)
|
||||
class_();
|
||||
|
||||
|
||||
// Construct with the class name. [ Would have used a default
|
||||
// argument but gcc-2.95.2 choked on typeid(T).name() as a default
|
||||
// parameter value]
|
||||
@@ -107,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;
|
||||
}
|
||||
|
||||
@@ -124,7 +125,7 @@ class class_ : public objects::class_base
|
||||
typedef detail::operator_<id,L,R> op_t;
|
||||
return this->def(op.name(), &op_t::template apply<T>::execute);
|
||||
}
|
||||
|
||||
|
||||
// Define the constructor with the given Args, which should be an
|
||||
// MPL sequence of types.
|
||||
template <class Args>
|
||||
@@ -142,7 +143,7 @@ class class_ : public objects::class_base
|
||||
self& def_init(Args const&, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0)
|
||||
{
|
||||
typedef detail::def_helper<CallPolicyOrDoc> helper;
|
||||
|
||||
|
||||
return this->def(
|
||||
"__init__",
|
||||
python::make_constructor<Args>(
|
||||
@@ -211,7 +212,7 @@ class class_ : public objects::class_base
|
||||
objects::add_to_namespace(
|
||||
*this, name,
|
||||
make_function(
|
||||
// This bit of nastiness casts F to a member function of T if possible.
|
||||
// This bit of nastiness casts F to a member function of T if possible.
|
||||
detail::member_function_cast<T,Fn>::stage1(fn).stage2((T*)0).stage3(fn)
|
||||
, policies)
|
||||
, doc);
|
||||
@@ -224,15 +225,43 @@ 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
|
||||
, typename detail::select_bases<X2
|
||||
, typename boost::python::detail::select_bases<X3>::type
|
||||
>::type
|
||||
>::type bases;
|
||||
|
||||
|
||||
// A helper class which will contain an array of id objects to be
|
||||
// passed to the base class constructor
|
||||
struct id_vector
|
||||
@@ -242,12 +271,12 @@ class class_ : public objects::class_base
|
||||
{
|
||||
// Stick the derived class id into the first element of the array
|
||||
ids[0] = type_id<T>();
|
||||
|
||||
|
||||
// Write the rest of the elements into succeeding positions.
|
||||
class_id* p = ids + 1;
|
||||
mpl::for_each<bases, void, detail::write_type_id>::execute(&p);
|
||||
}
|
||||
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::size_t, size = mpl::size<bases>::value + 1);
|
||||
class_id ids[size];
|
||||
@@ -265,7 +294,7 @@ inline class_<T,X1,X2,X3>::class_()
|
||||
{
|
||||
// register converters
|
||||
objects::register_class_from_python<T,bases>();
|
||||
|
||||
|
||||
detail::register_copy_constructor<T>(
|
||||
mpl::bool_t<is_copyable>()
|
||||
, objects::select_holder<T,held_type>((held_type*)0).get()
|
||||
@@ -278,7 +307,7 @@ inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc)
|
||||
{
|
||||
// register converters
|
||||
objects::register_class_from_python<T,bases>();
|
||||
|
||||
|
||||
detail::register_copy_constructor<T>(
|
||||
mpl::bool_t<is_copyable>()
|
||||
, objects::select_holder<T,held_type>((held_type*)0).get()
|
||||
|
||||
178
include/boost/python/detail/defaults_def.hpp
Normal file
178
include/boost/python/detail/defaults_def.hpp
Normal file
@@ -0,0 +1,178 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright David Abrahams 2002. 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
#ifndef DEFAULTS_DEF_JDG20020811_HPP
|
||||
#define DEFAULTS_DEF_JDG20020811_HPP
|
||||
|
||||
#include <boost/python/detail/defaults_gen.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/mpl/int_t.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This Boost PP code generates expansions for
|
||||
//
|
||||
// template <typename StubsT, typename HolderT>
|
||||
// inline void
|
||||
// define_stub_function(
|
||||
// char const* name, StubsT s, HolderT& holder, boost::mpl::int_t<N>)
|
||||
// {
|
||||
// holder.def(name, &StubsT::func_N);
|
||||
// }
|
||||
//
|
||||
// where N runs from 0 to BOOST_PYTHON_MAX_ARITY
|
||||
//
|
||||
// The set of overloaded functions (define_stub_function) expects:
|
||||
//
|
||||
// 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 BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>))
|
||||
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// define_with_defaults_helper<N>
|
||||
//
|
||||
// This helper template struct does the actual recursive definition.
|
||||
// There's a generic version define_with_defaults_helper<N> and a
|
||||
// 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: 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
|
||||
// define_with_defaults_helper<N-1>::def until it reaches the
|
||||
// terminal case case define_with_defaults_helper<0>.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <int N>
|
||||
struct define_with_defaults_helper {
|
||||
|
||||
template <typename StubsT, typename HolderT>
|
||||
static void
|
||||
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>(), doc);
|
||||
// call the next define_with_defaults_helper
|
||||
define_with_defaults_helper<N-1>::def(name, stubs, holder, doc);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////
|
||||
template <>
|
||||
struct define_with_defaults_helper<0> {
|
||||
|
||||
template <typename StubsT, typename HolderT>
|
||||
static void
|
||||
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>(), doc);
|
||||
// return
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// is a typelist that specifies the return type, the class (for member
|
||||
// functions, and the arguments. Here are some SigT examples:
|
||||
//
|
||||
// int foo(int) mpl::type_list<int, int>
|
||||
// void bar(int, int) mpl::type_list<void, int, int>
|
||||
// void C::foo(int) mpl::type_list<void, C, int>
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename StubsT, typename HolderT, typename SigT>
|
||||
inline void
|
||||
define_with_defaults(
|
||||
char const* name,
|
||||
StubsT,
|
||||
HolderT& holder,
|
||||
SigT sig,
|
||||
char const* doc)
|
||||
{
|
||||
typedef typename mpl::select_type
|
||||
<
|
||||
boost::is_same<void, typename mpl::at<0, SigT>::type>::value,
|
||||
typename StubsT::v_type,
|
||||
typename StubsT::nv_type
|
||||
>
|
||||
::type stubs_type;
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(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
|
||||
(name, gen_type(), holder, doc);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#endif // DEFAULTS_DEF_JDG20020811_HPP
|
||||
|
||||
#else // defined(BOOST_PP_IS_ITERATING)
|
||||
// PP vertical iteration code
|
||||
|
||||
template <typename StubsT, typename HolderT>
|
||||
inline void
|
||||
define_stub_function
|
||||
(
|
||||
char const* name,
|
||||
StubsT,
|
||||
HolderT& holder,
|
||||
boost::mpl::int_t<BOOST_PP_ITERATION()>,
|
||||
char const* doc
|
||||
)
|
||||
{
|
||||
holder.def(
|
||||
name,
|
||||
&StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()),
|
||||
default_call_policies(),
|
||||
doc);
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_PP_IS_ITERATING)
|
||||
305
include/boost/python/detail/defaults_gen.hpp
Normal file
305
include/boost/python/detail/defaults_gen.hpp
Normal file
@@ -0,0 +1,305 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright David Abrahams 2002. 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef DEFAULTS_GEN_JDG20020807_HPP
|
||||
#define DEFAULTS_GEN_JDG20020807_HPP
|
||||
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/enum.hpp>
|
||||
#include <boost/preprocessor/enum_params.hpp>
|
||||
#include <boost/preprocessor/tuple.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/arithmetic/sub.hpp>
|
||||
#include <boost/preprocessor/arithmetic/add.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/inc.hpp>
|
||||
#include <boost/preprocessor/empty.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// func_stubs_base is used as a base class for all function stubs.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct func_stubs_base {};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Temporary BOOST_PP fix before the CVS stabalizes /*$$$ FIX ME $$$*/
|
||||
|
||||
#ifndef BOOST_PP_FIX_REPEAT_2ND
|
||||
#define BOOST_PP_FIX_REPEAT_2ND(c, m, d) /* ... */ \
|
||||
BOOST_PP_CAT(BOOST_PP_R2_, c)(m, d) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BPL_IMPL_TYPEDEF_GEN(INDEX, DATA) \
|
||||
typedef typename boost::mpl::at \
|
||||
< \
|
||||
BOOST_PP_ADD(INDEX, DATA), \
|
||||
SigT \
|
||||
>::type BOOST_PP_CAT(T, INDEX); \
|
||||
|
||||
#define BPL_IMPL_ARGS_GEN(INDEX, DATA) \
|
||||
BOOST_PP_CAT(T, INDEX) BOOST_PP_CAT(arg, INDEX) \
|
||||
|
||||
#define BPL_IMPL_FUNC_WRAPPER_GEN(INDEX, DATA) \
|
||||
static RT BOOST_PP_CAT(func_, INDEX) \
|
||||
( \
|
||||
BOOST_PP_ENUM \
|
||||
( \
|
||||
BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \
|
||||
BPL_IMPL_ARGS_GEN, \
|
||||
BOOST_PP_EMPTY \
|
||||
) \
|
||||
) \
|
||||
{ \
|
||||
BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
|
||||
BOOST_PP_TUPLE_ELEM(3, 0, DATA) \
|
||||
( \
|
||||
BOOST_PP_ENUM_PARAMS \
|
||||
( \
|
||||
BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \
|
||||
arg \
|
||||
) \
|
||||
); \
|
||||
} \
|
||||
|
||||
#define BPL_IMPL_GEN_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \
|
||||
struct FSTUBS_NAME { \
|
||||
\
|
||||
BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(N_DFLTS)); \
|
||||
BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \
|
||||
\
|
||||
template <typename SigT> \
|
||||
struct gen { \
|
||||
\
|
||||
typedef typename boost::mpl::at<0, SigT>::type RT; \
|
||||
\
|
||||
BOOST_PP_FIX_REPEAT_2ND \
|
||||
( \
|
||||
BOOST_PP_INC(N_DFLTS), \
|
||||
BPL_IMPL_TYPEDEF_GEN, \
|
||||
1 \
|
||||
) \
|
||||
\
|
||||
BOOST_PP_FIX_REPEAT_2ND \
|
||||
( \
|
||||
BOOST_PP_INC(N_DFLTS), \
|
||||
BPL_IMPL_FUNC_WRAPPER_GEN, \
|
||||
(FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \
|
||||
) \
|
||||
}; \
|
||||
}; \
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(INDEX, DATA) \
|
||||
static RT BOOST_PP_CAT(func_, INDEX) \
|
||||
( \
|
||||
ClassT& obj, \
|
||||
BOOST_PP_ENUM \
|
||||
( \
|
||||
BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \
|
||||
BPL_IMPL_ARGS_GEN, \
|
||||
BOOST_PP_EMPTY \
|
||||
) \
|
||||
) \
|
||||
{ \
|
||||
BOOST_PP_TUPLE_ELEM(3, 2, DATA) obj. \
|
||||
BOOST_PP_TUPLE_ELEM(3, 0, DATA) \
|
||||
( \
|
||||
BOOST_PP_ENUM_PARAMS \
|
||||
( \
|
||||
BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \
|
||||
arg \
|
||||
) \
|
||||
); \
|
||||
} \
|
||||
|
||||
#define BPL_IMPL_GEN_MEM_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \
|
||||
struct FSTUBS_NAME { \
|
||||
\
|
||||
BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(N_DFLTS)); \
|
||||
BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \
|
||||
\
|
||||
template <typename SigT> \
|
||||
struct gen { \
|
||||
\
|
||||
typedef typename boost::mpl::at<0, SigT>::type RT; \
|
||||
typedef typename boost::mpl::at<1, SigT>::type ClassT; \
|
||||
\
|
||||
BOOST_PP_FIX_REPEAT_2ND \
|
||||
( \
|
||||
BOOST_PP_INC(N_DFLTS), \
|
||||
BPL_IMPL_TYPEDEF_GEN, \
|
||||
2 \
|
||||
) \
|
||||
\
|
||||
BOOST_PP_FIX_REPEAT_2ND \
|
||||
( \
|
||||
BOOST_PP_INC(N_DFLTS), \
|
||||
BPL_IMPL_MEM_FUNC_WRAPPER_GEN, \
|
||||
(FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \
|
||||
) \
|
||||
}; \
|
||||
}; \
|
||||
\
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(BOOST_MSVC)
|
||||
|
||||
#define BPL_IMPL_GEN_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \
|
||||
BPL_IMPL_GEN_FUNCTION \
|
||||
(FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \
|
||||
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 { \
|
||||
\
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \
|
||||
}; \
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BPL_IMPL_GEN_MEM_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \
|
||||
BPL_IMPL_GEN_MEM_FUNCTION \
|
||||
(FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \
|
||||
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 { \
|
||||
\
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \
|
||||
}; \
|
||||
|
||||
#else
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BPL_IMPL_GEN_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \
|
||||
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 { \
|
||||
\
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \
|
||||
}; \
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BPL_IMPL_GEN_MEM_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \
|
||||
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 { \
|
||||
\
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \
|
||||
typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \
|
||||
}; \
|
||||
|
||||
#endif // defined(BOOST_MSVC)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MAIN MACROS
|
||||
//
|
||||
// Given GENERATOR_NAME, FNAME, MIN_ARGS and MAX_ARGS, These macros
|
||||
// generate function stubs that forward to a function or member function
|
||||
// named FNAME. MAX_ARGS is the arity of the function or member function
|
||||
// FNAME. FNAME can have default arguments. MIN_ARGS is the minimum
|
||||
// arity that FNAME can accept.
|
||||
//
|
||||
// There are two versions:
|
||||
//
|
||||
// 1. BOOST_PYTHON_FUNCTION_GENERATOR for free functions
|
||||
// 2. BOOST_PYTHON_MEM_FUN_GENERATOR for member functions.
|
||||
//
|
||||
// For instance, given a function:
|
||||
//
|
||||
// int
|
||||
// foo(int a, char b = 1, unsigned c = 2, double d = 3)
|
||||
// {
|
||||
// return a + b + c + int(d);
|
||||
// }
|
||||
//
|
||||
// The macro invocation:
|
||||
//
|
||||
// BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4)
|
||||
//
|
||||
// Generates this code:
|
||||
//
|
||||
// struct foo_stubs_NV {
|
||||
//
|
||||
// static const int n_funcs = 4;
|
||||
// static const int max_args = n_funcs;
|
||||
//
|
||||
// template <typename SigT>
|
||||
// struct gen {
|
||||
//
|
||||
// typedef typename mpl::at<0, SigT>::type RT;
|
||||
// typedef typename mpl::at<1, SigT>::type T0;
|
||||
// typedef typename mpl::at<2, SigT>::type T1;
|
||||
// typedef typename mpl::at<3, SigT>::type T2;
|
||||
// typedef typename mpl::at<4, SigT>::type T3;
|
||||
//
|
||||
// static RT func_0(T0 arg0)
|
||||
// { return foo(arg0); }
|
||||
//
|
||||
// static RT func_1(T0 arg0, T1 arg1)
|
||||
// { return foo(arg0, arg1); }
|
||||
//
|
||||
// static RT func_2(T0 arg0, T1 arg1, T2 arg2)
|
||||
// { return foo(arg0, arg1, arg2); }
|
||||
//
|
||||
// static RT func_3(T0 arg0, T1 arg1, T2 arg2, T3 arg3)
|
||||
// { return foo(arg0, arg1, arg2, arg3); }
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// struct foo_stubs
|
||||
// : public boost::python::detail::func_stubs_base {
|
||||
//
|
||||
// typedef foo_stubs_NV nv_type;
|
||||
// typedef foo_stubs_NV v_type;
|
||||
// };
|
||||
//
|
||||
// The typedefs nv_type and v_type are used to handle compilers that
|
||||
// do not support void returns. The example above typedefs nv_type
|
||||
// and v_type to foo_stubs_NV. On compilers that do not support
|
||||
// void returns, there are two versions: foo_stubs_NV and foo_stubs_V.
|
||||
// The "V" version is almost identical to the "NV" version except
|
||||
// for the return type (void) and the lack of the return keyword.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PYTHON_FUNCTION_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\
|
||||
BPL_IMPL_GEN_FUNCTION_STUB \
|
||||
( \
|
||||
FNAME, \
|
||||
GENERATOR_NAME, \
|
||||
MAX_ARGS, \
|
||||
BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \
|
||||
) \
|
||||
|
||||
#define BOOST_PYTHON_MEM_FUN_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\
|
||||
BPL_IMPL_GEN_MEM_FUNCTION_STUB \
|
||||
( \
|
||||
FNAME, \
|
||||
GENERATOR_NAME, \
|
||||
MAX_ARGS, \
|
||||
BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \
|
||||
) \
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#endif // DEFAULTS_GEN_JDG20020807_HPP
|
||||
|
||||
|
||||
@@ -14,9 +14,18 @@
|
||||
# include <boost/python/module_init.hpp>
|
||||
# include <boost/python/object_core.hpp>
|
||||
# include <boost/python/detail/def_helper.hpp>
|
||||
# include <boost/python/detail/defaults_def.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Forward declaration (detail/defaults_def.hpp)
|
||||
struct func_stubs_base;
|
||||
|
||||
}
|
||||
|
||||
class module : public detail::module_base
|
||||
{
|
||||
public:
|
||||
@@ -32,34 +41,62 @@ class module : public detail::module_base
|
||||
this->module_base::setattr_doc(name, python::object(x), 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
module& add(type_handle x); // just use the type's name
|
||||
|
||||
|
||||
template <class T1, class T2 , class T3, class T4>
|
||||
module& add(class_<T1,T2,T3,T4> const& c)
|
||||
{
|
||||
this->add_class(type_handle(borrowed((PyTypeObject*)c.ptr())));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class Fn>
|
||||
module& def(char const* name, Fn fn)
|
||||
{
|
||||
this->setattr_doc(
|
||||
name, boost::python::make_function(fn), 0);
|
||||
|
||||
|
||||
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 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
309
include/boost/python/signature.hpp
Normal file
309
include/boost/python/signature.hpp
Normal file
@@ -0,0 +1,309 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright David Abrahams 2002. 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
#ifndef SIGNATURE_JDG20020813_HPP
|
||||
#define SIGNATURE_JDG20020813_HPP
|
||||
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/enum.hpp>
|
||||
#include <boost/preprocessor/enum_params.hpp>
|
||||
#include <boost/preprocessor/empty.hpp>
|
||||
#include <boost/preprocessor/arithmetic/sub.hpp>
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
#include <boost/mpl/type_list.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace python {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// signature
|
||||
//
|
||||
// This template struct acts as a type holder for the signature of a
|
||||
// function or member function. This struct is used to pass in the
|
||||
// return type, class (for member functions) and arguments of a
|
||||
// function or member function. Examples:
|
||||
//
|
||||
// signature<int(*)(int)> int foo(int)
|
||||
// signature<void(*)(int, int)> void foo(int, int)
|
||||
// signature<void(C::*)(int)> void C::foo(int, int)
|
||||
// signature<void(C::*)(int) const> void C::foo(int, int) const
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct signature {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following macros generate expansions for:
|
||||
//
|
||||
// template <typename RT, typename T0... typename TN>
|
||||
// inline boost::mpl::type_list<RT, T0...TN>
|
||||
// get_signature(signature<RT(*)(T0...TN)>)
|
||||
// {
|
||||
// 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))>)
|
||||
// {
|
||||
// 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(signature<RT(ClassT::*)(T0...TN) const)>)
|
||||
// {
|
||||
// return boost::mpl::type_list<RT, ClassT const, 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) typename BOOST_PP_CAT(T, INDEX)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, BOOST_PYTHON_MAX_ARITY-1, <boost/python/signature.hpp>))
|
||||
|
||||
#include BOOST_PP_ITERATE()
|
||||
#undef BPL_IMPL_TEMPLATE_GEN
|
||||
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#endif // SIGNATURE_JDG20020813_HPP
|
||||
|
||||
|
||||
#else // defined(BOOST_PP_IS_ITERATING)
|
||||
// PP vertical iteration code
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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)
|
||||
>();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
#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
|
||||
<
|
||||
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
|
||||
(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)
|
||||
>();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2)
|
||||
|
||||
template
|
||||
<
|
||||
typename RT, typename ClassT 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, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
|
||||
>
|
||||
get_signature
|
||||
(signature<RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))>)
|
||||
{
|
||||
return boost::mpl::type_list
|
||||
<
|
||||
RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)>
|
||||
();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
template
|
||||
<
|
||||
typename RT, typename ClassT 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, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
|
||||
>
|
||||
get_signature
|
||||
(signature<RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const>)
|
||||
{
|
||||
return boost::mpl::type_list
|
||||
<
|
||||
RT, ClassT const
|
||||
BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
|
||||
>();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
template
|
||||
<
|
||||
typename RT, typename ClassT 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, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
|
||||
>
|
||||
get_signature
|
||||
(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)))
|
||||
{
|
||||
return boost::mpl::type_list
|
||||
<
|
||||
RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
|
||||
>();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
template
|
||||
<
|
||||
typename RT, typename ClassT 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, ClassT const
|
||||
BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
|
||||
>
|
||||
get_signature
|
||||
(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const)
|
||||
{
|
||||
return boost::mpl::type_list
|
||||
<
|
||||
RT, ClassT const
|
||||
BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)
|
||||
>();
|
||||
}
|
||||
|
||||
#endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2)
|
||||
|
||||
#endif // !defined(BOOST_PP_IS_ITERATING)
|
||||
11
test/Jamfile
11
test/Jamfile
@@ -14,7 +14,7 @@ local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ;
|
||||
rule bpl-test ( name ? : files * )
|
||||
{
|
||||
files ?= $(name).py $(name).cpp ;
|
||||
|
||||
|
||||
local modules ;
|
||||
local py ;
|
||||
for local f in $(files)
|
||||
@@ -28,7 +28,7 @@ rule bpl-test ( name ? : files * )
|
||||
py = $(f) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
name ?= $(py:S=) ;
|
||||
|
||||
for local f in $(files)
|
||||
@@ -36,11 +36,11 @@ rule bpl-test ( name ? : files * )
|
||||
if $(f:S) != .py
|
||||
{
|
||||
local m = $(f:S=) ;
|
||||
|
||||
|
||||
if $(m) = $(py:S=)
|
||||
{
|
||||
m = $(name) ;
|
||||
|
||||
|
||||
if $(m) = $(py:S=)
|
||||
{
|
||||
m = $(m)_ext ;
|
||||
@@ -50,7 +50,7 @@ rule bpl-test ( name ? : files * )
|
||||
modules += $(m) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boost-python-runtest $(name) : $(py) <pyd>$(modules) ;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters
|
||||
bpl-test test_pointer_adoption ;
|
||||
bpl-test operators ;
|
||||
bpl-test callbacks ;
|
||||
bpl-test defaults_ext : defaults.py defaults.cpp ;
|
||||
|
||||
bpl-test object ;
|
||||
bpl-test list ;
|
||||
|
||||
111
test/defaults.cpp
Normal file
111
test/defaults.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright David Abrahams 2002. 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.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/list.hpp>
|
||||
|
||||
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
|
||||
# include <iostream> // works around a KCC intermediate code generation bug
|
||||
#endif
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace std;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
object
|
||||
bar(int a, char b, std::string c, double d)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
object
|
||||
bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const
|
||||
{
|
||||
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_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(defaults_ext)
|
||||
{
|
||||
module m("defaults_ext");
|
||||
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("bar", X::bar, X_bar_stubs());
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
90
test/defaults.py
Normal file
90
test/defaults.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""
|
||||
|
||||
>>> 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.0); '
|
||||
>>> foo(2, 'X')
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
>>> foo(3, 'Y', "Hello World")
|
||||
'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.0); '
|
||||
>>> x.bar(2, 'X')
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
>>> x.bar(3, 'Y', "Hello World")
|
||||
'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); '
|
||||
>>>
|
||||
|
||||
|
||||
|
||||
"""
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user