Skip to content

Commit 66d6272

Browse files
committed
Use mpl::vector and simplify constructor generation so we don't have
to constantly reverse lists. [SVN r18487]
1 parent 2f1b828 commit 66d6272

4 files changed

Lines changed: 100 additions & 120 deletions

File tree

include/boost/python/detail/type_list.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@
1616
# define BOOST_PYTHON_BASE_LIST_SIZE BOOST_PYTHON_MAX_BASES
1717
# endif
1818

19-
// Compute the MPL list header to use for lists up to BOOST_PYTHON_LIST_SIZE in length
19+
// Compute the MPL vector header to use for lists up to BOOST_PYTHON_LIST_SIZE in length
2020
# if BOOST_PYTHON_LIST_SIZE > 48
2121
# error Arities above 48 not supported by Boost.Python due to MPL internal limit
2222
# elif BOOST_PYTHON_LIST_SIZE > 38
23-
# include <boost/mpl/list/list50.hpp>
23+
# include <boost/mpl/vector/vector50.hpp>
2424
# elif BOOST_PYTHON_LIST_SIZE > 28
25-
# include <boost/mpl/list/list40.hpp>
25+
# include <boost/mpl/vector/vector40.hpp>
2626
# elif BOOST_PYTHON_LIST_SIZE > 18
27-
# include <boost/mpl/list/list30.hpp>
27+
# include <boost/mpl/vector/vector30.hpp>
2828
# elif BOOST_PYTHON_LIST_SIZE > 8
29-
# include <boost/mpl/list/list20.hpp>
29+
# include <boost/mpl/vector/vector20.hpp>
3030
# else
31-
# include <boost/mpl/list/list10.hpp>
31+
# include <boost/mpl/vector/vector10.hpp>
3232
# endif
3333

3434
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

include/boost/python/detail/type_list_impl.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace boost { namespace python { namespace detail {
2121

2222
template <BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_)>
2323
struct type_list
24-
: BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE)<BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_LIST_SIZE, T)>
24+
: BOOST_PP_CAT(mpl::vector,BOOST_PYTHON_LIST_SIZE)<BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_LIST_SIZE, T)>
2525
{
2626
};
2727

@@ -48,7 +48,7 @@ struct type_list<
4848
BOOST_PP_ENUM(
4949
BOOST_PYTHON_VOID_ARGS, BOOST_PYTHON_FIXED, mpl::void_)
5050
>
51-
: BOOST_PP_CAT(mpl::list,N)<BOOST_PP_ENUM_PARAMS_Z(1, N, T)>
51+
: BOOST_PP_CAT(mpl::vector,N)<BOOST_PP_ENUM_PARAMS_Z(1, N, T)>
5252
{
5353
};
5454

include/boost/python/detail/type_list_impl_no_pts.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ struct type_list_impl_chooser<N>
9797
>
9898
struct result_
9999
{
100-
typedef typename BOOST_PP_CAT(mpl::list,N)<
100+
typedef typename BOOST_PP_CAT(mpl::vector,N)<
101101
BOOST_PP_ENUM_PARAMS(N, T)
102102
>::type type;
103103
};

include/boost/python/init.hpp

Lines changed: 91 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,21 @@
1414
#include <boost/python/args_fwd.hpp>
1515
#include <boost/python/detail/make_keyword_range_fn.hpp>
1616

17-
#include <boost/mpl/fold_backward.hpp>
1817
#include <boost/mpl/if.hpp>
1918
#include <boost/mpl/apply_if.hpp>
20-
#include <boost/mpl/at.hpp>
2119
#include <boost/mpl/size.hpp>
22-
#include <boost/mpl/push_front.hpp>
2320
#include <boost/mpl/iterator_range.hpp>
24-
#include <boost/mpl/not.hpp>
25-
26-
# include <boost/python/detail/mpl_lambda.hpp>
27-
28-
#include <boost/mpl/lambda.hpp>
21+
#include <boost/mpl/empty.hpp>
2922
#include <boost/mpl/begin_end.hpp>
30-
#include <boost/mpl/find_if.hpp>
31-
#include <boost/mpl/fold.hpp>
32-
#include <boost/mpl/pop_front.hpp>
3323
#include <boost/mpl/bool.hpp>
24+
#include <boost/mpl/prior.hpp>
25+
#include <boost/mpl/joint_view.hpp>
26+
#include <boost/mpl/back.hpp>
3427

3528
#include <boost/type_traits/is_same.hpp>
3629

37-
#include <boost/static_assert.hpp>
3830
#include <boost/preprocessor/enum_params_with_a_default.hpp>
3931
#include <boost/preprocessor/enum_params.hpp>
40-
#include <boost/preprocessor/enum_params.hpp>
41-
#include <boost/preprocessor/repeat.hpp>
4232

4333
#include <utility>
4434

@@ -80,14 +70,11 @@ namespace detail
8070
};
8171
}
8272

