os/ossrv/ossrv_pub/boost_apis/boost/python/init.hpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/python/init.hpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,421 @@
     1.4 +///////////////////////////////////////////////////////////////////////////////
     1.5 +//
     1.6 +// Copyright David Abrahams 2002, Joel de Guzman, 2002.
     1.7 +// Distributed under the Boost Software License, Version 1.0. (See
     1.8 +// accompanying file LICENSE_1_0.txt or copy at
     1.9 +// http://www.boost.org/LICENSE_1_0.txt)
    1.10 +//
    1.11 +///////////////////////////////////////////////////////////////////////////////
    1.12 +#ifndef INIT_JDG20020820_HPP
    1.13 +#define INIT_JDG20020820_HPP
    1.14 +
    1.15 +# include <boost/python/detail/prefix.hpp>
    1.16 +
    1.17 +#include <boost/python/detail/type_list.hpp>
    1.18 +#include <boost/python/args_fwd.hpp>
    1.19 +#include <boost/python/detail/make_keyword_range_fn.hpp>
    1.20 +#include <boost/python/def_visitor.hpp>
    1.21 +
    1.22 +#include <boost/mpl/if.hpp>
    1.23 +#include <boost/mpl/eval_if.hpp>
    1.24 +#include <boost/mpl/size.hpp>
    1.25 +#include <boost/mpl/iterator_range.hpp>
    1.26 +#include <boost/mpl/empty.hpp>
    1.27 +#include <boost/mpl/begin_end.hpp>
    1.28 +#include <boost/mpl/bool.hpp>
    1.29 +#include <boost/mpl/prior.hpp>
    1.30 +#include <boost/mpl/joint_view.hpp>
    1.31 +#include <boost/mpl/back.hpp>
    1.32 +
    1.33 +#include <boost/type_traits/is_same.hpp>
    1.34 +
    1.35 +#include <boost/preprocessor/enum_params_with_a_default.hpp>
    1.36 +#include <boost/preprocessor/enum_params.hpp>
    1.37 +
    1.38 +#include <utility>
    1.39 +
    1.40 +///////////////////////////////////////////////////////////////////////////////
    1.41 +#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT                                \
    1.42 +    BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(                                        \
    1.43 +        BOOST_PYTHON_MAX_ARITY,                                                 \
    1.44 +        class T,                                                                \
    1.45 +        mpl::void_)                                                             \
    1.46 +
    1.47 +#define BOOST_PYTHON_OVERLOAD_TYPES                                             \
    1.48 +    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
    1.49 +        BOOST_PYTHON_MAX_ARITY,                                                 \
    1.50 +        class T)                                                                \
    1.51 +
    1.52 +#define BOOST_PYTHON_OVERLOAD_ARGS                                              \
    1.53 +    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
    1.54 +        BOOST_PYTHON_MAX_ARITY,                                                 \
    1.55 +        T)                                                                      \
    1.56 +
    1.57 +///////////////////////////////////////////////////////////////////////////////
    1.58 +namespace boost { namespace python {
    1.59 +
    1.60 +template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
    1.61 +class init; // forward declaration
    1.62 +
    1.63 +
    1.64 +template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
    1.65 +struct optional; // forward declaration
    1.66 +
    1.67 +namespace detail
    1.68 +{
    1.69 +  namespace error
    1.70 +  {
    1.71 +    template <int keywords, int init_args>
    1.72 +    struct more_keywords_than_init_arguments
    1.73 +    {
    1.74 +        typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1];
    1.75 +    };
    1.76 +  }
    1.77 +
    1.78 +  //  is_optional<T>::value
    1.79 +  //
    1.80 +  //      This metaprogram checks if T is an optional
    1.81 +  //
    1.82 +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
    1.83 +
    1.84 +    template <class T>
    1.85 +    struct is_optional {
    1.86 +
    1.87 +    private:
    1.88 +
    1.89 +        template <BOOST_PYTHON_OVERLOAD_TYPES>
    1.90 +        static boost::type_traits::yes_type f(optional<BOOST_PYTHON_OVERLOAD_ARGS>);
    1.91 +        static boost::type_traits::no_type f(...);
    1.92 +        static T t();
    1.93 +
    1.94 +    public:
    1.95 +
    1.96 +        BOOST_STATIC_CONSTANT(
    1.97 +            bool, value =
    1.98 +                sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
    1.99 +        typedef mpl::bool_<value> type;
   1.100 +    };
   1.101 +
   1.102 +#else
   1.103 +
   1.104 +    template <class T>
   1.105 +    struct is_optional
   1.106 +      : mpl::false_
   1.107 +    {};
   1.108 +
   1.109 +    template <BOOST_PYTHON_OVERLOAD_TYPES>
   1.110 +    struct is_optional<optional<BOOST_PYTHON_OVERLOAD_ARGS> >
   1.111 +      : mpl::true_
   1.112 +    {};
   1.113 +  
   1.114 +#endif
   1.115 +
   1.116 +  template <int NDefaults>
   1.117 +  struct define_class_init_helper;
   1.118 +
   1.119 +} // namespace detail
   1.120 +
   1.121 +template <class DerivedT>
   1.122 +struct init_base : def_visitor<DerivedT>
   1.123 +{
   1.124 +    init_base(char const* doc_, detail::keyword_range const& keywords_)
   1.125 +        : m_doc(doc_), m_keywords(keywords_)
   1.126 +    {}
   1.127 +        
   1.128 +    init_base(char const* doc_)
   1.129 +        : m_doc(doc_)
   1.130 +    {}
   1.131 +
   1.132 +    DerivedT const& derived() const
   1.133 +    {
   1.134 +        return *static_cast<DerivedT const*>(this);
   1.135 +    }
   1.136 +    
   1.137 +    char const* doc_string() const
   1.138 +    {
   1.139 +        return m_doc;
   1.140 +    }
   1.141 +
   1.142 +    detail::keyword_range const& keywords() const
   1.143 +    {
   1.144 +        return m_keywords;
   1.145 +    }
   1.146 +
   1.147 +    static default_call_policies call_policies()
   1.148 +    {
   1.149 +        return default_call_policies();
   1.150 +    }
   1.151 +
   1.152 + private:
   1.153 +    //  visit
   1.154 +    //
   1.155 +    //      Defines a set of n_defaults + 1 constructors for its
   1.156 +    //      class_<...> argument. Each constructor after the first has
   1.157 +    //      one less argument to its right. Example:
   1.158 +    //
   1.159 +    //          init<int, optional<char, long, double> >
   1.160 +    //
   1.161 +    //      Defines:
   1.162 +    //
   1.163 +    //          __init__(int, char, long, double)
   1.164 +    //          __init__(int, char, long)
   1.165 +    //          __init__(int, char)
   1.166 +    //          __init__(int)
   1.167 +    template <class classT>
   1.168 +    void visit(classT& cl) const
   1.169 +    {
   1.170 +        typedef typename DerivedT::signature signature;
   1.171 +        typedef typename DerivedT::n_arguments n_arguments;
   1.172 +        typedef typename DerivedT::n_defaults n_defaults;
   1.173 +    
   1.174 +        detail::define_class_init_helper<n_defaults::value>::apply(
   1.175 +            cl
   1.176 +          , derived().call_policies()
   1.177 +          , signature()
   1.178 +          , n_arguments()
   1.179 +          , derived().doc_string()
   1.180 +          , derived().keywords());
   1.181 +    }
   1.182 +    
   1.183 +    friend class python::def_visitor_access;
   1.184 +    
   1.185 + private: // data members
   1.186 +    char const* m_doc;
   1.187 +    detail::keyword_range m_keywords;
   1.188 +};
   1.189 +
   1.190 +template <class CallPoliciesT, class InitT>
   1.191 +class init_with_call_policies
   1.192 +    : public init_base<init_with_call_policies<CallPoliciesT, InitT> >
   1.193 +{
   1.194 +    typedef init_base<init_with_call_policies<CallPoliciesT, InitT> > base;
   1.195 + public:
   1.196 +    typedef typename InitT::n_arguments n_arguments;
   1.197 +    typedef typename InitT::n_defaults n_defaults;
   1.198 +    typedef typename InitT::signature signature;
   1.199 +
   1.200 +    init_with_call_policies(
   1.201 +        CallPoliciesT const& policies_
   1.202 +        , char const* doc_
   1.203 +        , detail::keyword_range const& keywords
   1.204 +        )
   1.205 +        : base(doc_, keywords)
   1.206 +        , m_policies(policies_)
   1.207 +    {}
   1.208 +
   1.209 +    CallPoliciesT const& call_policies() const
   1.210 +    {
   1.211 +        return this->m_policies;
   1.212 +    }
   1.213 +    
   1.214 + private: // data members
   1.215 +    CallPoliciesT m_policies;
   1.216 +};
   1.217 +
   1.218 +//
   1.219 +// drop1<S> is the initial length(S) elements of S
   1.220 +//
   1.221 +namespace detail
   1.222 +{
   1.223 +  template <class S>
   1.224 +  struct drop1
   1.225 +    : mpl::iterator_range<
   1.226 +          typename mpl::begin<S>::type
   1.227 +        , typename mpl::prior<
   1.228 +              typename mpl::end<S>::type
   1.229 +          >::type
   1.230 +      >
   1.231 +  {};
   1.232 +}
   1.233 +
   1.234 +template <BOOST_PYTHON_OVERLOAD_TYPES>
   1.235 +class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
   1.236 +{
   1.237 +    typedef init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> > base;
   1.238 + public:
   1.239 +    typedef init<BOOST_PYTHON_OVERLOAD_ARGS> self_t;
   1.240 +
   1.241 +    init(char const* doc_ = 0)
   1.242 +        : base(doc_)
   1.243 +    {
   1.244 +    }
   1.245 +
   1.246 +    template <std::size_t N>
   1.247 +    init(char const* doc_, detail::keywords<N> const& kw)
   1.248 +        : base(doc_, kw.range())
   1.249 +    {
   1.250 +        typedef typename detail::error::more_keywords_than_init_arguments<
   1.251 +            N, n_arguments::value
   1.252 +            >::too_many_keywords assertion;
   1.253 +    }
   1.254 +
   1.255 +    template <std::size_t N>
   1.256 +    init(detail::keywords<N> const& kw, char const* doc_ = 0)
   1.257 +        : base(doc_, kw.range())
   1.258 +    {
   1.259 +        typedef typename detail::error::more_keywords_than_init_arguments<
   1.260 +            N, n_arguments::value
   1.261 +            >::too_many_keywords assertion;
   1.262 +    }
   1.263 +
   1.264 +    template <class CallPoliciesT>
   1.265 +    init_with_call_policies<CallPoliciesT, self_t>
   1.266 +    operator[](CallPoliciesT const& policies) const
   1.267 +    {
   1.268 +        return init_with_call_policies<CallPoliciesT, self_t>(
   1.269 +            policies, this->doc_string(), this->keywords());
   1.270 +    }
   1.271 +
   1.272 +    typedef detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS> signature_;
   1.273 +
   1.274 +    typedef detail::is_optional<
   1.275 +        typename mpl::eval_if<
   1.276 +            mpl::empty<signature_>
   1.277 +          , mpl::false_
   1.278 +          , mpl::back<signature_>
   1.279 +        >::type
   1.280 +    > back_is_optional;
   1.281 +    
   1.282 +    typedef typename mpl::eval_if<
   1.283 +        back_is_optional
   1.284 +      , mpl::back<signature_>
   1.285 +      , mpl::vector0<>
   1.286 +    >::type optional_args;
   1.287 +
   1.288 +    typedef typename mpl::eval_if<
   1.289 +        back_is_optional
   1.290 +      , mpl::if_<
   1.291 +            mpl::empty<optional_args>
   1.292 +          , detail::drop1<signature_>
   1.293 +          , mpl::joint_view<
   1.294 +                detail::drop1<signature_>
   1.295 +              , optional_args
   1.296 +            >
   1.297 +        >
   1.298 +      , signature_
   1.299 +    >::type signature;
   1.300 +
   1.301 +    // TODO: static assert to make sure there are no other optional elements
   1.302 +
   1.303 +    // Count the number of default args
   1.304 +    typedef mpl::size<optional_args> n_defaults;
   1.305 +    typedef mpl::size<signature> n_arguments;
   1.306 +};
   1.307 +
   1.308 +///////////////////////////////////////////////////////////////////////////////
   1.309 +//
   1.310 +//  optional
   1.311 +//
   1.312 +//      optional<T0...TN>::type returns a typelist.
   1.313 +//
   1.314 +///////////////////////////////////////////////////////////////////////////////
   1.315 +template <BOOST_PYTHON_OVERLOAD_TYPES>
   1.316 +struct optional
   1.317 +    : detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS>
   1.318 +{
   1.319 +};
   1.320 +
   1.321 +namespace detail
   1.322 +{
   1.323 +  template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
   1.324 +  inline void def_init_aux(
   1.325 +      ClassT& cl
   1.326 +      , Signature const&
   1.327 +      , NArgs
   1.328 +      , CallPoliciesT const& policies
   1.329 +      , char const* doc
   1.330 +      , detail::keyword_range const& keywords_
   1.331 +      )
   1.332 +  {
   1.333 +      cl.def(
   1.334 +          "__init__"
   1.335 +        , detail::make_keyword_range_constructor<Signature,NArgs>(
   1.336 +              policies
   1.337 +            , keywords_
   1.338 +            , (typename ClassT::metadata::holder*)0
   1.339 +          )
   1.340 +        , doc
   1.341 +      );
   1.342 +  }
   1.343 +
   1.344 +  ///////////////////////////////////////////////////////////////////////////////
   1.345 +  //
   1.346 +  //  define_class_init_helper<N>::apply
   1.347 +  //
   1.348 +  //      General case
   1.349 +  //
   1.350 +  //      Accepts a class_ and an arguments list. Defines a constructor
   1.351 +  //      for the class given the arguments and recursively calls
   1.352 +  //      define_class_init_helper<N-1>::apply with one fewer argument (the
   1.353 +  //      rightmost argument is shaved off)
   1.354 +  //
   1.355 +  ///////////////////////////////////////////////////////////////////////////////
   1.356 +  template <int NDefaults>
   1.357 +  struct define_class_init_helper
   1.358 +  {
   1.359 +
   1.360 +      template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
   1.361 +      static void apply(
   1.362 +          ClassT& cl
   1.363 +          , CallPoliciesT const& policies
   1.364 +          , Signature const& args
   1.365 +          , NArgs
   1.366 +          , char const* doc
   1.367 +          , detail::keyword_range keywords)
   1.368 +      {
   1.369 +          detail::def_init_aux(cl, args, NArgs(), policies, 0, keywords);
   1.370 +
   1.371 +          if (keywords.second > keywords.first)
   1.372 +              --keywords.second;
   1.373 +
   1.374 +          typedef typename mpl::prior<NArgs>::type next_nargs;
   1.375 +          define_class_init_helper<NDefaults-1>::apply(
   1.376 +              cl, policies, Signature(), next_nargs(), doc, keywords);
   1.377 +      }
   1.378 +  };
   1.379 +
   1.380 +  ///////////////////////////////////////////////////////////////////////////////
   1.381 +  //
   1.382 +  //  define_class_init_helper<0>::apply
   1.383 +  //
   1.384 +  //      Terminal case
   1.385 +  //
   1.386 +  //      Accepts a class_ and an arguments list. Defines a constructor
   1.387 +  //      for the class given the arguments.
   1.388 +  //
   1.389 +  ///////////////////////////////////////////////////////////////////////////////
   1.390 +  template <>
   1.391 +  struct define_class_init_helper<0> {
   1.392 +
   1.393 +      template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
   1.394 +      static void apply(
   1.395 +          ClassT& cl
   1.396 +        , CallPoliciesT const& policies
   1.397 +        , Signature const& args
   1.398 +        , NArgs
   1.399 +        , char const* doc
   1.400 +        , detail::keyword_range const& keywords)
   1.401 +      {
   1.402 +          detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
   1.403 +      }
   1.404 +  };
   1.405 +}
   1.406 +
   1.407 +}} // namespace boost::python
   1.408 +
   1.409 +#undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT
   1.410 +#undef BOOST_PYTHON_OVERLOAD_TYPES
   1.411 +#undef BOOST_PYTHON_OVERLOAD_ARGS
   1.412 +#undef BOOST_PYTHON_IS_OPTIONAL_VALUE
   1.413 +#undef BOOST_PYTHON_APPEND_TO_INIT
   1.414 +
   1.415 +///////////////////////////////////////////////////////////////////////////////
   1.416 +#endif // INIT_JDG20020820_HPP
   1.417 +
   1.418 +
   1.419 +
   1.420 +
   1.421 +
   1.422 +
   1.423 +
   1.424 +