diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index aed14276..c10985e0 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -32,10 +32,12 @@ namespace boost { namespace python { +typedef detail::keywords<1> arg; + namespace detail { template - struct keywords + struct keywords_base { BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords); @@ -44,19 +46,45 @@ namespace detail return keyword_range(elements, elements + nkeywords); } - keywords operator,(const keywords<1> &k) const - { - python::detail::keywords res; - std::copy(elements, elements+size, res.elements); - res.elements[size] = k.elements[0]; - return res; - } - - keywords operator,(const char *name) const; - keyword elements[nkeywords]; }; + + template + struct keywords : keywords_base + { + }; + template <> + struct keywords<1> : keywords_base<1> + { + explicit keywords(char const *name) + { + elements[0].name = name; + } + + template + arg& operator=(T const& value) + { + object z(value); + elements[0].default_value = handle<>(python::borrowed(object(value).ptr())); + return *this; + } + + operator detail::keyword const&() const + { + return elements[0]; + } + }; + + template + keywords operator,(keywords const& l, const keywords<1> &k) + { + python::detail::keywords res; + std::copy(l.elements, l.elements+nkeywords, res.elements); + res.elements[nkeywords] = k.elements[0]; + return res; + } + # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct is_keywords @@ -112,37 +140,21 @@ namespace detail class old_edg_workaround_for_arg { friend class arg; }; #endif -struct arg : detail::keywords<1> -{ - explicit arg(char const *name) - { - elements[0].name = name; - } - - template - arg& operator=(T const& value) - { - object z(value); - elements[0].default_value = handle<>(python::borrowed(object(value).ptr())); - return *this; - } - - operator detail::keyword const&() const - { - return elements[0]; - } -}; - namespace detail { template inline keywords - keywords::operator,(const char *name) const + operator,(keywords const& l, char *name) { - return this->operator,(arg(name)); + return l.operator,(arg(name)); } } +inline detail::keywords<1> args(char const* name) +{ + return detail::keywords<1>(name); +} + # define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n; # define BOOST_PP_LOCAL_MACRO(n) \ inline detail::keywords args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \ @@ -151,7 +163,7 @@ inline detail::keywords args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \ return result; \ } -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) +# define BOOST_PP_LOCAL_LIMITS (2, BOOST_PYTHON_MAX_ARITY) # include BOOST_PP_LOCAL_ITERATE() }} // namespace boost::python diff --git a/test/keywords.cpp b/test/keywords.cpp index 36205656..04e6da32 100755 --- a/test/keywords.cpp +++ b/test/keywords.cpp @@ -56,6 +56,11 @@ struct Bar n_ = n; } + void seta(int a) + { + a_ = a; + } + int geta() const { return a_; } double getb() const { return b_; } @@ -71,37 +76,34 @@ private: BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(bar_set, Bar::set, 0,3) using namespace boost::python; -#if BOOST_WORKAROUND(__GNUC__, == 2) -using boost::python::arg; -#endif BOOST_PYTHON_MODULE(keywords) { - class_("Foo" , init< - int - , double - , const std::string & - >( - ( arg("a") = 0 - , arg("b") = 0.0 - , arg("n") = std::string() - ) - )) +#if BOOST_WORKAROUND(__GNUC__, == 2) + using boost::python::arg; +#endif + + class_( + "Foo" + , init( + ( arg("a") = 0 + , arg("b") = 0.0 + , arg("n") = std::string() + ) + )) .def("set", &Foo::set, (arg("a") = 0, arg("b") = 0.0, arg("n") = std::string()) ) + .def("a", &Foo::geta) .def("b", &Foo::getb) .def("n", &Foo::getn) ; - class_("Bar" , init - >() - ) - + class_("Bar" + , init >() + ) .def("set", &Bar::set, bar_set()) + .def("seta", &Bar::seta, arg("a")) + .def("a", &Bar::geta) .def("b", &Bar::getb) .def("n", &Bar::getn)