83-
///////////////////////////////////////////////////////////////////////////
84-
//
85-
// is_optional<T>::value
86-
//
87-
// This metaprogram checks if T is an optional
88-
//
89-
///////////////////////////////////////////////////////////////////////////
90-
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
73+
// is_optional<T>::value
74+
//
75+
// This metaprogram checks if T is an optional
76+
//
77+
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
9178

9279
template <class T>
9380
struct is_optional {
@@ -105,32 +92,21 @@ namespace detail
10592
bool, value =
10693
sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
10794
typedef mpl::bool_<value> type;
108-
109-
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T))
11095
};
11196

112-
///////////////////////////////////////
113-
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
97+
#else
11498

11599
template <class T>
116-
struct is_optional_impl {
117-
118-
BOOST_STATIC_CONSTANT(bool, value = false);
119-
};
100+
struct is_optional
101+
: mpl::false_
102+
{};
120103

121104
template <BOOST_PYTHON_OVERLOAD_TYPES>
122-
struct is_optional_impl<optional<BOOST_PYTHON_OVERLOAD_ARGS> > {
123-
124-
BOOST_STATIC_CONSTANT(bool, value = true);
125-
};
126-
127-
template <class T>
128-
struct is_optional : is_optional_impl<T>
129-
{
130-
typedef mpl::bool_<is_optional_impl<T>::value> type;
131-
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T))
132-
};
133-
#endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
105+
struct is_optional<optional<BOOST_PYTHON_OVERLOAD_ARGS> >
106+
: mpl::true_
107+
{};
108+
109+
#endif
134110

135111
} // namespace detail
136112

@@ -176,10 +152,9 @@ class init_with_call_policies
176152
{
177153
typedef init_base<init_with_call_policies<CallPoliciesT, InitT> > base;
178154
public:
179-
BOOST_STATIC_CONSTANT(int, n_arguments = InitT::n_arguments);
180-
BOOST_STATIC_CONSTANT(int, n_defaults = InitT::n_defaults);
181-
182-
typedef typename InitT::reversed_args reversed_args;
155+
typedef typename InitT::n_arguments n_arguments;
156+
typedef typename InitT::n_defaults n_defaults;
157+
typedef typename InitT::signature signature;
183158

184159
init_with_call_policies(
185160
CallPoliciesT const& policies_
@@ -199,6 +174,22 @@ class init_with_call_policies
199174
CallPoliciesT m_policies;
200175
};
201176

177+
//
178+
// drop1<S> is the initial length(S) elements of S
179+
//
180+
namespace detail
181+
{
182+
template <class S>
183+
struct drop1
184+
: mpl::iterator_range<
185+
typename mpl::begin<S>::type
186+
, typename mpl::prior<
187+
typename mpl::end<S>::type
188+
>::type
189+
>
190+
{};
191+
}
192+
202193
template <BOOST_PYTHON_OVERLOAD_TYPES>
203194
class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
204195
{
@@ -216,7 +207,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
216207
: base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size))
217208
{
218209
typedef typename detail::error::more_keywords_than_init_arguments<
219-
Keywords::size, n_arguments
210+
Keywords::size, n_arguments::value
220211
>::too_many_keywords assertion;
221212
}
222213

@@ -225,7 +216,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
225216
: base(doc_, kw.range())
226217
{
227218
typedef typename detail::error::more_keywords_than_init_arguments<
228-
Keywords::size, n_arguments
219+
Keywords::size, n_arguments::value
229220
>::too_many_keywords assertion;
230221
}
231222

@@ -238,51 +229,39 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
238229
}
239230

240231
typedef detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS> signature_;
241-
typedef typename mpl::end<signature_>::type finish;
242-
243-
// Find the optional<> element, if any
244-
typedef typename mpl::find_if<
245-
signature_, detail::is_optional<mpl::_>
246-
>::type opt;
247232

248-
249-
// Check to make sure the optional<> element, if any, is the last one
233+
typedef detail::is_optional<
234+
typename mpl::apply_if<
235+
mpl::empty<signature_>
236+
, mpl::false_
237+
, mpl::back<signature_>
238+
>::type
239+
> back_is_optional;
240+
250241
typedef typename mpl::apply_if<
251-
is_same<opt,finish>
252-
, mpl::identity<opt>
253-
, mpl::next<opt>
254-
>::type expected_finish;
255-
BOOST_STATIC_ASSERT((is_same<expected_finish, finish>::value));
242+
back_is_optional
243+
, mpl::back<signature_>
244+
, mpl::vector0<>
245+
>::type optional_args;
256246

257247
typedef typename mpl::apply_if<
258-
is_same<opt,finish>
259-
, mpl::list0<>
260-
, opt
261-
>::type optional_args;
248+
back_is_optional
249+
, mpl::if_<
250+
mpl::empty<optional_args>
251+
, detail::drop1<signature_>
252+
, mpl::joint_view<
253+
detail::drop1<signature_>
254+
, optional_args
255+
>
256+
>
257+
, signature_
258+
>::type signature;
259+
260+
// TODO: static assert to make sure there are no other optional elements
262261

