2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-31 08:22:18 +00:00

Use mpl::vector and simplify constructor generation so we don't have

to constantly reverse lists.


[SVN r18487]
This commit is contained in:
Dave Abrahams
2003-05-21 21:53:30 +00:00
parent 2f1b828967
commit 66d6272942
4 changed files with 101 additions and 121 deletions

View File

@@ -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 <boost/mpl/list/list50.hpp>
# include <boost/mpl/vector/vector50.hpp>
# elif BOOST_PYTHON_LIST_SIZE > 28
# include <boost/mpl/list/list40.hpp>
# include <boost/mpl/vector/vector40.hpp>
# elif BOOST_PYTHON_LIST_SIZE > 18
# include <boost/mpl/list/list30.hpp>
# include <boost/mpl/vector/vector30.hpp>
# elif BOOST_PYTHON_LIST_SIZE > 8
# include <boost/mpl/list/list20.hpp>
# include <boost/mpl/vector/vector20.hpp>
# else
# include <boost/mpl/list/list10.hpp>
# include <boost/mpl/vector/vector10.hpp>
# endif
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

View File

@@ -21,7 +21,7 @@ namespace boost { namespace python { namespace detail {
template <BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_)>
struct type_list
: BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE)<BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_LIST_SIZE, T)>
: BOOST_PP_CAT(mpl::vector,BOOST_PYTHON_LIST_SIZE)<BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_LIST_SIZE, T)>
{
};
@@ -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_ENUM_PARAMS_Z(1, N, T)>
: BOOST_PP_CAT(mpl::vector,N)<BOOST_PP_ENUM_PARAMS_Z(1, N, T)>
{
};

View File

@@ -97,7 +97,7 @@ struct type_list_impl_chooser<N>
>
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;
};

View File

@@ -14,31 +14,21 @@
#include <boost/python/args_fwd.hpp>
#include <boost/python/detail/make_keyword_range_fn.hpp>
#include <boost/mpl/fold_backward.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/iterator_range.hpp>
#include <boost/mpl/not.hpp>
# include <boost/python/detail/mpl_lambda.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/prior.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/back.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/enum_params_with_a_default.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <utility>
@@ -80,14 +70,11 @@ namespace detail
};
}
///////////////////////////////////////////////////////////////////////////
//
// is_optional<T>::value
//
// This metaprogram checks if T is an optional
//
///////////////////////////////////////////////////////////////////////////
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
// is_optional<T>::value
//
// This metaprogram checks if T is an optional
//
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T>
struct is_optional {
@@ -105,32 +92,21 @@ namespace detail
bool, value =
sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
typedef mpl::bool_<value> type;
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T))
};
///////////////////////////////////////
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#else
template <class T>
struct is_optional_impl {
BOOST_STATIC_CONSTANT(bool, value = false);
};
struct is_optional
: mpl::false_
{};
template <BOOST_PYTHON_OVERLOAD_TYPES>
struct is_optional_impl<optional<BOOST_PYTHON_OVERLOAD_ARGS> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_optional : is_optional_impl<T>
{
typedef mpl::bool_<is_optional_impl<T>::value> type;
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T))
};
#endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
struct is_optional<optional<BOOST_PYTHON_OVERLOAD_ARGS> >
: mpl::true_
{};
#endif
} // namespace detail
@@ -176,10 +152,9 @@ class init_with_call_policies
{
typedef init_base<init_with_call_policies<CallPoliciesT, InitT> > 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<S> is the initial length(S) elements of S
//
namespace detail
{
template <class S>
struct drop1
: mpl::iterator_range<
typename mpl::begin<S>::type
, typename mpl::prior<
typename mpl::end<S>::type
>::type
>
{};
}
template <BOOST_PYTHON_OVERLOAD_TYPES>
class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
{
@@ -216,7 +207,7 @@ class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
: 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<init<BOOST_PYTHON_OVERLOAD_ARGS> >
: 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<init<BOOST_PYTHON_OVERLOAD_ARGS> >
}
typedef detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS> signature_;
typedef typename mpl::end<signature_>::type finish;
// Find the optional<> element, if any
typedef typename mpl::find_if<
signature_, detail::is_optional<mpl::_>
>::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<signature_>
, mpl::false_
, mpl::back<signature_>
>::type
> back_is_optional;
typedef typename mpl::apply_if<
is_same<opt,finish>
, mpl::identity<opt>
, mpl::next<opt>
>::type expected_finish;
BOOST_STATIC_ASSERT((is_same<expected_finish, finish>::value));
typedef typename mpl::apply_if<
is_same<opt,finish>
, mpl::list0<>
, opt
back_is_optional
, mpl::back<signature_>
, mpl::vector0<>
>::type optional_args;
typedef typename mpl::apply_if<
back_is_optional
, mpl::if_<
mpl::empty<optional_args>
, detail::drop1<signature_>
, mpl::joint_view<
detail::drop1<signature_>
, 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<optional_args>::value);
typedef typename mpl::iterator_range<
typename mpl::begin<signature_>::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<reversed_args>::value);
typedef mpl::size<optional_args> n_defaults;
typedef mpl::size<signature> n_arguments;
};
///////////////////////////////////////////////////////////////////////////////
@@ -300,21 +279,16 @@ struct optional
namespace detail
{
template <class ClassT, class CallPoliciesT, class ReversedArgs>
void def_init_reversed(
template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
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<args>(
detail::make_keyword_range_constructor<Signature,NArgs>(
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<N-1>::apply with one less arguments (the
// define_class_init_helper<N-1>::apply with one fewer argument (the
// rightmost argument is shaved off)
//
///////////////////////////////////////////////////////////////////////////////
template <int N>
template <int NDefaults>
struct define_class_init_helper {
template <class ClassT, class CallPoliciesT, class ReversedArgs>
template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
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<ReversedArgs>::type next;
define_class_init_helper<N-1>::apply(cl, policies, next, doc, keywords);
typedef typename mpl::prior<NArgs>::type next_nargs;
define_class_init_helper<NDefaults-1>::apply(
cl, policies, Signature(), next_nargs(), doc, keywords);
}
};
@@ -383,15 +359,16 @@ namespace detail
template <>
struct define_class_init_helper<0> {
template <class ClassT, class CallPoliciesT, class ReversedArgs>
template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
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 <class ClassT, class InitT>
void
define_init(ClassT& cl, InitT const& i)
{
typedef typename InitT::reversed_args reversed_args;
detail::define_class_init_helper<InitT::n_defaults>::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<n_defaults::value>::apply(
cl, i.call_policies(), signature(), n_arguments(), i.doc_string(), i.keywords());
}
}} // namespace boost::python