diff --git a/include/boost/python/detail/type_list.hpp b/include/boost/python/detail/type_list.hpp index 4a09c0be..0791fb28 100644 --- a/include/boost/python/detail/type_list.hpp +++ b/include/boost/python/detail/type_list.hpp @@ -16,19 +16,19 @@ # define BOOST_PYTHON_BASE_LIST_SIZE BOOST_PYTHON_MAX_BASES # endif -// Compute the MPL list header to use for lists up to BOOST_PYTHON_LIST_SIZE in length +// Compute the MPL vector header to use for lists up to BOOST_PYTHON_LIST_SIZE in length # if BOOST_PYTHON_LIST_SIZE > 48 # error Arities above 48 not supported by Boost.Python due to MPL internal limit # elif BOOST_PYTHON_LIST_SIZE > 38 -# include +# include # elif BOOST_PYTHON_LIST_SIZE > 28 -# include +# include # elif BOOST_PYTHON_LIST_SIZE > 18 -# include +# include # elif BOOST_PYTHON_LIST_SIZE > 8 -# include +# include # else -# include +# include # endif # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION diff --git a/include/boost/python/detail/type_list_impl.hpp b/include/boost/python/detail/type_list_impl.hpp index 50ab2446..545664f9 100644 --- a/include/boost/python/detail/type_list_impl.hpp +++ b/include/boost/python/detail/type_list_impl.hpp @@ -21,7 +21,7 @@ namespace boost { namespace python { namespace detail { template struct type_list - : BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE) + : BOOST_PP_CAT(mpl::vector,BOOST_PYTHON_LIST_SIZE) { }; @@ -48,7 +48,7 @@ struct type_list< BOOST_PP_ENUM( BOOST_PYTHON_VOID_ARGS, BOOST_PYTHON_FIXED, mpl::void_) > - : BOOST_PP_CAT(mpl::list,N) + : BOOST_PP_CAT(mpl::vector,N) { }; diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp index 7c9d7fab..280db11e 100644 --- a/include/boost/python/detail/type_list_impl_no_pts.hpp +++ b/include/boost/python/detail/type_list_impl_no_pts.hpp @@ -97,7 +97,7 @@ struct type_list_impl_chooser > struct result_ { - typedef typename BOOST_PP_CAT(mpl::list,N)< + typedef typename BOOST_PP_CAT(mpl::vector,N)< BOOST_PP_ENUM_PARAMS(N, T) >::type type; }; diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 39bf4ac7..897f5f2b 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -14,31 +14,21 @@ #include #include -#include #include #include -#include #include -#include #include -#include - -# include - -#include +#include #include -#include -#include -#include #include +#include +#include +#include #include -#include #include #include -#include -#include #include @@ -80,14 +70,11 @@ namespace detail }; } - /////////////////////////////////////////////////////////////////////////// - // - // is_optional::value - // - // This metaprogram checks if T is an optional - // - /////////////////////////////////////////////////////////////////////////// - #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + // is_optional::value + // + // This metaprogram checks if T is an optional + // +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct is_optional { @@ -105,32 +92,21 @@ namespace detail bool, value = sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); typedef mpl::bool_ type; - - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) }; - /////////////////////////////////////// - #else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +#else template - struct is_optional_impl { - - BOOST_STATIC_CONSTANT(bool, value = false); - }; + struct is_optional + : mpl::false_ + {}; template - struct is_optional_impl > { - - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template - struct is_optional : is_optional_impl - { - typedef mpl::bool_::value> type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) - }; - #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + struct is_optional > + : mpl::true_ + {}; + +#endif } // namespace detail @@ -176,10 +152,9 @@ class init_with_call_policies { typedef init_base > base; public: - 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; + typedef typename InitT::n_arguments n_arguments; + typedef typename InitT::n_defaults n_defaults; + typedef typename InitT::signature signature; init_with_call_policies( CallPoliciesT const& policies_ @@ -199,6 +174,22 @@ class init_with_call_policies CallPoliciesT m_policies; }; +// +// drop1 is the initial length(S) elements of S +// +namespace detail +{ + template + struct drop1 + : mpl::iterator_range< + typename mpl::begin::type + , typename mpl::prior< + typename mpl::end::type + >::type + > + {}; +} + template class init : public init_base > { @@ -216,7 +207,7 @@ class init : public init_base > : base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size)) { typedef typename detail::error::more_keywords_than_init_arguments< - Keywords::size, n_arguments + Keywords::size, n_arguments::value >::too_many_keywords assertion; } @@ -225,7 +216,7 @@ class init : public init_base > : base(doc_, kw.range()) { typedef typename detail::error::more_keywords_than_init_arguments< - Keywords::size, n_arguments + Keywords::size, n_arguments::value >::too_many_keywords assertion; } @@ -238,51 +229,39 @@ class init : public init_base > } 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 - >::type opt; - - - // Check to make sure the optional<> element, if any, is the last one + typedef detail::is_optional< + typename mpl::apply_if< + mpl::empty + , mpl::false_ + , mpl::back + >::type + > back_is_optional; + typedef typename mpl::apply_if< - is_same - , mpl::identity - , mpl::next - >::type expected_finish; - BOOST_STATIC_ASSERT((is_same::value)); - - typedef typename mpl::apply_if< - is_same - , mpl::list0<> - , opt + back_is_optional + , mpl::back + , mpl::vector0<> >::type optional_args; + typedef typename mpl::apply_if< + back_is_optional + , mpl::if_< + mpl::empty + , detail::drop1 + , mpl::joint_view< + detail::drop1 + , optional_args + > + > + , signature_ + >::type signature; + + // TODO: static assert to make sure there are no other optional elements + // Count the number of default args - BOOST_STATIC_CONSTANT(int, n_defaults = mpl::size::value); - - typedef typename mpl::iterator_range< - typename mpl::begin::type - , opt - >::type required_args; - - // Build a reverse image of all the args, including optionals - typedef typename mpl::fold< - required_args - , mpl::list0<> - , mpl::push_front<> - >::type reversed_required; - - typedef typename mpl::fold< - optional_args - , reversed_required - , mpl::push_front<> - >::type reversed_args; - - // Count the maximum number of arguments - BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); + typedef mpl::size n_defaults; + typedef mpl::size n_arguments; }; /////////////////////////////////////////////////////////////////////////////// @@ -300,21 +279,16 @@ struct optional namespace detail { - template - void def_init_reversed( + template + inline void def_init_aux( ClassT& cl - , ReversedArgs const& + , Signature const& + , NArgs , CallPoliciesT const& policies , char const* doc , detail::keyword_range const& keywords_ ) { - typedef typename mpl::fold< - ReversedArgs - , mpl::list0<> - , mpl::push_front<> - >::type args; - typedef typename ClassT::holder_selector holder_selector_t; # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) typedef typename holder_selector_t::type selector_t; @@ -323,7 +297,7 @@ namespace detail cl.def( "__init__", - detail::make_keyword_range_constructor( + detail::make_keyword_range_constructor( policies , keywords_ # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) @@ -345,28 +319,30 @@ namespace detail // // Accepts a class_ and an arguments list. Defines a constructor // for the class given the arguments and recursively calls - // define_class_init_helper::apply with one less arguments (the + // define_class_init_helper::apply with one fewer argument (the // rightmost argument is shaved off) // /////////////////////////////////////////////////////////////////////////////// - template + template struct define_class_init_helper { - template + template static void apply( ClassT& cl , CallPoliciesT const& policies - , ReversedArgs const& args + , Signature const& args + , NArgs , char const* doc , detail::keyword_range keywords) { - def_init_reversed(cl, args, policies, doc, keywords); + detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords); if (keywords.second > keywords.first) --keywords.second; - - typename mpl::pop_front::type next; - define_class_init_helper::apply(cl, policies, next, doc, keywords); + + typedef typename mpl::prior::type next_nargs; + define_class_init_helper::apply( + cl, policies, Signature(), next_nargs(), doc, keywords); } }; @@ -383,15 +359,16 @@ namespace detail template <> struct define_class_init_helper<0> { - template + template static void apply( ClassT& cl , CallPoliciesT const& policies - , ReversedArgs const& args + , Signature const& args + , NArgs , char const* doc , detail::keyword_range const& keywords) { - def_init_reversed(cl, args, policies, doc, keywords); + def_init_aux(cl, args, NArgs(), policies, doc, keywords); } }; } @@ -421,9 +398,12 @@ template void define_init(ClassT& cl, InitT const& i) { - typedef typename InitT::reversed_args reversed_args; - detail::define_class_init_helper::apply( - cl, i.call_policies(), reversed_args(), i.doc_string(), i.keywords()); + typedef typename InitT::signature signature; + typedef typename InitT::n_arguments n_arguments; + typedef typename InitT::n_defaults n_defaults; + + detail::define_class_init_helper::apply( + cl, i.call_policies(), signature(), n_arguments(), i.doc_string(), i.keywords()); } }} // namespace boost::python