263262
// Count the number of default args
264-
BOOST_STATIC_CONSTANT(int, n_defaults = mpl::size<optional_args>::value);
265-
266-
typedef typename mpl::iterator_range<
267-
typename mpl::begin<signature_>::type
268-
, opt
269-
>::type required_args;
270-
271-
// Build a reverse image of all the args, including optionals
272-
typedef typename mpl::fold<
273-
required_args
274-
, mpl::list0<>
275-
, mpl::push_front<>
276-
>::type reversed_required;
277-
278-
typedef typename mpl::fold<
279-
optional_args
280-
, reversed_required
281-
, mpl::push_front<>
282-
>::type reversed_args;
283-
284-
// Count the maximum number of arguments
285-
BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size<reversed_args>::value);
263+
typedef mpl::size<optional_args> n_defaults;
264+
typedef mpl::size<signature> n_arguments;
286265
};
287266

288267
///////////////////////////////////////////////////////////////////////////////
@@ -300,21 +279,16 @@ struct optional
300279

301280
namespace detail
302281
{
303-
template <class ClassT, class CallPoliciesT, class ReversedArgs>
304-
void def_init_reversed(
282+
template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
283+
inline void def_init_aux(
305284
ClassT& cl
306-
, ReversedArgs const&
285+
, Signature const&
286+
, NArgs
307287
, CallPoliciesT const& policies
308288
, char const* doc
309289
, detail::keyword_range const& keywords_
310290
)
311291
{
312-
typedef typename mpl::fold<
313-
ReversedArgs
314-
, mpl::list0<>
315-
, mpl::push_front<>
316-
>::type args;
317-
318292
typedef typename ClassT::holder_selector holder_selector_t;
319293
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
320294
typedef typename holder_selector_t::type selector_t;
@@ -323,7 +297,7 @@ namespace detail
323297

324298
cl.def(
325299
"__init__",
326-
detail::make_keyword_range_constructor<args>(
300+
detail::make_keyword_range_constructor<Signature,NArgs>(
327301
policies
328302
, keywords_
329303
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
@@ -345,28 +319,30 @@ namespace detail
345319
//
346320
// Accepts a class_ and an arguments list. Defines a constructor
347321
// for the class given the arguments and recursively calls
348-
// define_class_init_helper<N-1>::apply with one less arguments (the
322+
// define_class_init_helper<N-1>::apply with one fewer argument (the
349323
// rightmost argument is shaved off)
350324
//
351325
///////////////////////////////////////////////////////////////////////////////
352-
template <int N>
326+
template <int NDefaults>
353327
struct define_class_init_helper {
354328

355-
template <class ClassT, class CallPoliciesT, class ReversedArgs>
329+
template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
356330
static void apply(
357331
ClassT& cl
358332
, CallPoliciesT const& policies
359-
, ReversedArgs const& args
333+
, Signature const& args
334+
, NArgs
360335
, char const* doc
361336
, detail::keyword_range keywords)
362337
{
363-
def_init_reversed(cl, args, policies, doc, keywords);
338+
detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
364339

365340
if (keywords.second > keywords.first)
366341
--keywords.second;
367-
368-
typename mpl::pop_front<ReversedArgs>::type next;
369-
define_class_init_helper<N-1>::apply(cl, policies, next, doc, keywords);
342+
343+
typedef typename mpl::prior<NArgs>::type next_nargs;
344+
define_class_init_helper<NDefaults-1>::apply(
345+
cl, policies, Signature(), next_nargs(), doc, keywords);
370346
}
371347
};
372348

@@ -383,15 +359,16 @@ namespace detail
383359
template <>
384360
struct define_class_init_helper<0> {
385361

386-
template <class ClassT, class CallPoliciesT, class ReversedArgs>
362+
template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
387363
static void apply(
388364
ClassT& cl
389365
, CallPoliciesT const& policies
390-
, ReversedArgs const& args
366+
, Signature const& args
367+
, NArgs
391368
, char const* doc
392369
, detail::keyword_range const& keywords)
393370
{
394-
def_init_reversed(cl, args, policies, doc, keywords);
371+
def_init_aux(cl, args, NArgs(), policies, doc, keywords);
395372
}
396373
};
397374
}
@@ -421,9 +398,12 @@ template <class ClassT, class InitT>
421398
void
422399
define_init(ClassT& cl, InitT const& i)
423400
{
424-
typedef typename InitT::reversed_args reversed_args;
425-
detail::define_class_init_helper<InitT::n_defaults>::apply(
426-
cl, i.call_policies(), reversed_args(), i.doc_string(), i.keywords());
401+
typedef typename InitT::signature signature;
402+
typedef typename InitT::n_arguments n_arguments;
403+
typedef typename InitT::n_defaults n_defaults;
404+
405+
detail::define_class_init_helper<n_defaults::value>::apply(
406+
cl, i.call_policies(), signature(), n_arguments(), i.doc_string(), i.keywords());
427407
}
428408

429409
}} // namespace boost::python

0 commit comments

Comments
 (0)