From dd31026cc96129b0cefbe9932236861157cbfa56 Mon Sep 17 00:00:00 2001
From: Petr Machata <pmachata@redhat.com>
Date: Thu, 5 Sep 2013 23:20:57 +0200
Subject: [PATCH 2/3] [python] Convert a number of assertion constructs to
BOOST_MPL_ASSERT_MSG
- There are a number of separate mechanisms involving typedefs that
simulate a functionality similar to BOOST_STATIC_ASSERT or
BOOST_MPL_ASSERT_MSG. Instead of reinventing the wheel, we just use
the latter--that because unlike the former, it allows us to specify
an error message.
---
boost/python/args_fwd.hpp | 9 ---------
boost/python/class.hpp | 24 +++++-------------------
boost/python/def.hpp | 7 ++++---
boost/python/detail/defaults_gen.hpp | 11 +++++------
boost/python/init.hpp | 20 +++++---------------
boost/python/make_constructor.hpp | 5 ++---
boost/python/make_function.hpp | 9 ++++-----
boost/python/object/pickle_support.hpp | 10 +++-------
8 files changed, 28 insertions(+), 67 deletions(-)
diff --git a/boost/python/args_fwd.hpp b/boost/python/args_fwd.hpp
index 3923946..83933f4 100644
a
|
b
|
namespace detail
|
36 | 36 | BOOST_STATIC_CONSTANT(std::size_t, size = 0); |
37 | 37 | static keyword_range range() { return keyword_range(); } |
38 | 38 | }; |
39 | | |
40 | | namespace error |
41 | | { |
42 | | template <int keywords, int function_args> |
43 | | struct more_keywords_than_function_arguments |
44 | | { |
45 | | typedef char too_many_keywords[keywords > function_args ? -1 : 1]; |
46 | | }; |
47 | | } |
48 | 39 | } |
49 | 40 | |
50 | 41 | }} // namespace boost::python |
diff --git a/boost/python/class.hpp b/boost/python/class.hpp
index 253667b..a8e4111 100644
a
|
b
|
|
39 | 39 | # include <boost/mpl/for_each.hpp> |
40 | 40 | # include <boost/mpl/bool.hpp> |
41 | 41 | # include <boost/mpl/not.hpp> |
| 42 | # include <boost/mpl/assert.hpp> |
42 | 43 | |
43 | 44 | # include <boost/detail/workaround.hpp> |
44 | 45 | |
… |
… |
namespace detail
|
107 | 108 | namespace error |
108 | 109 | { |
109 | 110 | // |
110 | | // A meta-assertion mechanism which prints nice error messages and |
111 | | // backtraces on lots of compilers. Usage: |
112 | | // |
113 | | // assertion<C>::failed |
114 | | // |
115 | | // where C is an MPL metafunction class |
116 | | // |
117 | | |
118 | | template <class C> struct assertion_failed { }; |
119 | | template <class C> struct assertion_ok { typedef C failed; }; |
120 | | |
121 | | template <class C> |
122 | | struct assertion |
123 | | : mpl::if_<C, assertion_ok<C>, assertion_failed<C> >::type |
124 | | {}; |
125 | | |
126 | | // |
127 | 111 | // Checks for validity of arguments used to define virtual |
128 | 112 | // functions with default implementations. |
129 | 113 | // |
… |
… |
namespace detail
|
141 | 125 | // https://svn.boost.org/trac/boost/ticket/5803 |
142 | 126 | //typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0; |
143 | 127 | # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) |
144 | | typedef typename assertion<is_polymorphic<T> >::failed test1; |
| 128 | BOOST_MPL_ASSERT_MSG(is_polymorphic<T>::value, |
| 129 | NOT_POLYMORPHIC, (T)); |
145 | 130 | # endif |
146 | | typedef typename assertion<is_member_function_pointer<Fn> >::failed test2; |
| 131 | BOOST_MPL_ASSERT_MSG(is_member_function_pointer<Fn>::value, |
| 132 | NOT_MEMBER_FUNCTION_POINTER, (Fn)); |
147 | 133 | not_a_derived_class_member<Default>(Fn()); |
148 | 134 | } |
149 | 135 | }; |
diff --git a/boost/python/def.hpp b/boost/python/def.hpp
index 76829b0..bde35f3 100644
a
|
b
|
|
15 | 15 | # include <boost/python/signature.hpp> |
16 | 16 | # include <boost/python/detail/scope.hpp> |
17 | 17 | |
| 18 | # include <boost/mpl/assert.hpp> |
| 19 | |
18 | 20 | namespace boost { namespace python { |
19 | 21 | |
20 | 22 | namespace detail |
… |
… |
namespace detail
|
35 | 37 | char const* name, F const& fn, Helper const& helper) |
36 | 38 | { |
37 | 39 | // Must not try to use default implementations except with method definitions. |
38 | | typedef typename error::multiple_functions_passed_to_def< |
39 | | Helper::has_default_implementation |
40 | | >::type assertion; |
| 40 | BOOST_MPL_ASSERT_MSG(!Helper::has_default_implementation, |
| 41 | MULTIPLE_FUNCTIONS_PASSED_TO_DEF, (Helper)); |
41 | 42 | |
42 | 43 | detail::scope_setattr_doc( |
43 | 44 | name, boost::python::make_function( |
diff --git a/boost/python/detail/defaults_gen.hpp b/boost/python/detail/defaults_gen.hpp
index 0b3e0e2..f77912e 100644
a
|
b
|
|
26 | 26 | #include <boost/mpl/begin_end.hpp> |
27 | 27 | #include <boost/mpl/next.hpp> |
28 | 28 | #include <boost/mpl/deref.hpp> |
| 29 | #include <boost/mpl/assert.hpp> |
29 | 30 | #include <cstddef> |
30 | 31 | |
31 | 32 | namespace boost { namespace python { |
… |
… |
namespace detail
|
211 | 212 | : ::boost::python::detail::overloads_common<fstubs_name>( \ |
212 | 213 | doc, keywords.range()) \ |
213 | 214 | { \ |
214 | | typedef typename ::boost::python::detail:: \ |
215 | | error::more_keywords_than_function_arguments< \ |
216 | | N,n_args>::too_many_keywords assertion; \ |
| 215 | BOOST_MPL_ASSERT_MSG(N <= n_args, \ |
| 216 | MORE_KEYWORDS_THAN_FUNCTION_ARGUMENTS, ()); \ |
217 | 217 | } \ |
218 | 218 | template <std::size_t N> \ |
219 | 219 | fstubs_name(::boost::python::detail::keywords<N> const& keywords, char const* doc = 0) \ |
220 | 220 | : ::boost::python::detail::overloads_common<fstubs_name>( \ |
221 | 221 | doc, keywords.range()) \ |
222 | 222 | { \ |
223 | | typedef typename ::boost::python::detail:: \ |
224 | | error::more_keywords_than_function_arguments< \ |
225 | | N,n_args>::too_many_keywords assertion; \ |
| 223 | BOOST_MPL_ASSERT_MSG(N <= n_args, \ |
| 224 | MORE_KEYWORDS_THAN_FUNCTION_ARGUMENTS, ()); \ |
226 | 225 | } |
227 | 226 | |
228 | 227 | # if defined(BOOST_NO_VOID_RETURNS) |
diff --git a/boost/python/init.hpp b/boost/python/init.hpp
index 6598fd3..c9edea9 100644
a
|
b
|
|
26 | 26 | #include <boost/mpl/prior.hpp> |
27 | 27 | #include <boost/mpl/joint_view.hpp> |
28 | 28 | #include <boost/mpl/back.hpp> |
| 29 | #include <boost/mpl/assert.hpp> |
29 | 30 | |
30 | 31 | #include <boost/type_traits/is_same.hpp> |
31 | 32 | |
… |
… |
struct optional; // forward declaration
|
63 | 64 | |
64 | 65 | namespace detail |
65 | 66 | { |
66 | | namespace error |
67 | | { |
68 | | template <int keywords, int init_args> |
69 | | struct more_keywords_than_init_arguments |
70 | | { |
71 | | typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1]; |
72 | | }; |
73 | | } |
74 | | |
75 | 67 | // is_optional<T>::value |
76 | 68 | // |
77 | 69 | // This metaprogram checks if T is an optional |
… |
… |
class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
|
244 | 236 | init(char const* doc_, detail::keywords<N> const& kw) |
245 | 237 | : base(doc_, kw.range()) |
246 | 238 | { |
247 | | typedef typename detail::error::more_keywords_than_init_arguments< |
248 | | N, n_arguments::value + 1 |
249 | | >::too_many_keywords assertion; |
| 239 | BOOST_MPL_ASSERT_MSG(N <= n_arguments::value + 1, |
| 240 | MORE_KEYWORDS_THAN_INIT_ARGUMENTS, ()); |
250 | 241 | } |
251 | 242 | |
252 | 243 | template <std::size_t N> |
253 | 244 | init(detail::keywords<N> const& kw, char const* doc_ = 0) |
254 | 245 | : base(doc_, kw.range()) |
255 | 246 | { |
256 | | typedef typename detail::error::more_keywords_than_init_arguments< |
257 | | N, n_arguments::value + 1 |
258 | | >::too_many_keywords assertion; |
| 247 | BOOST_MPL_ASSERT_MSG(N <= n_arguments::value + 1, |
| 248 | MORE_KEYWORDS_THAN_INIT_ARGUMENTS, ()); |
259 | 249 | } |
260 | 250 | |
261 | 251 | template <class CallPoliciesT> |
diff --git a/boost/python/make_constructor.hpp b/boost/python/make_constructor.hpp
index 8ae722b..597b679 100644
a
|
b
|
namespace detail
|
181 | 181 | { |
182 | 182 | enum { arity = mpl::size<Sig>::value - 1 }; |
183 | 183 | |
184 | | typedef typename detail::error::more_keywords_than_function_arguments< |
185 | | NumKeywords::value, arity |
186 | | >::too_many_keywords assertion; |
| 184 | BOOST_MPL_ASSERT_MSG(NumKeywords::value <= arity, |
| 185 | MORE_KEYWORDS_THAN_FUNCTION_ARGUMENTS, ()); |
187 | 186 | |
188 | 187 | typedef typename outer_constructor_signature<Sig>::type outer_signature; |
189 | 188 | |
diff --git a/boost/python/make_function.hpp b/boost/python/make_function.hpp
index f2f2a9e..68751f3 100644
a
|
b
|
|
15 | 15 | |
16 | 16 | # include <boost/mpl/size.hpp> |
17 | 17 | # include <boost/mpl/int.hpp> |
| 18 | # include <boost/mpl/assert.hpp> |
18 | 19 | |
19 | 20 | namespace boost { namespace python { |
20 | 21 | |
… |
… |
namespace detail
|
52 | 53 | ) |
53 | 54 | { |
54 | 55 | enum { arity = mpl::size<Sig>::value - 1 }; |
55 | | |
56 | | typedef typename detail::error::more_keywords_than_function_arguments< |
57 | | NumKeywords::value, arity |
58 | | >::too_many_keywords assertion; |
59 | | |
| 56 | BOOST_MPL_ASSERT_MSG(NumKeywords::value <= arity, |
| 57 | MORE_KEYWORDS_THAN_FUNCTION_ARGUMENTS, ()); |
| 58 | |
60 | 59 | return objects::function_object( |
61 | 60 | detail::caller<F,CallPolicies,Sig>(f, p) |
62 | 61 | , kw); |
diff --git a/boost/python/object/pickle_support.hpp b/boost/python/object/pickle_support.hpp
index cbdbcbb..097fcfc 100644
a
|
b
|
|
6 | 6 | # define BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP |
7 | 7 | |
8 | 8 | # include <boost/python/detail/prefix.hpp> |
| 9 | # include <boost/mpl/assert.hpp> |
9 | 10 | |
10 | 11 | namespace boost { namespace python { |
11 | 12 | |
… |
… |
BOOST_PYTHON_DECL object const& make_instance_reduce_function();
|
21 | 22 | struct pickle_suite; |
22 | 23 | |
23 | 24 | namespace error_messages { |
24 | | |
25 | | template <class T> |
26 | | struct missing_pickle_suite_function_or_incorrect_signature {}; |
27 | | |
28 | 25 | inline void must_be_derived_from_pickle_suite(pickle_suite const&) {} |
29 | 26 | } |
30 | 27 | |
… |
… |
namespace detail {
|
105 | 102 | Class_&, |
106 | 103 | ...) |
107 | 104 | { |
108 | | typedef typename |
109 | | error_messages::missing_pickle_suite_function_or_incorrect_signature< |
110 | | Class_>::error_type error_type; |
| 105 | BOOST_MPL_ASSERT_MSG |
| 106 | (false, MISSING_PICKLE_SUITE_FUNCTION_OR_INCORRECT_SIGNATURE, ()); |
111 | 107 | } |
112 | 108 | }; |
113 | 109 | |