mirror of
https://github.com/boostorg/python.git
synced 2026-01-21 17:12:22 +00:00
Keyword argument support
[SVN r15533]
This commit is contained in:
@@ -3,33 +3,117 @@
|
||||
// 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 ARGS_DWA2002323_HPP
|
||||
# define ARGS_DWA2002323_HPP
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
#ifndef KEYWORDS_DWA2002323_HPP
|
||||
# define KEYWORDS_DWA2002323_HPP
|
||||
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
|
||||
# include <boost/type_traits/is_reference.hpp>
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
# include <boost/preprocessor/facilities/intercept.hpp>
|
||||
# include <boost/preprocessor/iteration/local.hpp>
|
||||
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
# include <boost/mpl/bool_c.hpp>
|
||||
|
||||
# include <boost/type.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
enum no_init_t { no_init };
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Args>
|
||||
struct args_base {};
|
||||
struct keyword
|
||||
{
|
||||
char const* name;
|
||||
handle<> default_value;
|
||||
};
|
||||
|
||||
template <std::size_t nkeywords>
|
||||
struct keywords
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
|
||||
|
||||
keyword_range range() const
|
||||
{
|
||||
return keyword_range(elements, elements + nkeywords);
|
||||
}
|
||||
|
||||
keyword elements[nkeywords];
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
struct is_keywords
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template<std::size_t nkeywords>
|
||||
struct is_keywords<keywords<nkeywords> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template <class T>
|
||||
struct is_reference_to_keywords
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
|
||||
typedef typename remove_reference<T>::type deref;
|
||||
typedef typename remove_cv<deref>::type key_t;
|
||||
BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
|
||||
|
||||
typedef mpl::bool_c<value> type;
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
|
||||
};
|
||||
# else
|
||||
typedef char (&yes_keywords_t)[1];
|
||||
typedef char (&no_keywords_t)[2];
|
||||
|
||||
no_keywords_t is_keywords_test(...);
|
||||
|
||||
template<std::size_t nkeywords>
|
||||
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords>&));
|
||||
|
||||
template<std::size_t nkeywords>
|
||||
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords> const&));
|
||||
|
||||
template<typename T>
|
||||
class is_reference_to_keywords
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_keywords_test( (void (*)(T))0 ))
|
||||
== sizeof(detail::yes_keywords_t)));
|
||||
|
||||
typedef mpl::bool_c<value> type;
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
|
||||
};
|
||||
# endif
|
||||
}
|
||||
}}
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// A type list for specifying arguments
|
||||
template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, mpl::void_) >
|
||||
struct args : detail::args_base<args<BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_ARITY, A)> >
|
||||
, detail::type_list< BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_ARITY, A) >::type
|
||||
{};
|
||||
# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
|
||||
# define BOOST_PP_LOCAL_MACRO(n) \
|
||||
inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
|
||||
{ \
|
||||
detail::keywords<n> result; \
|
||||
BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
|
||||
return result; \
|
||||
}
|
||||
# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY)
|
||||
# include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
|
||||
# endif // ARGS_DWA2002323_HPP
|
||||
# endif // KEYWORDS_DWA2002323_HPP
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
# include <boost/python/detail/defaults_def.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
# include <boost/python/init.hpp>
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
@@ -120,8 +121,9 @@ template <
|
||||
class class_ : public objects::class_base
|
||||
{
|
||||
public: // types
|
||||
typedef objects::class_base base;
|
||||
|
||||
typedef objects::class_base base;
|
||||
typedef T wrapped_type;
|
||||
|
||||
typedef class_<T,X1,X2,X3> self;
|
||||
BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable<X1,X2,X3>::value));
|
||||
|
||||
@@ -201,7 +203,7 @@ class class_ : public objects::class_base
|
||||
template <class F>
|
||||
self& def(char const* name, F f)
|
||||
{
|
||||
this->def_impl(name, f, default_call_policies(), 0, &f);
|
||||
this->def_impl(name, f, detail::keywords<>(), default_call_policies(), 0, &f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -236,6 +238,13 @@ class class_ : public objects::class_base
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Arg1T, class Arg2T, class Arg3T, class Arg4T>
|
||||
self& def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3, Arg4T const& arg4)
|
||||
{
|
||||
dispatch_def(&arg2, name, arg1, arg2, arg3, arg4);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <detail::operator_id id, class L, class R>
|
||||
self& def(detail::operator_<id,L,R> const& op)
|
||||
{
|
||||
@@ -297,22 +306,32 @@ class class_ : public objects::class_base
|
||||
|
||||
private: // helper functions
|
||||
|
||||
template <class Fn, class Policies>
|
||||
inline void def_impl(char const* name, Fn fn, Policies const& policies
|
||||
, char const* doc, ...)
|
||||
template <class Fn, class Policies, class Keywords>
|
||||
inline void def_impl(
|
||||
char const* name
|
||||
, Fn fn
|
||||
, Keywords const& keywords
|
||||
, Policies const& policies
|
||||
, char const* doc
|
||||
, ...)
|
||||
{
|
||||
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)
|
||||
, policies, keywords)
|
||||
, doc);
|
||||
}
|
||||
|
||||
template <class F>
|
||||
inline void def_impl(char const* name, F f, default_call_policies const&
|
||||
, char const* doc, object const*)
|
||||
inline void def_impl(
|
||||
char const* name
|
||||
, F f
|
||||
, detail::keywords<> const&
|
||||
, default_call_policies const&
|
||||
, char const* doc
|
||||
, object const*)
|
||||
{
|
||||
objects::add_to_namespace(*this, name, f, doc);
|
||||
}
|
||||
@@ -332,33 +351,60 @@ class class_ : public objects::class_base
|
||||
name, overloads, *this, detail::get_signature(sig));
|
||||
}
|
||||
|
||||
template <class Fn, class CallPolicyOrDoc>
|
||||
template <class Fn, class A1>
|
||||
void dispatch_def(
|
||||
void const*,
|
||||
char const* name,
|
||||
Fn fn,
|
||||
CallPolicyOrDoc const& policy_or_doc)
|
||||
A1 const& a1)
|
||||
{
|
||||
typedef detail::def_helper<CallPolicyOrDoc> helper;
|
||||
detail::def_helper<A1> helper(a1);
|
||||
|
||||
this->def_impl(
|
||||
name, fn, helper::get_policy(policy_or_doc),
|
||||
helper::get_doc(policy_or_doc, 0), &fn);
|
||||
name, fn
|
||||
, helper.keywords()
|
||||
, helper.policies()
|
||||
, helper.doc()
|
||||
, &fn);
|
||||
|
||||
}
|
||||
|
||||
template <class Fn, class CallPolicyOrDoc1, class CallPolicyOrDoc2>
|
||||
template <class Fn, class A1, class A2>
|
||||
void dispatch_def(
|
||||
void const*,
|
||||
char const* name,
|
||||
Fn fn,
|
||||
CallPolicyOrDoc1 const& policy_or_doc1,
|
||||
CallPolicyOrDoc2 const& policy_or_doc2)
|
||||
A1 const& a1,
|
||||
A2 const& a2)
|
||||
{
|
||||
typedef detail::def_helper<CallPolicyOrDoc1> helper;
|
||||
|
||||
detail::def_helper<A1,A2> helper(a1,a2);
|
||||
|
||||
this->def_impl(
|
||||
name, fn, helper::get_policy(policy_or_doc1, policy_or_doc2),
|
||||
helper::get_doc(policy_or_doc1, policy_or_doc2), &fn);
|
||||
name, fn
|
||||
, helper.keywords()
|
||||
, helper.policies()
|
||||
, helper.doc()
|
||||
, &fn);
|
||||
}
|
||||
|
||||
template <class Fn, class A1, class A2, class A3>
|
||||
void dispatch_def(
|
||||
void const*,
|
||||
char const* name,
|
||||
Fn fn,
|
||||
A1 const& a1,
|
||||
A2 const& a2,
|
||||
A3 const& a3
|
||||
)
|
||||
{
|
||||
detail::def_helper<A1,A2,A3> helper(a1,a2,a3);
|
||||
|
||||
this->def_impl(
|
||||
name, fn
|
||||
, helper.keywords()
|
||||
, helper.policies()
|
||||
, helper.doc()
|
||||
, &fn);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -12,43 +12,49 @@
|
||||
# include <boost/python/detail/defaults_def.hpp>
|
||||
# include <boost/python/scope.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
# include <boost/python/detail/scope.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc);
|
||||
|
||||
template <class Fn, class CallPolicyOrDoc>
|
||||
template <class Fn, class A1>
|
||||
void
|
||||
dispatch_def(
|
||||
void const*,
|
||||
char const* name,
|
||||
Fn fn,
|
||||
CallPolicyOrDoc const& policy_or_doc)
|
||||
A1 const& a1)
|
||||
{
|
||||
typedef detail::def_helper<CallPolicyOrDoc> helper;
|
||||
|
||||
def_helper<A1> helper(a1);
|
||||
|
||||
detail::scope_setattr_doc(
|
||||
name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)),
|
||||
helper::get_doc(policy_or_doc, 0));
|
||||
name, boost::python::make_function(
|
||||
fn
|
||||
, helper.policies()
|
||||
, helper.keywords())
|
||||
, helper.doc()
|
||||
);
|
||||
}
|
||||
|
||||
template <class Fn, class CallPolicyOrDoc1, class CallPolicyOrDoc2>
|
||||
template <class Fn, class A1, class A2>
|
||||
void dispatch_def(
|
||||
void const*,
|
||||
char const* name,
|
||||
Fn fn,
|
||||
CallPolicyOrDoc1 const& policy_or_doc1,
|
||||
CallPolicyOrDoc2 const& policy_or_doc2)
|
||||
A1 const& a1,
|
||||
A2 const& a2)
|
||||
{
|
||||
typedef detail::def_helper<CallPolicyOrDoc1> helper;
|
||||
def_helper<A1,A2> helper(a1,a2);
|
||||
|
||||
detail::scope_setattr_doc(
|
||||
name, boost::python::make_function(
|
||||
fn, helper::get_policy(policy_or_doc1, policy_or_doc2)),
|
||||
helper::get_doc(policy_or_doc1, policy_or_doc2));
|
||||
}
|
||||
name, python::make_function(
|
||||
fn
|
||||
, helper.policies()
|
||||
, helper.keywords())
|
||||
, helper.doc()
|
||||
);
|
||||
}
|
||||
|
||||
template <class StubsT, class SigT>
|
||||
void dispatch_def(
|
||||
@@ -87,22 +93,22 @@ void def(char const* name, Arg1T arg1, Arg2T const& arg2)
|
||||
template <class Arg1T, class Arg2T, class Arg3T>
|
||||
void def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3)
|
||||
{
|
||||
// The arguments are definitely:
|
||||
// def(name, function, policy, doc_string) // TODO: exchange policy, doc_string position
|
||||
|
||||
detail::dispatch_def(&arg2, name, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
//template <class Arg1T, class Arg2T, class Arg3T>
|
||||
//void def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3, char const* doc)
|
||||
//{
|
||||
// // The arguments are definitely:
|
||||
// // arg1: signature
|
||||
// // arg2: stubs
|
||||
// // arg3: policy
|
||||
//
|
||||
// detail::dispatch_def(&arg2, name, arg1, arg2, arg3, doc);
|
||||
//}
|
||||
template <class F, class A1, class A2, class A3>
|
||||
void def(char const* name, F f, A1 const& a1, A2 const& a2, A3 const& a3)
|
||||
{
|
||||
detail::def_helper<A1,A2,A3> helper(a1,a2,a3);
|
||||
|
||||
detail::scope_setattr_doc(
|
||||
name, python::make_function(
|
||||
f
|
||||
, helper.policies()
|
||||
, helper.keywords())
|
||||
, helper.doc()
|
||||
);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
|
||||
@@ -6,72 +6,146 @@
|
||||
#ifndef DEF_HELPER_DWA200287_HPP
|
||||
# define DEF_HELPER_DWA200287_HPP
|
||||
|
||||
# include <boost/python/args.hpp>
|
||||
# include <boost/type_traits/ice.hpp>
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/python/detail/string_literal.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/logical/not.hpp>
|
||||
# include <boost/mpl/logical/and.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# include <boost/mpl/lambda.hpp>
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/tuple/tuple.hpp>
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
namespace boost { namespace python {
|
||||
|
||||
//
|
||||
// def_helper<T> --
|
||||
//
|
||||
// A helper for def() functions which determines how to interpret
|
||||
// an argument of type T which could be either CallPolicies or a
|
||||
// string literal representing a docstring.
|
||||
//
|
||||
// Generates two static functions:
|
||||
//
|
||||
// get_policy(x), where x is of type T, returns a policies
|
||||
// object: either a reference to x or default_call_policies()
|
||||
// if x is a string literal.
|
||||
//
|
||||
// get_doc(x, s), where s convertible to char const*, returns x
|
||||
// if x is a string literal, s otherwise.
|
||||
struct default_call_policies;
|
||||
|
||||
template <bool is_string = false>
|
||||
struct def_helper_impl
|
||||
namespace detail
|
||||
{
|
||||
template <class P>
|
||||
static P const&
|
||||
get_policy(P const& x) { return x; }
|
||||
|
||||
template <class P1, class P2>
|
||||
static P1 const&
|
||||
get_policy(P1 const& x, P2 const&) { return x; } // select left
|
||||
|
||||
template <class P>
|
||||
static char const*
|
||||
get_doc(P const&, char const* doc) { return doc; } // select right
|
||||
};
|
||||
|
||||
template <>
|
||||
struct def_helper_impl<true>
|
||||
{
|
||||
static python::default_call_policies
|
||||
get_policy(char const*)
|
||||
{ return default_call_policies(); }
|
||||
|
||||
template <class P1, class P2>
|
||||
static P2 const&
|
||||
get_policy(P1 const&, P2 const& y) { return y; } // select right
|
||||
|
||||
template <class P>
|
||||
static char const*
|
||||
get_doc(char const* doc, P const&) // select left
|
||||
{ return doc; }
|
||||
};
|
||||
template <class Tuple, class Predicate>
|
||||
struct tuple_extract;
|
||||
|
||||
template <class T>
|
||||
struct def_helper
|
||||
: def_helper_impl<
|
||||
type_traits::ice_or<
|
||||
is_string_literal<T const>::value
|
||||
, is_same<T, char const*>::value
|
||||
, is_same<T, char*>::value
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
template <bool matched>
|
||||
struct tuple_extract_impl
|
||||
{
|
||||
template <class Tuple, class Predicate>
|
||||
struct apply
|
||||
{
|
||||
typedef typename Tuple::head_type result_type;
|
||||
|
||||
static typename Tuple::head_type extract(Tuple const& x)
|
||||
{
|
||||
return x.get_head();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tuple_extract_impl<false>
|
||||
{
|
||||
template <class Tuple, class Predicate>
|
||||
struct apply
|
||||
: tuple_extract<typename Tuple::tail_type, Predicate>
|
||||
{
|
||||
// All of this forwarding would be unneeded if tuples were
|
||||
// derived from their tails.
|
||||
typedef tuple_extract<typename Tuple::tail_type, Predicate> base;
|
||||
typedef typename base::result_type result_type;
|
||||
static result_type extract(Tuple const& x)
|
||||
{
|
||||
return base::extract(x.get_tail());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
template <class Tuple, class Predicate>
|
||||
struct tuple_extract_base_select
|
||||
{
|
||||
typedef typename Tuple::head_type head_type;
|
||||
typedef typename mpl::apply1<Predicate,head_type>::type match_t;
|
||||
BOOST_STATIC_CONSTANT(bool, match = match_t::value);
|
||||
typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type;
|
||||
};
|
||||
|
||||
template <class Tuple, class Predicate>
|
||||
struct tuple_extract
|
||||
: tuple_extract_base_select<
|
||||
Tuple
|
||||
, typename mpl::lambda<Predicate>::type
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template <class Tuple>
|
||||
struct doc_extract
|
||||
: tuple_extract<
|
||||
Tuple,
|
||||
mpl::logical_not<
|
||||
is_reference_to_class<
|
||||
add_reference<mpl::_1>
|
||||
>
|
||||
> >
|
||||
{
|
||||
};
|
||||
|
||||
template <class Tuple>
|
||||
struct keyword_extract
|
||||
: tuple_extract<Tuple, is_reference_to_keywords<add_reference<mpl::_1> > >
|
||||
{
|
||||
};
|
||||
|
||||
template <class Tuple>
|
||||
struct policy_extract
|
||||
: tuple_extract<
|
||||
Tuple,
|
||||
mpl::logical_and<
|
||||
is_reference_to_class<add_reference<mpl::_> >
|
||||
, mpl::logical_not<is_reference_to_keywords<add_reference<mpl::_1> > >
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# define BOOST_PYTHON_DEF_HELPER_TAIL default_call_policies, keywords<0>, char const*
|
||||
template <class T1, class T2 = not_specified, class T3 = not_specified>
|
||||
struct def_helper
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_same<T2, not_specified>
|
||||
, boost::tuples::tuple<T1 const&, BOOST_PYTHON_DEF_HELPER_TAIL>
|
||||
, typename mpl::if_<
|
||||
is_same<T3, not_specified>
|
||||
, boost::tuples::tuple<T1 const&, T2 const&, BOOST_PYTHON_DEF_HELPER_TAIL>
|
||||
, boost::tuples::tuple<T1 const&, T2 const&, T3 const&>
|
||||
>::type
|
||||
>::type all_t;
|
||||
|
||||
def_helper(T1 const& a1) : m_all(a1) {}
|
||||
def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2) {}
|
||||
def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3) {}
|
||||
|
||||
char const* doc() const
|
||||
{
|
||||
return doc_extract<all_t>::extract(m_all);
|
||||
}
|
||||
|
||||
typename keyword_extract<all_t>::result_type keywords() const
|
||||
{
|
||||
return keyword_extract<all_t>::extract(m_all);
|
||||
}
|
||||
|
||||
typename policy_extract<all_t>::result_type policies() const
|
||||
{
|
||||
return policy_extract<all_t>::extract(m_all);
|
||||
}
|
||||
|
||||
all_t m_all;
|
||||
};
|
||||
# undef BOOST_PYTHON_DEF_HELPER_TAIL
|
||||
}
|
||||
|
||||
}} // namespace boost::python::detail
|
||||
|
||||
#endif // DEF_HELPER_DWA200287_HPP
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
#include <boost/python/class_fwd.hpp>
|
||||
#include <boost/python/object/function.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#include <boost/preprocessor/debug/line.hpp>
|
||||
#include <boost/python/detail/scope.hpp>
|
||||
#include <boost/python/detail/make_keyword_range_fn.hpp>
|
||||
#include <boost/python/object/add_to_namespace.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace python {
|
||||
@@ -33,78 +35,92 @@ namespace objects
|
||||
struct class_base;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Func, class CallPolicies, class NameSpaceT>
|
||||
static void name_space_def(
|
||||
NameSpaceT& name_space,
|
||||
char const* name,
|
||||
Func f,
|
||||
CallPolicies const& policies,
|
||||
char const* doc,
|
||||
objects::class_base*
|
||||
)
|
||||
namespace detail
|
||||
{
|
||||
name_space.def(
|
||||
name, f, policies, doc);
|
||||
}
|
||||
template <class T, class F> struct member_function_cast;
|
||||
|
||||
template <class Func, class CallPolicies, class NameSpaceT>
|
||||
static void name_space_def(
|
||||
NameSpaceT& name_space
|
||||
, char const* name
|
||||
, Func f
|
||||
, keyword_range const& kw
|
||||
, CallPolicies const& policies
|
||||
, char const* doc
|
||||
, objects::class_base*
|
||||
)
|
||||
{
|
||||
typedef typename NameSpaceT::wrapped_type wrapped_type;
|
||||
|
||||
objects::add_to_namespace(
|
||||
name_space, name,
|
||||
make_keyword_range_function(
|
||||
// This bit of nastiness casts F to a member function of T if possible.
|
||||
member_function_cast<wrapped_type,Func>::stage1(f).stage2((wrapped_type*)0).stage3(f)
|
||||
, policies, kw)
|
||||
, doc);
|
||||
}
|
||||
|
||||
template <class Func, class CallPolicies>
|
||||
static void name_space_def(
|
||||
object& name_space,
|
||||
char const* name,
|
||||
Func f,
|
||||
CallPolicies const& policies,
|
||||
char const* doc,
|
||||
...
|
||||
)
|
||||
{
|
||||
scope within(name_space);
|
||||
template <class Func, class CallPolicies>
|
||||
static void name_space_def(
|
||||
object& name_space
|
||||
, char const* name
|
||||
, Func f
|
||||
, keyword_range const& kw
|
||||
, CallPolicies const& policies
|
||||
, char const* doc
|
||||
, ...
|
||||
)
|
||||
{
|
||||
scope within(name_space);
|
||||
|
||||
def(name, f, policies, doc);
|
||||
}
|
||||
detail::scope_setattr_doc(
|
||||
name
|
||||
, detail::make_keyword_range_function(f, policies, kw)
|
||||
, doc);
|
||||
}
|
||||
|
||||
// For backward compatibility
|
||||
template <class Func, class CallPolicies, class NameSpaceT>
|
||||
static void name_space_def(
|
||||
NameSpaceT& name_space,
|
||||
char const* name,
|
||||
Func f,
|
||||
CallPolicies const& policies,
|
||||
char const* doc,
|
||||
module*
|
||||
)
|
||||
{
|
||||
name_space.def(
|
||||
name, f, policies, doc);
|
||||
}
|
||||
// For backward compatibility
|
||||
template <class Func, class CallPolicies, class NameSpaceT>
|
||||
static void name_space_def(
|
||||
NameSpaceT& name_space
|
||||
, char const* name
|
||||
, Func f
|
||||
, keyword_range const& kw // ignored
|
||||
, CallPolicies const& policies
|
||||
, char const* doc
|
||||
, module*
|
||||
)
|
||||
{
|
||||
name_space.def(name, f, policies, doc);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This Boost PP code generates expansions for
|
||||
//
|
||||
// template <typename StubsT, typename NameSpaceT>
|
||||
// inline void
|
||||
// define_stub_function(
|
||||
// char const* name, StubsT s, NameSpaceT& name_space, mpl::int_c<N>)
|
||||
// {
|
||||
// name_space.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. NameSpaceT& name_space: 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
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <int N>
|
||||
struct define_stub_function {};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This Boost PP code generates expansions for
|
||||
//
|
||||
// template <typename OverloadsT, typename NameSpaceT>
|
||||
// inline void
|
||||
// define_stub_function(
|
||||
// char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_c<N>)
|
||||
// {
|
||||
// name_space.def(name, &OverloadsT::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. OverloadsT: a function overloads struct (see defaults_gen.hpp)
|
||||
// 3. NameSpaceT& name_space: a python::class_ or python::module instance
|
||||
// 4. int_t<N>: the Nth overloaded function (OverloadsT::func_N)
|
||||
// (see defaults_gen.hpp)
|
||||
// 5. char const* name: doc string
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <int N>
|
||||
struct define_stub_function {};
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>))
|
||||
@@ -120,10 +136,10 @@ struct define_stub_function {};
|
||||
// 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. NameSpaceT& name_space: a python::class_ or python::module instance
|
||||
// 4. char const* name: doc string
|
||||
// 1. char const* name: function name that will be visible to python
|
||||
// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp)
|
||||
// 3. NameSpaceT& name_space: 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
|
||||
@@ -139,14 +155,19 @@ struct define_stub_function {};
|
||||
def(
|
||||
char const* name,
|
||||
StubsT stubs,
|
||||
keyword_range kw,
|
||||
CallPolicies const& policies,
|
||||
NameSpaceT& name_space,
|
||||
char const* doc)
|
||||
{
|
||||
// define the NTH stub function of stubs
|
||||
define_stub_function<N>::define(name, stubs, policies, name_space, doc);
|
||||
define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
|
||||
|
||||
if (kw.second > kw.first)
|
||||
--kw.second;
|
||||
|
||||
// call the next define_with_defaults_helper
|
||||
define_with_defaults_helper<N-1>::def(name, stubs, policies, name_space, doc);
|
||||
define_with_defaults_helper<N-1>::def(name, stubs, kw, policies, name_space, doc);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -159,12 +180,13 @@ struct define_stub_function {};
|
||||
def(
|
||||
char const* name,
|
||||
StubsT stubs,
|
||||
keyword_range const& kw,
|
||||
CallPolicies const& policies,
|
||||
NameSpaceT& name_space,
|
||||
char const* doc)
|
||||
{
|
||||
// define the Oth stub function of stubs
|
||||
define_stub_function<0>::define(name, stubs, policies, name_space, doc);
|
||||
define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc);
|
||||
// return
|
||||
}
|
||||
};
|
||||
@@ -174,7 +196,7 @@ struct define_stub_function {};
|
||||
// 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)
|
||||
// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp)
|
||||
// 3. CallPolicies& policies: Call policies
|
||||
// 4. NameSpaceT& name_space: a python::class_ or python::module instance
|
||||
// 5. SigT sig: Function signature typelist (see defaults_gen.hpp)
|
||||
@@ -191,17 +213,17 @@ struct define_stub_function {};
|
||||
// void C::foo(int) mpl::list<void, C, int>
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <class StubsT, class NameSpaceT, class SigT>
|
||||
template <class OverloadsT, class NameSpaceT, class SigT>
|
||||
inline void
|
||||
define_with_defaults(
|
||||
char const* name,
|
||||
StubsT const& stubs,
|
||||
OverloadsT const& overloads,
|
||||
NameSpaceT& name_space,
|
||||
SigT sig)
|
||||
{
|
||||
typedef typename mpl::front<SigT>::type return_type;
|
||||
typedef typename StubsT::void_return_type void_return_type;
|
||||
typedef typename StubsT::non_void_return_type non_void_return_type;
|
||||
typedef typename OverloadsT::void_return_type void_return_type;
|
||||
typedef typename OverloadsT::non_void_return_type non_void_return_type;
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
boost::is_same<void, return_type>::value
|
||||
@@ -213,8 +235,13 @@ struct define_stub_function {};
|
||||
(stubs_type::max_args) <= mpl::size<SigT>::value);
|
||||
|
||||
typedef typename stubs_type::template gen<SigT> gen_type;
|
||||
define_with_defaults_helper<stubs_type::n_funcs-1>::def
|
||||
(name, gen_type(), stubs.call_policies(), name_space, stubs.doc_string());
|
||||
define_with_defaults_helper<stubs_type::n_funcs-1>::def(
|
||||
name
|
||||
, gen_type()
|
||||
, overloads.keywords()
|
||||
, overloads.call_policies()
|
||||
, name_space
|
||||
, overloads.doc_string());
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
@@ -232,17 +259,21 @@ template <>
|
||||
struct define_stub_function<BOOST_PP_ITERATION()> {
|
||||
template <class StubsT, class CallPolicies, class NameSpaceT>
|
||||
static void define(
|
||||
char const* name,
|
||||
StubsT,
|
||||
CallPolicies const& policies,
|
||||
NameSpaceT& name_space,
|
||||
char const* doc)
|
||||
char const* name
|
||||
, StubsT const&
|
||||
, keyword_range const& kw
|
||||
, CallPolicies const& policies
|
||||
, NameSpaceT& name_space
|
||||
, char const* doc)
|
||||
{
|
||||
detail::name_space_def(name_space,
|
||||
name,
|
||||
&StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()),
|
||||
policies,
|
||||
doc, &name_space);
|
||||
detail::name_space_def(
|
||||
name_space
|
||||
, name
|
||||
, &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION())
|
||||
, kw
|
||||
, policies
|
||||
, doc
|
||||
, &name_space);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,74 +29,96 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// overloads_base is used as a base class for all function
|
||||
// stubs. This class holds the doc_string of the stubs.
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// overloads_base is used as a base class for all function
|
||||
// stubs. This class holds the doc_string of the stubs.
|
||||
struct overloads_base
|
||||
{
|
||||
overloads_base(char const* doc_)
|
||||
: doc(doc_) {}
|
||||
: m_doc(doc_) {}
|
||||
|
||||
overloads_base(char const* doc_, detail::keyword_range const& kw)
|
||||
: m_doc(doc_), m_keywords(kw) {}
|
||||
|
||||
char const* doc_string() const
|
||||
{ return doc; }
|
||||
{
|
||||
return m_doc;
|
||||
}
|
||||
|
||||
char const* doc;
|
||||
detail::keyword_range const& keywords() const
|
||||
{
|
||||
return m_keywords;
|
||||
}
|
||||
|
||||
private:
|
||||
char const* m_doc;
|
||||
detail::keyword_range m_keywords;
|
||||
};
|
||||
}
|
||||
|
||||
// overloads_proxy is generated by the overloads_common operator[] (see
|
||||
// below). This class holds a user defined call policies of the stubs.
|
||||
// overloads_proxy is generated by the overloads_common operator[] (see
|
||||
// below). This class holds a user defined call policies of the stubs.
|
||||
template <class CallPoliciesT, class OverloadsT>
|
||||
struct overloads_proxy
|
||||
: public overloads_base
|
||||
{
|
||||
typedef typename OverloadsT::non_void_return_type non_void_return_type;
|
||||
typedef typename OverloadsT::void_return_type void_return_type;
|
||||
|
||||
template <class CallPoliciesT, class OverloadsT>
|
||||
struct overloads_proxy
|
||||
: public detail::overloads_base
|
||||
{
|
||||
typedef typename OverloadsT::non_void_return_type non_void_return_type;
|
||||
typedef typename OverloadsT::void_return_type void_return_type;
|
||||
overloads_proxy(
|
||||
CallPoliciesT const& policies_
|
||||
, char const* doc
|
||||
, keyword_range const& kw
|
||||
)
|
||||
: overloads_base(doc, kw)
|
||||
, policies(policies_)
|
||||
{}
|
||||
|
||||
overloads_proxy(CallPoliciesT const& policies_, char const* doc)
|
||||
: detail::overloads_base(doc), policies(policies_) {}
|
||||
CallPoliciesT
|
||||
call_policies() const
|
||||
{
|
||||
return policies;
|
||||
}
|
||||
|
||||
CallPoliciesT
|
||||
call_policies() const
|
||||
{ return policies; }
|
||||
CallPoliciesT policies;
|
||||
};
|
||||
|
||||
CallPoliciesT policies;
|
||||
};
|
||||
// overloads_common is our default function stubs base class. This
|
||||
// class returns the default_call_policies in its call_policies()
|
||||
// member function. It can generate a overloads_proxy however through
|
||||
// its operator[]
|
||||
template <class DerivedT>
|
||||
struct overloads_common
|
||||
: public overloads_base
|
||||
{
|
||||
overloads_common(char const* doc)
|
||||
: overloads_base(doc) {}
|
||||
|
||||
// overloads_common is our default function stubs base class. This class
|
||||
// returns the default_call_policies in its call_policies() member function.
|
||||
// It can generate a overloads_proxy however through its operator[]
|
||||
overloads_common(char const* doc, keyword_range const& kw)
|
||||
: overloads_base(doc, kw) {}
|
||||
|
||||
template <class DerivedT>
|
||||
struct overloads_common
|
||||
: public detail::overloads_base {
|
||||
default_call_policies
|
||||
call_policies() const
|
||||
{
|
||||
return default_call_policies();
|
||||
}
|
||||
|
||||
overloads_common(char const* doc)
|
||||
: detail::overloads_base(doc) {}
|
||||
template <class CallPoliciesT>
|
||||
overloads_proxy<CallPoliciesT, DerivedT>
|
||||
operator[](CallPoliciesT const& policies) const
|
||||
{
|
||||
return overloads_proxy<CallPoliciesT, DerivedT>(
|
||||
policies, this->doc_string(), this->keywords());
|
||||
}
|
||||
};
|
||||
|
||||
default_call_policies
|
||||
call_policies() const
|
||||
{ return default_call_policies(); }
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
template <class CallPoliciesT>
|
||||
::boost::python::overloads_proxy<CallPoliciesT, DerivedT>
|
||||
operator[](CallPoliciesT const& policies) const
|
||||
{
|
||||
return overloads_proxy<CallPoliciesT, DerivedT>
|
||||
(policies, doc);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PYTHON_TYPEDEF_GEN(z, index, data) \
|
||||
typedef typename BOOST_PP_CAT(iter, index)::next \
|
||||
BOOST_PP_CAT(iter, BOOST_PP_INC(index)); \
|
||||
typedef typename BOOST_PP_CAT(iter, index)::type BOOST_PP_CAT(T, index); \
|
||||
typedef typename BOOST_PP_CAT(iter, index)::type BOOST_PP_CAT(T, index);
|
||||
|
||||
#define BOOST_PYTHON_FUNC_WRAPPER_GEN(z, index, data) \
|
||||
static RT BOOST_PP_CAT(func_, \
|
||||
@@ -112,14 +134,14 @@ struct overloads_common
|
||||
}
|
||||
|
||||
#define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \
|
||||
struct fstubs_name { \
|
||||
\
|
||||
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 { \
|
||||
\
|
||||
struct gen \
|
||||
{ \
|
||||
typedef typename ::boost::mpl::begin<SigT>::type rt_iter; \
|
||||
typedef typename rt_iter::type RT; \
|
||||
typedef typename rt_iter::next iter0; \
|
||||
@@ -151,14 +173,14 @@ struct overloads_common
|
||||
}
|
||||
|
||||
#define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \
|
||||
struct fstubs_name { \
|
||||
\
|
||||
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 { \
|
||||
\
|
||||
struct gen \
|
||||
{ \
|
||||
typedef typename ::boost::mpl::begin<SigT>::type rt_iter; \
|
||||
typedef typename rt_iter::type RT; \
|
||||
\
|
||||
@@ -179,75 +201,82 @@ struct overloads_common
|
||||
}; \
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(BOOST_NO_VOID_RETURNS)
|
||||
|
||||
#define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_FUNCTION \
|
||||
(fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \
|
||||
BOOST_PYTHON_GEN_FUNCTION \
|
||||
(fname, BOOST_PP_CAT(fstubs_name, _V), n_args, n_dflts, ;) \
|
||||
struct fstubs_name \
|
||||
: public boost::python::overloads_common<fstubs_name> \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _V) void_return_type; \
|
||||
\
|
||||
fstubs_name(char const* doc = 0) \
|
||||
: boost::python:: \
|
||||
overloads_common<fstubs_name>(doc) {} \
|
||||
}; \
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_MEM_FUNCTION \
|
||||
(fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \
|
||||
BOOST_PYTHON_GEN_MEM_FUNCTION \
|
||||
(fname, BOOST_PP_CAT(fstubs_name, _V), n_args, n_dflts, ;) \
|
||||
struct fstubs_name \
|
||||
: public boost::python::overloads_common<fstubs_name> \
|
||||
#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
||||
fstubs_name(char const* doc = 0) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>(doc) {} \
|
||||
template <class Keywords> \
|
||||
fstubs_name(char const* doc, Keywords const& keywords) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>( \
|
||||
doc, keywords.range()) \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _V) void_return_type; \
|
||||
\
|
||||
fstubs_name(char const* doc = 0) \
|
||||
: boost::python:: \
|
||||
overloads_common<fstubs_name>(doc) {} \
|
||||
}; \
|
||||
|
||||
#else
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_FUNCTION \
|
||||
(fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \
|
||||
struct fstubs_name \
|
||||
: public boost::python::overloads_common<fstubs_name> \
|
||||
typedef typename ::boost::python::detail:: \
|
||||
error::more_keywords_than_function_arguments< \
|
||||
Keywords::size,(n_args+n_dflts)>::too_many_keywords assertion; \
|
||||
} \
|
||||
template <class Keywords> \
|
||||
fstubs_name(Keywords const& keywords, char const* doc = 0) \
|
||||
: ::boost::python::detail::overloads_common<fstubs_name>( \
|
||||
doc, keywords.range()) \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _NV) void_return_type; \
|
||||
\
|
||||
fstubs_name(char const* doc = 0) \
|
||||
: boost::python:: \
|
||||
overloads_common<fstubs_name>(doc) {} \
|
||||
}; \
|
||||
typedef typename ::boost::python::detail:: \
|
||||
error::more_keywords_than_function_arguments< \
|
||||
Keywords::size,(n_args+n_dflts)>::too_many_keywords assertion; \
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_MEM_FUNCTION \
|
||||
(fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \
|
||||
# if defined(BOOST_NO_VOID_RETURNS)
|
||||
|
||||
# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_FUNCTION( \
|
||||
fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return) \
|
||||
BOOST_PYTHON_GEN_FUNCTION( \
|
||||
fname, BOOST_PP_CAT(fstubs_name, Void), n_args, n_dflts, ;) \
|
||||
struct fstubs_name \
|
||||
: public boost::python::overloads_common<fstubs_name> \
|
||||
: public ::boost::python::detail::overloads_common<fstubs_name> \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, _NV) void_return_type; \
|
||||
\
|
||||
fstubs_name(char const* doc = 0) \
|
||||
: boost::python:: \
|
||||
overloads_common<fstubs_name>(doc) {} \
|
||||
}; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, Void) void_return_type; \
|
||||
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_MSVC)
|
||||
# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_MEM_FUNCTION( \
|
||||
fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return) \
|
||||
BOOST_PYTHON_GEN_MEM_FUNCTION( \
|
||||
fname, BOOST_PP_CAT(fstubs_name, Void), n_args, n_dflts, ;) \
|
||||
struct fstubs_name \
|
||||
: public ::boost::python::detail::overloads_common<fstubs_name> \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, Void) void_return_type; \
|
||||
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
||||
};
|
||||
|
||||
# else // !defined(BOOST_NO_VOID_RETURNS)
|
||||
|
||||
# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_FUNCTION( \
|
||||
fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return) \
|
||||
struct fstubs_name \
|
||||
: public ::boost::python::detail::overloads_common<fstubs_name> \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, NonVoid) void_return_type; \
|
||||
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
||||
};
|
||||
|
||||
|
||||
# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
|
||||
BOOST_PYTHON_GEN_MEM_FUNCTION( \
|
||||
fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return) \
|
||||
struct fstubs_name \
|
||||
: public ::boost::python::detail::overloads_common<fstubs_name> \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \
|
||||
typedef BOOST_PP_CAT(fstubs_name, NonVoid) void_return_type; \
|
||||
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
|
||||
};
|
||||
|
||||
# endif // !defined(BOOST_NO_VOID_RETURNS)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -278,14 +307,14 @@ struct overloads_common
|
||||
//
|
||||
// Generates this code:
|
||||
//
|
||||
// struct foo_stubs_NV {
|
||||
//
|
||||
// struct foo_stubsNonVoid
|
||||
// {
|
||||
// static const int n_funcs = 4;
|
||||
// static const int max_args = n_funcs;
|
||||
//
|
||||
// template <typename SigT>
|
||||
// struct gen {
|
||||
//
|
||||
// struct gen
|
||||
// {
|
||||
// typedef typename ::boost::mpl::begin<SigT>::type rt_iter;
|
||||
// typedef typename rt_iter::type RT;
|
||||
// typedef typename rt_iter::next iter0;
|
||||
@@ -312,28 +341,27 @@ struct overloads_common
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// struct foo_stubs
|
||||
// : public boost::python::overloads_common<foo_stubs>
|
||||
// struct foo_overloads
|
||||
// : public boost::python::detail::overloads_common<foo_overloads>
|
||||
// {
|
||||
// typedef foo_overloadsNonVoid non_void_return_type;
|
||||
// typedef foo_overloadsNonVoid void_return_type;
|
||||
//
|
||||
// typedef foo_stubs_NV non_void_return_type;
|
||||
// typedef foo_stubs_NV void_return_type;
|
||||
//
|
||||
// fstubs_name(char const* doc = 0)
|
||||
// : boost::python::
|
||||
// overloads_common<foo_stubs>(doc) {}
|
||||
// foo_overloads(char const* doc = 0)
|
||||
// : boost::python::detail::overloads_common<foo_overloads>(doc) {}
|
||||
// };
|
||||
//
|
||||
// The typedefs non_void_return_type and void_return_type are
|
||||
// used to handle compilers that do not support void returns. The
|
||||
// example above typedefs non_void_return_type and
|
||||
// void_return_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.
|
||||
// void_return_type to foo_overloadsNonVoid. On compilers that do
|
||||
// not support void returns, there are two versions:
|
||||
// foo_overloadsNonVoid and foo_overloadsVoid. The "Void"
|
||||
// version is almost identical to the "NonVoid" version except
|
||||
// for the return type (void) and the lack of the return keyword.
|
||||
//
|
||||
// See the overloads_common above for a description of the foo_stubs'
|
||||
// base class.
|
||||
// See the overloads_common above for a description of the
|
||||
// foo_overloads' base class.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PYTHON_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
# include <boost/type_traits/remove_pointer.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/bool_c.hpp>
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
@@ -163,6 +165,8 @@ struct is_reference_to_class
|
||||
>::value
|
||||
>::value)
|
||||
);
|
||||
typedef mpl::bool_c<value> type;
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T))
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -343,7 +347,6 @@ struct is_reference_to_volatile
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <typename V>
|
||||
typename is_pointer_help<V>::type reference_to_pointer_helper(V&);
|
||||
outer_no_type reference_to_pointer_helper(...);
|
||||
@@ -370,8 +373,10 @@ struct is_reference_to_class
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value
|
||||
= (is_reference<T>::value
|
||||
&& sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))
|
||||
& (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type)))
|
||||
);
|
||||
typedef mpl::bool_c<value> type;
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T))
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
|
||||
45
include/boost/python/detail/make_keyword_range_fn.hpp
Normal file
45
include/boost/python/detail/make_keyword_range_fn.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// 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 MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP
|
||||
# define MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP
|
||||
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
# include <boost/python/detail/caller.hpp>
|
||||
# include <boost/python/object/function_object.hpp>
|
||||
# include <boost/python/object/make_holder.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class F, class Policies>
|
||||
object make_keyword_range_function(F f, Policies const& policies, keyword_range const& kw)
|
||||
{
|
||||
enum { n_arguments = detail::arg_tuple_size<F>::value };
|
||||
return objects::function_object(
|
||||
::boost::bind<PyObject*>(detail::caller(), f, _1, _2, policies)
|
||||
, n_arguments
|
||||
, kw);
|
||||
}
|
||||
|
||||
template <class ArgList, class HolderGenerator, class Policies>
|
||||
object make_keyword_range_constructor(
|
||||
Policies const& policies
|
||||
, detail::keyword_range const& kw
|
||||
, HolderGenerator* = 0
|
||||
, ArgList* = 0)
|
||||
{
|
||||
enum { nargs = mpl::size<ArgList>::value };
|
||||
|
||||
return objects::function_object(
|
||||
::boost::bind<PyObject*>(detail::caller(),
|
||||
objects::make_holder<nargs>
|
||||
::template apply<HolderGenerator,ArgList>::execute
|
||||
, _1, _2, policies)
|
||||
, nargs + 1, kw);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP
|
||||
15
include/boost/python/detail/scope.hpp
Normal file
15
include/boost/python/detail/scope.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
// 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 SCOPE_DWA2002927_HPP
|
||||
# define SCOPE_DWA2002927_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc);
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // SCOPE_DWA2002927_HPP
|
||||
@@ -11,6 +11,7 @@
|
||||
#define INIT_JDG20020820_HPP
|
||||
|
||||
#include <boost/python/detail/type_list.hpp>
|
||||
#include <boost/python/args_fwd.hpp>
|
||||
#include <boost/mpl/fold_backward.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
@@ -25,6 +26,7 @@
|
||||
#include <boost/mpl/find_if.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/pop_front.hpp>
|
||||
#include <boost/mpl/bool_c.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
@@ -34,6 +36,8 @@
|
||||
#include <boost/preprocessor/enum_params.hpp>
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT \
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \
|
||||
@@ -55,13 +59,22 @@
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
|
||||
struct init; // forward declaration
|
||||
class init; // forward declaration
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
|
||||
struct optional; // forward declaration
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
namespace error
|
||||
{
|
||||
template <int keywords, int init_args>
|
||||
struct more_keywords_than_init_arguments
|
||||
{
|
||||
typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1];
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -89,7 +102,7 @@ namespace detail {
|
||||
sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
|
||||
typedef mpl::bool_c<value> type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) // needed for MSVC & Borland
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T))
|
||||
};
|
||||
|
||||
///////////////////////////////////////
|
||||
@@ -111,61 +124,114 @@ namespace detail {
|
||||
struct is_optional : is_optional_impl<T>
|
||||
{
|
||||
typedef mpl::bool_c<is_optional_impl<T>::value> type;
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) // needed for MSVC & Borland
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T))
|
||||
};
|
||||
#endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class DerivedT>
|
||||
struct init_base {
|
||||
|
||||
struct init_base
|
||||
{
|
||||
init_base(char const* doc_, detail::keyword_range const& keywords_)
|
||||
: m_doc(doc_), m_keywords(keywords_)
|
||||
{}
|
||||
|
||||
init_base(char const* doc_)
|
||||
: m_doc(doc_)
|
||||
{}
|
||||
|
||||
DerivedT const& derived() const
|
||||
{ return *static_cast<DerivedT const*>(this); }
|
||||
{
|
||||
return *static_cast<DerivedT const*>(this);
|
||||
}
|
||||
|
||||
char const* doc_string() const
|
||||
{
|
||||
return m_doc;
|
||||
}
|
||||
|
||||
detail::keyword_range const& keywords() const
|
||||
{
|
||||
return m_keywords;
|
||||
}
|
||||
|
||||
static default_call_policies call_policies()
|
||||
{
|
||||
return default_call_policies();
|
||||
}
|
||||
|
||||
private: // data members
|
||||
char const* m_doc;
|
||||
detail::keyword_range m_keywords;
|
||||
};
|
||||
|
||||
template <class CallPoliciesT, class InitT>
|
||||
struct init_with_call_policies
|
||||
: public init_base<init_with_call_policies<CallPoliciesT, InitT> >
|
||||
class init_with_call_policies
|
||||
: public init_base<init_with_call_policies<CallPoliciesT, InitT> >
|
||||
{
|
||||
typedef init_base<init_with_call_policies<CallPoliciesT, InitT> > base;
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(int, n_arguments = InitT::n_arguments);
|
||||
BOOST_STATIC_CONSTANT(int, n_defaults = InitT::n_defaults);
|
||||
|
||||
typedef typename InitT::reversed_args reversed_args;
|
||||
|
||||
init_with_call_policies(CallPoliciesT const& policies_, char const* doc_)
|
||||
: policies(policies_), doc(doc_) {}
|
||||
init_with_call_policies(
|
||||
CallPoliciesT const& policies_
|
||||
, char const* doc_
|
||||
, detail::keyword_range const& keywords
|
||||
)
|
||||
: base(doc_, keywords)
|
||||
, m_policies(policies_)
|
||||
{}
|
||||
|
||||
char const* doc_string() const
|
||||
{ return doc; }
|
||||
|
||||
CallPoliciesT
|
||||
call_policies() const
|
||||
{ return policies; }
|
||||
|
||||
CallPoliciesT policies;
|
||||
char const* doc;
|
||||
CallPoliciesT const& call_policies() const
|
||||
{
|
||||
return this->m_policies;
|
||||
}
|
||||
|
||||
private: // data members
|
||||
CallPoliciesT m_policies;
|
||||
};
|
||||
|
||||
template <BOOST_PYTHON_OVERLOAD_TYPES>
|
||||
struct init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
|
||||
class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
|
||||
{
|
||||
typedef init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> > base;
|
||||
public:
|
||||
typedef init<BOOST_PYTHON_OVERLOAD_ARGS> self_t;
|
||||
|
||||
init(char const* doc_ = 0)
|
||||
: doc(doc_) {}
|
||||
: base(doc_)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Keywords>
|
||||
init(char const* doc_, Keywords const& kw)
|
||||
: base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size))
|
||||
{
|
||||
typedef typename detail::error::more_keywords_than_init_arguments<
|
||||
Keywords::size, n_arguments
|
||||
>::too_many_keywords assertion;
|
||||
}
|
||||
|
||||
char const* doc_string() const
|
||||
{ return doc; }
|
||||
|
||||
default_call_policies
|
||||
call_policies() const
|
||||
{ return default_call_policies(); }
|
||||
template <class Keywords>
|
||||
init(Keywords const& kw)
|
||||
: base(0, kw.range())
|
||||
{
|
||||
typedef typename detail::error::more_keywords_than_init_arguments<
|
||||
Keywords::size, n_arguments
|
||||
>::too_many_keywords assertion;
|
||||
}
|
||||
|
||||
template <class CallPoliciesT>
|
||||
init_with_call_policies<CallPoliciesT, self_t>
|
||||
operator[](CallPoliciesT const& policies) const
|
||||
{ return init_with_call_policies<CallPoliciesT, self_t>(policies, doc); }
|
||||
{
|
||||
return init_with_call_policies<CallPoliciesT, self_t>(
|
||||
policies, this->doc_string(), this->keywords());
|
||||
}
|
||||
|
||||
typedef detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS> signature_;
|
||||
typedef typename mpl::end<signature_>::type finish;
|
||||
@@ -213,37 +279,47 @@ struct init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
|
||||
|
||||
// Count the maximum number of arguments
|
||||
BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size<reversed_args>::value);
|
||||
|
||||
char const* doc;
|
||||
};
|
||||
|
||||
# if 1
|
||||
template <> // specialization for zero args
|
||||
struct init<> : public init_base<init<> >
|
||||
class init<> : public init_base<init<> >
|
||||
{
|
||||
typedef init_base<init<> > base;
|
||||
public:
|
||||
typedef init<> self_t;
|
||||
|
||||
init(char const* doc_ = 0)
|
||||
: doc(doc_) {}
|
||||
: base(doc_)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Keywords>
|
||||
init(char const* doc_, Keywords const& kw)
|
||||
: base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size))
|
||||
{
|
||||
}
|
||||
|
||||
char const* doc_string() const
|
||||
{ return doc; }
|
||||
|
||||
default_call_policies
|
||||
call_policies() const
|
||||
{ return default_call_policies(); }
|
||||
template <class Keywords>
|
||||
init(Keywords const& kw)
|
||||
: base(0, std::make_pair(kw.base(), kw.base() + Keywords::size))
|
||||
{
|
||||
}
|
||||
|
||||
template <class CallPoliciesT>
|
||||
init_with_call_policies<CallPoliciesT, self_t>
|
||||
operator[](CallPoliciesT const& policies) const
|
||||
{ return init_with_call_policies<CallPoliciesT, self_t>(policies, doc); }
|
||||
{
|
||||
return init_with_call_policies<CallPoliciesT, self_t>(
|
||||
policies, this->doc_string(), this->keywords());
|
||||
}
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, n_defaults = 0);
|
||||
BOOST_STATIC_CONSTANT(int, n_arguments = 0);
|
||||
|
||||
typedef detail::type_list<> reversed_args;
|
||||
|
||||
char const* doc;
|
||||
};
|
||||
# endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -261,7 +337,13 @@ struct optional
|
||||
namespace detail
|
||||
{
|
||||
template <class ClassT, class CallPoliciesT, class ReversedArgs>
|
||||
void def_init_reversed(ClassT& cl, ReversedArgs const&, CallPoliciesT const& policies, char const* doc)
|
||||
void def_init_reversed(
|
||||
ClassT& cl
|
||||
, ReversedArgs const&
|
||||
, CallPoliciesT const& policies
|
||||
, char const* doc
|
||||
, detail::keyword_range const& keywords_
|
||||
)
|
||||
{
|
||||
typedef typename mpl::fold<
|
||||
ReversedArgs
|
||||
@@ -274,8 +356,9 @@ namespace detail
|
||||
|
||||
cl.def(
|
||||
"__init__",
|
||||
python::make_constructor<args>(
|
||||
detail::make_keyword_range_constructor<args>(
|
||||
policies
|
||||
, keywords_
|
||||
// Using runtime type selection works around a CWPro7 bug.
|
||||
, holder_selector_t::execute((held_type_t*)0).get()
|
||||
)
|
||||
@@ -299,12 +382,20 @@ namespace detail
|
||||
struct define_class_init_helper {
|
||||
|
||||
template <class ClassT, class CallPoliciesT, class ReversedArgs>
|
||||
static void apply(ClassT& cl, CallPoliciesT const& policies, ReversedArgs const& args, char const* doc)
|
||||
static void apply(
|
||||
ClassT& cl
|
||||
, CallPoliciesT const& policies
|
||||
, ReversedArgs const& args
|
||||
, char const* doc
|
||||
, detail::keyword_range keywords)
|
||||
{
|
||||
def_init_reversed(cl, args, policies, doc);
|
||||
def_init_reversed(cl, args, policies, doc, keywords);
|
||||
|
||||
if (keywords.second > keywords.first)
|
||||
--keywords.second;
|
||||
|
||||
typename mpl::pop_front<ReversedArgs>::type next;
|
||||
define_class_init_helper<N-1>::apply(cl, policies, next, doc);
|
||||
define_class_init_helper<N-1>::apply(cl, policies, next, doc, keywords);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -322,9 +413,14 @@ namespace detail
|
||||
struct define_class_init_helper<0> {
|
||||
|
||||
template <class ClassT, class CallPoliciesT, class ReversedArgs>
|
||||
static void apply(ClassT& cl, CallPoliciesT const& policies, ReversedArgs const& args, char const* doc)
|
||||
static void apply(
|
||||
ClassT& cl
|
||||
, CallPoliciesT const& policies
|
||||
, ReversedArgs const& args
|
||||
, char const* doc
|
||||
, detail::keyword_range const& keywords)
|
||||
{
|
||||
def_init_reversed(cl, args, policies, doc);
|
||||
def_init_reversed(cl, args, policies, doc, keywords);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -356,7 +452,7 @@ define_init(ClassT& cl, InitT const& i)
|
||||
{
|
||||
typedef typename InitT::reversed_args reversed_args;
|
||||
detail::define_class_init_helper<InitT::n_defaults>::apply(
|
||||
cl, i.call_policies(), reversed_args(), i.doc_string());
|
||||
cl, i.call_policies(), reversed_args(), i.doc_string(), i.keywords());
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# define MAKE_FUNCTION_DWA20011221_HPP
|
||||
|
||||
# include <boost/python/object/function_object.hpp>
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
# include <boost/python/object/make_holder.hpp>
|
||||
# include <boost/python/detail/caller.hpp>
|
||||
# include <boost/python/detail/arg_tuple_size.hpp>
|
||||
@@ -32,6 +33,20 @@ object make_function(F f, Policies const& policies)
|
||||
, detail::arg_tuple_size<F>::value);
|
||||
}
|
||||
|
||||
template <class F, class Policies, class Keywords>
|
||||
object make_function(F f, Policies const& policies, Keywords const& keywords)
|
||||
{
|
||||
enum { n_arguments = detail::arg_tuple_size<F>::value };
|
||||
typedef typename detail::error::more_keywords_than_function_arguments<
|
||||
Keywords::size, n_arguments
|
||||
>::too_many_keywords assertion;
|
||||
|
||||
return objects::function_object(
|
||||
::boost::bind<PyObject*>(detail::caller(), f, _1, _2, policies)
|
||||
, n_arguments
|
||||
, keywords.range());
|
||||
}
|
||||
|
||||
template <class ArgList, class HolderGenerator>
|
||||
object make_constructor(HolderGenerator* = 0, ArgList* = 0)
|
||||
{
|
||||
|
||||
@@ -71,11 +71,12 @@ class module : public detail::module_base
|
||||
char const* doc,
|
||||
void const*)
|
||||
{
|
||||
typedef detail::def_helper<CallPolicyOrDoc> helper;
|
||||
detail::def_helper<CallPolicyOrDoc,char const*> helper(policy_or_doc, doc);
|
||||
|
||||
this->setattr_doc(
|
||||
name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)),
|
||||
helper::get_doc(policy_or_doc, doc));
|
||||
name
|
||||
, boost::python::make_function(fn, helper.policies())
|
||||
, helper.doc());
|
||||
}
|
||||
|
||||
template <typename StubsT, typename SigT>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# define FUNCTION_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/function/function2.hpp>
|
||||
@@ -17,7 +18,13 @@ namespace boost { namespace python { namespace objects {
|
||||
|
||||
struct BOOST_PYTHON_DECL function : PyObject
|
||||
{
|
||||
function(py_function const&, unsigned min_args, unsigned max_args = 0);
|
||||
function(
|
||||
py_function const&
|
||||
, unsigned min_arity
|
||||
, unsigned max_arity
|
||||
, python::detail::keyword const* names_and_defaults
|
||||
, unsigned num_keywords);
|
||||
|
||||
~function();
|
||||
|
||||
PyObject* call(PyObject*, PyObject*) const;
|
||||
@@ -42,11 +49,12 @@ struct BOOST_PYTHON_DECL function : PyObject
|
||||
|
||||
private: // data members
|
||||
py_function m_fn;
|
||||
unsigned m_min_args;
|
||||
unsigned m_max_args;
|
||||
unsigned m_min_arity;
|
||||
unsigned m_max_arity;
|
||||
handle<function> m_overloads;
|
||||
object m_name;
|
||||
object m_doc;
|
||||
object m_arg_names;
|
||||
};
|
||||
|
||||
//
|
||||
@@ -66,7 +74,7 @@ inline object const& function::name() const
|
||||
{
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // FUNCTION_DWA20011214_HPP
|
||||
|
||||
@@ -8,17 +8,36 @@
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/function/function2.hpp>
|
||||
# include <boost/python/object_core.hpp>
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
# include <boost/python/object/py_function.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_DECL api::object function_object_impl(boost::function2<PyObject*, PyObject*, PyObject*> const& f, unsigned min_args, unsigned max_args = 0);
|
||||
namespace objects
|
||||
{
|
||||
BOOST_PYTHON_DECL api::object function_object(
|
||||
py_function const& f
|
||||
, unsigned min_arity, unsigned max_arity
|
||||
, python::detail::keyword_range const&);
|
||||
|
||||
template <class F>
|
||||
inline object function_object(F const& f, unsigned min_args, unsigned max_args = 0)
|
||||
{
|
||||
return objects::function_object_impl(boost::function2<PyObject*, PyObject*, PyObject*>(f), min_args, max_args);
|
||||
BOOST_PYTHON_DECL api::object function_object(
|
||||
py_function const& f
|
||||
, unsigned arity
|
||||
, python::detail::keyword_range const&);
|
||||
|
||||
BOOST_PYTHON_DECL api::object function_object(py_function const& f, unsigned arity);
|
||||
|
||||
// Add an attribute to the name_space with the given name. If it is
|
||||
// a Boost.Python function object
|
||||
// (boost/python/object/function.hpp), and an existing function is
|
||||
// already there, add it as an overload.
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute);
|
||||
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute, char const* doc);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
}} // namespace boost::python::objects
|
||||
|
||||
#endif // FUNCTION_OBJECT_DWA2002725_HPP
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#include <boost/python/object/function_object.hpp>
|
||||
#include <boost/python/detail/module_base.hpp>
|
||||
#include <boost/python/object/function.hpp>
|
||||
#include <boost/python/cast.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
@@ -35,7 +35,7 @@ void module_base::setattr_doc(const char* name, python::object const& x, char co
|
||||
{
|
||||
// Use function::add_to_namespace to achieve overloading if
|
||||
// appropriate.
|
||||
objects::function::add_to_namespace(python::object(m_module), name, x, doc);
|
||||
objects::add_to_namespace(python::object(m_module), name, x, doc);
|
||||
}
|
||||
|
||||
void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& x, char const* doc)
|
||||
@@ -43,7 +43,7 @@ void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& x, char
|
||||
// Use function::add_to_namespace to achieve overloading if
|
||||
// appropriate.
|
||||
scope current;
|
||||
objects::function::add_to_namespace(current, name, x, doc);
|
||||
objects::add_to_namespace(current, name, x, doc);
|
||||
}
|
||||
|
||||
void module_base::add(type_handle const& x)
|
||||
|
||||
@@ -7,22 +7,54 @@
|
||||
#include <boost/python/object/function.hpp>
|
||||
#include <boost/python/object/function_object.hpp>
|
||||
#include <boost/python/object/function_handle.hpp>
|
||||
#include <numeric>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/str.hpp>
|
||||
#include <boost/python/object_attributes.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <boost/python/refcount.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <boost/python/object_attributes.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
extern PyTypeObject function_type;
|
||||
|
||||
function::function(py_function const& implementation, unsigned min_args, unsigned max_args)
|
||||
function::function(
|
||||
py_function const& implementation
|
||||
, unsigned min_arity
|
||||
, unsigned max_arity
|
||||
, python::detail::keyword const* names_and_defaults
|
||||
, unsigned num_keywords
|
||||
)
|
||||
: m_fn(implementation)
|
||||
, m_min_args(min_args)
|
||||
, m_max_args(std::max(max_args,min_args))
|
||||
, m_min_arity(min_arity)
|
||||
// was using std::max here, but a problem with MinGW-2.95 and
|
||||
// our <boost/numeric/...> directory prevents it.
|
||||
, m_max_arity(max_arity > min_arity ? max_arity : min_arity)
|
||||
{
|
||||
if (names_and_defaults != 0)
|
||||
{
|
||||
unsigned keyword_offset
|
||||
= m_max_arity > num_keywords ? m_max_arity - num_keywords : 0;
|
||||
|
||||
|
||||
m_arg_names = object(handle<>(PyTuple_New(m_max_arity)));
|
||||
for (unsigned j = 0; j < keyword_offset; ++j)
|
||||
PyTuple_SET_ITEM(m_arg_names.ptr(), j, incref(Py_None));
|
||||
|
||||
for (unsigned i = 0; i < num_keywords; ++i)
|
||||
{
|
||||
PyTuple_SET_ITEM(
|
||||
m_arg_names.ptr()
|
||||
, i + keyword_offset
|
||||
, expect_non_null(
|
||||
PyString_FromString(const_cast<char*>(names_and_defaults[i].name))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* p = this;
|
||||
if (function_type.ob_type == 0)
|
||||
{
|
||||
@@ -39,14 +71,51 @@ function::~function()
|
||||
PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
std::size_t nargs = PyTuple_GET_SIZE(args);
|
||||
std::size_t nkeywords = keywords ? PyDict_Size(keywords) : 0;
|
||||
std::size_t total_args = nargs + nkeywords;
|
||||
|
||||
function const* f = this;
|
||||
do
|
||||
{
|
||||
// Check for a plausible number of arguments
|
||||
if (nargs >= f->m_min_args && nargs <= f->m_max_args)
|
||||
if (total_args >= f->m_min_arity && total_args <= f->m_max_arity)
|
||||
{
|
||||
handle<> args2(allow_null(borrowed(args)));
|
||||
if (nkeywords > 0)
|
||||
{
|
||||
if (!f->m_arg_names
|
||||
|| static_cast<std::size_t>(PyTuple_Size(f->m_arg_names.ptr())) < total_args)
|
||||
{
|
||||
args2 = handle<>(); // signal failure
|
||||
}
|
||||
else
|
||||
{
|
||||
// build a new arg tuple
|
||||
args2 = handle<>(PyTuple_New(total_args));
|
||||
|
||||
// Fill in the positional arguments
|
||||
for (std::size_t i = 0; i < nargs; ++i)
|
||||
PyTuple_SET_ITEM(args2.get(), i, incref(PyTuple_GET_ITEM(args, i)));
|
||||
|
||||
// Grab remaining arguments by name from the keyword dictionary
|
||||
for (std::size_t j = nargs; j < total_args; ++j)
|
||||
{
|
||||
PyObject* value = PyDict_GetItem(
|
||||
keywords, PyTuple_GET_ITEM(f->m_arg_names.ptr(), j));
|
||||
|
||||
if (!value)
|
||||
{
|
||||
PyErr_Clear();
|
||||
args2 = handle<>();
|
||||
break;
|
||||
}
|
||||
PyTuple_SET_ITEM(args2.get(), j, incref(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function
|
||||
PyObject* result = f->m_fn(args, keywords);
|
||||
PyObject* result = args2 ? f->m_fn(args2.get(), 0) : 0;
|
||||
|
||||
// If the result is NULL but no error was set, m_fn failed
|
||||
// the argument-matching test.
|
||||
@@ -154,7 +223,10 @@ namespace
|
||||
|
||||
handle<function> not_implemented_function()
|
||||
{
|
||||
static object keeper(function_object(¬_implemented_impl, 2, 3));
|
||||
static object keeper(
|
||||
function_object(¬_implemented_impl, 2, 3
|
||||
, python::detail::keyword_range())
|
||||
);
|
||||
return handle<function>(borrowed(downcast<function>(keeper.ptr())));
|
||||
}
|
||||
}
|
||||
@@ -222,6 +294,19 @@ void function::add_to_namespace(
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute)
|
||||
{
|
||||
function::add_to_namespace(name_space, name, attribute);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute, char const* doc)
|
||||
{
|
||||
function::add_to_namespace(name_space, name, attribute, doc);
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
struct bind_return
|
||||
@@ -350,31 +435,35 @@ PyTypeObject function_type = {
|
||||
0 /* tp_new */
|
||||
};
|
||||
|
||||
object function_object_impl(py_function const& f, unsigned min_args, unsigned max_args)
|
||||
object function_object(
|
||||
py_function const& f, unsigned min_arity, unsigned max_arity
|
||||
, python::detail::keyword_range const& keywords)
|
||||
{
|
||||
return python::object(
|
||||
python::detail::new_non_null_reference(
|
||||
new function(f, min_args, max_args)));
|
||||
new function(
|
||||
f, min_arity, max_arity, keywords.first, keywords.second - keywords.first)));
|
||||
}
|
||||
|
||||
handle<> function_handle_impl(py_function const& f, unsigned min_args, unsigned max_args)
|
||||
object function_object(
|
||||
py_function const& f
|
||||
, unsigned arity
|
||||
, python::detail::keyword_range const& kw)
|
||||
{
|
||||
return function_object(f, arity, arity, kw);
|
||||
}
|
||||
|
||||
object function_object(py_function const& f, unsigned arity)
|
||||
{
|
||||
return function_object(f, arity, arity, python::detail::keyword_range());
|
||||
}
|
||||
|
||||
|
||||
handle<> function_handle_impl(py_function const& f, unsigned min_arity, unsigned max_arity)
|
||||
{
|
||||
return python::handle<>(
|
||||
allow_null(
|
||||
new function(f, min_args, max_args)));
|
||||
new function(f, min_arity, max_arity, 0, 0)));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute)
|
||||
{
|
||||
function::add_to_namespace(name_space, name, attribute);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute, char const* doc)
|
||||
{
|
||||
function::add_to_namespace(name_space, name, attribute, doc);
|
||||
}
|
||||
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/object/iterator_core.hpp>
|
||||
#include <boost/python/object/function.hpp>
|
||||
#include <boost/python/object/function_object.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
||||
@@ -54,10 +54,10 @@ rule bpl-test ( name ? : files * : requirements * )
|
||||
boost-python-runtest $(name) : $(py) <pyd>$(modules) ;
|
||||
}
|
||||
|
||||
bpl-test numpy ;
|
||||
|
||||
bpl-test enum ;
|
||||
bpl-test minimal ;
|
||||
bpl-test args ;
|
||||
bpl-test numpy ;
|
||||
bpl-test enum ;
|
||||
bpl-test docstring ;
|
||||
bpl-test exception_translator ;
|
||||
bpl-test pearu1 : test_cltree.py cltree.cpp ;
|
||||
|
||||
81
test/args.cpp
Normal file
81
test/args.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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_init.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/return_internal_reference.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
|
||||
{
|
||||
return make_tuple(x, y, z);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
|
||||
|
||||
typedef test_class<> Y;
|
||||
|
||||
struct X
|
||||
{
|
||||
X(int a0 = 0, int a1 = 1) : inner0(a0), inner1(a1) {}
|
||||
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
|
||||
{
|
||||
return make_tuple(x, y, z);
|
||||
}
|
||||
|
||||
Y const& inner(bool n) const { return n ? inner1 : inner0; }
|
||||
|
||||
Y inner0;
|
||||
Y inner1;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(args_ext)
|
||||
{
|
||||
def("f", f, args("x", "y", "z")
|
||||
, "This is f's docstring"
|
||||
);
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
|
||||
// MSVC6 gives a fatal error LNK1179: invalid or corrupt file:
|
||||
// duplicate comdat error if we try to re-use the exact type of f
|
||||
// here, so substitute long for int.
|
||||
tuple (*f)(long,double,char const*) = 0;
|
||||
#endif
|
||||
def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
|
||||
def("f2", f, f_overloads(args("x", "y", "z")));
|
||||
def("f3", f, f_overloads(args("x", "y", "z"), "f3's docstring"));
|
||||
|
||||
class_<Y>("Y", init<int>())
|
||||
.def("value", &Y::value)
|
||||
;
|
||||
|
||||
class_<X>("X", "This is X's docstring")
|
||||
.def(init<int, optional<int> >(args("a0", "a1")))
|
||||
.def("f", &X::f
|
||||
, "This is X.f's docstring"
|
||||
, args("x", "y", "z"))
|
||||
|
||||
// Just to prove that all the different argument combinations work
|
||||
.def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring")
|
||||
.def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n"))
|
||||
|
||||
.def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring")
|
||||
.def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n"))
|
||||
|
||||
.def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>())
|
||||
.def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>())
|
||||
|
||||
.def("f1", &X::f, X_f_overloads(args("x", "y", "z")))
|
||||
;
|
||||
|
||||
def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());
|
||||
}
|
||||
161
test/args.py
Normal file
161
test/args.py
Normal file
@@ -0,0 +1,161 @@
|
||||
"""
|
||||
>>> from args_ext import *
|
||||
|
||||
>>> f(x= 1, y = 3, z = 'hello')
|
||||
(1, 3.0, 'hello')
|
||||
|
||||
>>> f(z = 'hello', x = 3, y = 2.5)
|
||||
(3, 2.5, 'hello')
|
||||
|
||||
>>> f(1, z = 'hi', y = 3)
|
||||
(1, 3.0, 'hi')
|
||||
|
||||
>>> try: f(1, 2, 'hello', bar = 'baz')
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception: unknown keyword'
|
||||
|
||||
|
||||
Exercise the functions using default stubs
|
||||
|
||||
>>> f1(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> f1(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> f1(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> f1()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
>>> f2(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> f2(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> f2(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> f2()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
>>> f3(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> f3(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> f3(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> f3()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
Member function tests
|
||||
|
||||
>>> q = X()
|
||||
>>> q.f(x= 1, y = 3, z = 'hello')
|
||||
(1, 3.0, 'hello')
|
||||
|
||||
>>> q.f(z = 'hello', x = 3, y = 2.5)
|
||||
(3, 2.5, 'hello')
|
||||
|
||||
>>> q.f(1, z = 'hi', y = 3)
|
||||
(1, 3.0, 'hi')
|
||||
|
||||
>>> try: q.f(1, 2, 'hello', bar = 'baz')
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception: unknown keyword'
|
||||
|
||||
Exercise member functions using default stubs
|
||||
|
||||
>>> q.f1(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> q.f1(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> q.f1(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> q.f1()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
>>> X.f.__doc__
|
||||
"This is X.f's docstring"
|
||||
|
||||
>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5)
|
||||
>>> for f in xfuncs:
|
||||
... print f(q,1).value(),
|
||||
... print f(q, n = 1).value(),
|
||||
... print f(q, n = 0).value(),
|
||||
... print f.__doc__
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
|
||||
>>> x = X(a1 = 44, a0 = 22)
|
||||
>>> x.inner0(0).value()
|
||||
22
|
||||
>>> x.inner0(1).value()
|
||||
44
|
||||
|
||||
>>> x = X(a0 = 7)
|
||||
>>> x.inner0(0).value()
|
||||
7
|
||||
>>> x.inner0(1).value()
|
||||
1
|
||||
|
||||
>>> inner(n = 1, self = q).value()
|
||||
1
|
||||
"""
|
||||
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])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 // works around a name lookup bug
|
||||
# define C C_
|
||||
#endif
|
||||
struct C {};
|
||||
|
||||
struct D {};
|
||||
|
||||
Reference in New Issue
Block a user