Skip to content

Commit ef7d675

Browse files
committed
bug fix for a single use of arg with no comma operator
[SVN r20533]
1 parent 2b9d29a commit ef7d675

2 files changed

Lines changed: 69 additions & 55 deletions

File tree

include/boost/python/args.hpp

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@
3232

3333
namespace boost { namespace python {
3434

35+
typedef detail::keywords<1> arg;
36+
3537
namespace detail
3638
{
3739
template <std::size_t nkeywords>
38-
struct keywords
40+
struct keywords_base
3941
{
4042
BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
4143

@@ -44,19 +46,45 @@ namespace detail
4446
return keyword_range(elements, elements + nkeywords);
4547
}
4648

47-
keywords<nkeywords+1> operator,(const keywords<1> &k) const
49+
keyword elements[nkeywords];
50+
};
51+
52+
template <std::size_t nkeywords>
53+
struct keywords : keywords_base<nkeywords>
54+
{
55+
};
56+
57+
template <>
58+
struct keywords<1> : keywords_base<1>
59+
{
60+
explicit keywords(char const *name)
4861
{
49-
python::detail::keywords<size+1> res;
50-
std::copy(elements, elements+size, res.elements);
51-
res.elements[size] = k.elements[0];
52-
return res;
62+
elements[0].name = name;
63+
}
64+
65+
template <class T>
66+
arg& operator=(T const& value)
67+
{
68+
object z(value);
69+
elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
70+
return *this;
71+
}
72+
73+
operator detail::keyword const&() const
74+
{
75+
return elements[0];
5376
}
54-
55-
keywords<nkeywords+1> operator,(const char *name) const;
56-
57-
keyword elements[nkeywords];
5877
};
5978

79+
template <std::size_t nkeywords>
80+
keywords<nkeywords+1> operator,(keywords<nkeywords> const& l, const keywords<1> &k)
81+
{
82+
python::detail::keywords<nkeywords+1> res;
83+
std::copy(l.elements, l.elements+nkeywords, res.elements);
84+
res.elements[nkeywords] = k.elements[0];
85+
return res;
86+
}
87+
6088
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
6189
template<typename T>
6290
struct is_keywords
@@ -112,37 +140,21 @@ namespace detail
112140
class old_edg_workaround_for_arg { friend class arg; };
113141
#endif
114142

115-
struct arg : detail::keywords<1>
116-
{
117-
explicit arg(char const *name)
118-
{
119-
elements[0].name = name;
120-
}
121-
122-
template <class T>
123-
arg& operator=(T const& value)
124-
{
125-
object z(value);
126-
elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
127-
return *this;
128-
}
129-
130-
operator detail::keyword const&() const
131-
{
132-
return elements[0];
133-
}
134-
};
135-
136143
namespace detail
137144
{
138145
template <std::size_t nkeywords>
139146
inline keywords<nkeywords + 1>
140-
keywords<nkeywords>::operator,(const char *name) const
147+
operator,(keywords<nkeywords> const& l, char *name)
141148
{
142-
return this->operator,(arg(name));
149+
return l.operator,(arg(name));
143150
}
144151
}
145152

153+
inline detail::keywords<1> args(char const* name)
154+
{
155+
return detail::keywords<1>(name);
156+
}
157+
146158
# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
147159
# define BOOST_PP_LOCAL_MACRO(n) \
148160
inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
@@ -151,7 +163,7 @@ inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name))
151163
BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
152164
return result; \
153165
}
154-
# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY)
166+
# define BOOST_PP_LOCAL_LIMITS (2, BOOST_PYTHON_MAX_ARITY)
155167
# include BOOST_PP_LOCAL_ITERATE()
156168

157169
}} // namespace boost::python

test/keywords.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ struct Bar
5656
n_ = n;
5757
}
5858

59+
void seta(int a)
60+
{
61+
a_ = a;
62+
}
63+
5964
int geta() const { return a_; }
6065

6166
double getb() const { return b_; }
@@ -71,37 +76,34 @@ struct Bar
7176
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(bar_set, Bar::set, 0,3)
7277

7378
using namespace boost::python;
74-
#if BOOST_WORKAROUND(__GNUC__, == 2)
75-
using boost::python::arg;
76-
#endif
7779
BOOST_PYTHON_MODULE(keywords)
7880
{
79-
class_<Foo>("Foo" , init<
80-
int
81-
, double
82-
, const std::string &
83-
>(
84-
( arg("a") = 0
85-
, arg("b") = 0.0
86-
, arg("n") = std::string()
87-
)
88-
))
81+
#if BOOST_WORKAROUND(__GNUC__, == 2)
82+
using boost::python::arg;
83+
#endif
84+
85+
class_<Foo>(
86+
"Foo"
87+
, init<int, double, const std::string&>(
88+
( arg("a") = 0
89+
, arg("b") = 0.0
90+
, arg("n") = std::string()
91+
)
92+
))
8993

9094
.def("set", &Foo::set, (arg("a") = 0, arg("b") = 0.0, arg("n") = std::string()) )
95+
9196
.def("a", &Foo::geta)
9297
.def("b", &Foo::getb)
9398
.def("n", &Foo::getn)
9499
;
95100

96-
class_<Bar>("Bar" , init<optional<
97-
int
98-
, double
99-
, const std::string &
100-
>
101-
>()
102-
)
103-
101+
class_<Bar>("Bar"
102+
, init<optional<int, double, const std::string &> >()
103+
)
104104
.def("set", &Bar::set, bar_set())
105+
.def("seta", &Bar::seta, arg("a"))
106+
105107
.def("a", &Bar::geta)
106108
.def("b", &Bar::getb)
107109
.def("n", &Bar::getn)

0 commit comments

Comments
 (0)