diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 733973b1..d9f0e5c3 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -36,26 +36,20 @@ /////////////////////////////////////////////////////////////////////////////// #define BOOST_PYTHON_TEMPLATE_TYPES_WITH_DEFAULT \ - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT \ - ( \ + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ BOOST_PYTHON_MAX_ARITY, \ class T, \ - mpl::void_ \ - ) \ + mpl::void_) \ #define BOOST_PYTHON_TEMPLATE_TYPES \ - BOOST_PP_ENUM_PARAMS \ - ( \ + BOOST_PP_ENUM_PARAMS( \ BOOST_PYTHON_MAX_ARITY, \ - class T \ - ) \ + class T) \ #define BOOST_PYTHON_TEMPLATE_ARGS \ - BOOST_PP_ENUM_PARAMS \ - ( \ + BOOST_PP_ENUM_PARAMS( \ BOOST_PYTHON_MAX_ARITY, \ - T \ - ) \ + T) \ /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { @@ -94,7 +88,7 @@ namespace detail { bool, value = sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); typedef mpl::bool_c type; - + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) // needed for MSVC & Borland }; @@ -123,16 +117,62 @@ namespace detail { } // namespace detail +template +struct init_base { + + DerivedT const& derived() const + { return *static_cast(this); } +}; + +template +struct init_with_call_policies +: public init_base > +{ + 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_) {} + + char const* doc_string() const + { return doc; } + + CallPoliciesT + call_policies() const + { return policies; } + + CallPoliciesT policies; + char const* doc; +}; template -struct init //: detail::check_init_params +struct init : public init_base > { + typedef init self_t; + + init(char const* doc_ = 0) + : doc(doc_) {} + + char const* doc_string() const + { return doc; } + + default_call_policies + call_policies() const + { return default_call_policies(); } + + template + init_with_call_policies + operator[](CallPoliciesT const& policies) const + { return init_with_call_policies(policies, doc); } + typedef detail::type_list signature_; typedef typename mpl::end::type finish; // Find the optional<> element, if any typedef typename mpl::find_if< - signature_, detail::is_optional + signature_, detail::is_optional >::type opt; @@ -143,7 +183,7 @@ struct init //: detail::check_init_params , mpl::next >::type expected_finish; BOOST_STATIC_ASSERT((is_same::value)); - + typedef typename mpl::apply_if< is_same , mpl::list0<> @@ -162,17 +202,47 @@ struct init //: detail::check_init_params typedef typename mpl::fold< required_args , mpl::list0<> - , mpl::push_front + , mpl::push_front<> >::type reversed_required; typedef typename mpl::fold< optional_args , reversed_required - , mpl::push_front + , mpl::push_front<> >::type reversed_args; // Count the maximum number of arguments BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); + + char const* doc; +}; + +template <> // specialization for zero args +struct init<> : public init_base > +{ + typedef init<> self_t; + + init(char const* doc_ = 0) + : doc(doc_) {} + + char const* doc_string() const + { return doc; } + + default_call_policies + call_policies() const + { return default_call_policies(); } + + template + init_with_call_policies + operator[](CallPoliciesT const& policies) const + { return init_with_call_policies(policies, doc); } + + BOOST_STATIC_CONSTANT(int, n_defaults = 0); + BOOST_STATIC_CONSTANT(int, n_arguments = 0); + + typedef detail::type_list<> reversed_args; + + char const* doc; }; /////////////////////////////////////////////////////////////////////////////// @@ -196,12 +266,12 @@ namespace detail typedef typename mpl::fold< ReversedArgs , mpl::list0<> - , mpl::push_front + , mpl::push_front<> >::type args; - + cl.def_init(args(), policies, doc); } - + /////////////////////////////////////////////////////////////////////////////// // // define_class_init_helper::apply @@ -269,12 +339,13 @@ namespace detail // __init__(int) // /////////////////////////////////////////////////////////////////////////////// -template +template void -define_init(ClassT& cl, InitT const& i, CallPoliciesT const& policies, char const* doc) +define_init(ClassT& cl, InitT const& i) { typedef typename InitT::reversed_args reversed_args; - detail::define_class_init_helper::apply(cl, policies, reversed_args(), doc); + detail::define_class_init_helper::apply( + cl, i.call_policies(), reversed_args(), i.doc_string()); } }} // namespace boost::python