os/ossrv/ossrv_pub/boost_apis/boost/python/init.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
///////////////////////////////////////////////////////////////////////////////
sl@0
     2
//
sl@0
     3
// Copyright David Abrahams 2002, Joel de Guzman, 2002.
sl@0
     4
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
     5
// accompanying file LICENSE_1_0.txt or copy at
sl@0
     6
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     7
//
sl@0
     8
///////////////////////////////////////////////////////////////////////////////
sl@0
     9
#ifndef INIT_JDG20020820_HPP
sl@0
    10
#define INIT_JDG20020820_HPP
sl@0
    11
sl@0
    12
# include <boost/python/detail/prefix.hpp>
sl@0
    13
sl@0
    14
#include <boost/python/detail/type_list.hpp>
sl@0
    15
#include <boost/python/args_fwd.hpp>
sl@0
    16
#include <boost/python/detail/make_keyword_range_fn.hpp>
sl@0
    17
#include <boost/python/def_visitor.hpp>
sl@0
    18
sl@0
    19
#include <boost/mpl/if.hpp>
sl@0
    20
#include <boost/mpl/eval_if.hpp>
sl@0
    21
#include <boost/mpl/size.hpp>
sl@0
    22
#include <boost/mpl/iterator_range.hpp>
sl@0
    23
#include <boost/mpl/empty.hpp>
sl@0
    24
#include <boost/mpl/begin_end.hpp>
sl@0
    25
#include <boost/mpl/bool.hpp>
sl@0
    26
#include <boost/mpl/prior.hpp>
sl@0
    27
#include <boost/mpl/joint_view.hpp>
sl@0
    28
#include <boost/mpl/back.hpp>
sl@0
    29
sl@0
    30
#include <boost/type_traits/is_same.hpp>
sl@0
    31
sl@0
    32
#include <boost/preprocessor/enum_params_with_a_default.hpp>
sl@0
    33
#include <boost/preprocessor/enum_params.hpp>
sl@0
    34
sl@0
    35
#include <utility>
sl@0
    36
sl@0
    37
///////////////////////////////////////////////////////////////////////////////
sl@0
    38
#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT                                \
sl@0
    39
    BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(                                        \
sl@0
    40
        BOOST_PYTHON_MAX_ARITY,                                                 \
sl@0
    41
        class T,                                                                \
sl@0
    42
        mpl::void_)                                                             \
sl@0
    43
sl@0
    44
#define BOOST_PYTHON_OVERLOAD_TYPES                                             \
sl@0
    45
    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
sl@0
    46
        BOOST_PYTHON_MAX_ARITY,                                                 \
sl@0
    47
        class T)                                                                \
sl@0
    48
sl@0
    49
#define BOOST_PYTHON_OVERLOAD_ARGS                                              \
sl@0
    50
    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
sl@0
    51
        BOOST_PYTHON_MAX_ARITY,                                                 \
sl@0
    52
        T)                                                                      \
sl@0
    53
sl@0
    54
///////////////////////////////////////////////////////////////////////////////
sl@0
    55
namespace boost { namespace python {
sl@0
    56
sl@0
    57
template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
sl@0
    58
class init; // forward declaration
sl@0
    59
sl@0
    60
sl@0
    61
template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
sl@0
    62
struct optional; // forward declaration
sl@0
    63
sl@0
    64
namespace detail
sl@0
    65
{
sl@0
    66
  namespace error
sl@0
    67
  {
sl@0
    68
    template <int keywords, int init_args>
sl@0
    69
    struct more_keywords_than_init_arguments
sl@0
    70
    {
sl@0
    71
        typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1];
sl@0
    72
    };
sl@0
    73
  }
sl@0
    74
sl@0
    75
  //  is_optional<T>::value
sl@0
    76
  //
sl@0
    77
  //      This metaprogram checks if T is an optional
sl@0
    78
  //
sl@0
    79
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
sl@0
    80
sl@0
    81
    template <class T>
sl@0
    82
    struct is_optional {
sl@0
    83
sl@0
    84
    private:
sl@0
    85
sl@0
    86
        template <BOOST_PYTHON_OVERLOAD_TYPES>
sl@0
    87
        static boost::type_traits::yes_type f(optional<BOOST_PYTHON_OVERLOAD_ARGS>);
sl@0
    88
        static boost::type_traits::no_type f(...);
sl@0
    89
        static T t();
sl@0
    90
sl@0
    91
    public:
sl@0
    92
sl@0
    93
        BOOST_STATIC_CONSTANT(
sl@0
    94
            bool, value =
sl@0
    95
                sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
sl@0
    96
        typedef mpl::bool_<value> type;
sl@0
    97
    };
sl@0
    98
sl@0
    99
#else
sl@0
   100
sl@0
   101
    template <class T>
sl@0
   102
    struct is_optional
sl@0
   103
      : mpl::false_
sl@0
   104
    {};
sl@0
   105
sl@0
   106
    template <BOOST_PYTHON_OVERLOAD_TYPES>
sl@0
   107
    struct is_optional<optional<BOOST_PYTHON_OVERLOAD_ARGS> >
sl@0
   108
      : mpl::true_
sl@0
   109
    {};
sl@0
   110
  
sl@0
   111
#endif
sl@0
   112
sl@0
   113
  template <int NDefaults>
sl@0
   114
  struct define_class_init_helper;
sl@0
   115
sl@0
   116
} // namespace detail
sl@0
   117
sl@0
   118
template <class DerivedT>
sl@0
   119
struct init_base : def_visitor<DerivedT>
sl@0
   120
{
sl@0
   121
    init_base(char const* doc_, detail::keyword_range const& keywords_)
sl@0
   122
        : m_doc(doc_), m_keywords(keywords_)
sl@0
   123
    {}
sl@0
   124
        
sl@0
   125
    init_base(char const* doc_)
sl@0
   126
        : m_doc(doc_)
sl@0
   127
    {}
sl@0
   128
sl@0
   129
    DerivedT const& derived() const
sl@0
   130
    {
sl@0
   131
        return *static_cast<DerivedT const*>(this);
sl@0
   132
    }
sl@0
   133
    
sl@0
   134
    char const* doc_string() const
sl@0
   135
    {
sl@0
   136
        return m_doc;
sl@0
   137
    }
sl@0
   138
sl@0
   139
    detail::keyword_range const& keywords() const
sl@0
   140
    {
sl@0
   141
        return m_keywords;
sl@0
   142
    }
sl@0
   143
sl@0
   144
    static default_call_policies call_policies()
sl@0
   145
    {
sl@0
   146
        return default_call_policies();
sl@0
   147
    }
sl@0
   148
sl@0
   149
 private:
sl@0
   150
    //  visit
sl@0
   151
    //
sl@0
   152
    //      Defines a set of n_defaults + 1 constructors for its
sl@0
   153
    //      class_<...> argument. Each constructor after the first has
sl@0
   154
    //      one less argument to its right. Example:
sl@0
   155
    //
sl@0
   156
    //          init<int, optional<char, long, double> >
sl@0
   157
    //
sl@0
   158
    //      Defines:
sl@0
   159
    //
sl@0
   160
    //          __init__(int, char, long, double)
sl@0
   161
    //          __init__(int, char, long)
sl@0
   162
    //          __init__(int, char)
sl@0
   163
    //          __init__(int)
sl@0
   164
    template <class classT>
sl@0
   165
    void visit(classT& cl) const
sl@0
   166
    {
sl@0
   167
        typedef typename DerivedT::signature signature;
sl@0
   168
        typedef typename DerivedT::n_arguments n_arguments;
sl@0
   169
        typedef typename DerivedT::n_defaults n_defaults;
sl@0
   170
    
sl@0
   171
        detail::define_class_init_helper<n_defaults::value>::apply(
sl@0
   172
            cl
sl@0
   173
          , derived().call_policies()
sl@0
   174
          , signature()
sl@0
   175
          , n_arguments()
sl@0
   176
          , derived().doc_string()
sl@0
   177
          , derived().keywords());
sl@0
   178
    }
sl@0
   179
    
sl@0
   180
    friend class python::def_visitor_access;
sl@0
   181
    
sl@0
   182
 private: // data members
sl@0
   183
    char const* m_doc;
sl@0
   184
    detail::keyword_range m_keywords;
sl@0
   185
};
sl@0
   186
sl@0
   187
template <class CallPoliciesT, class InitT>
sl@0
   188
class init_with_call_policies
sl@0
   189
    : public init_base<init_with_call_policies<CallPoliciesT, InitT> >
sl@0
   190
{
sl@0
   191
    typedef init_base<init_with_call_policies<CallPoliciesT, InitT> > base;
sl@0
   192
 public:
sl@0
   193
    typedef typename InitT::n_arguments n_arguments;
sl@0
   194
    typedef typename InitT::n_defaults n_defaults;
sl@0
   195
    typedef typename InitT::signature signature;
sl@0
   196
sl@0
   197
    init_with_call_policies(
sl@0
   198
        CallPoliciesT const& policies_
sl@0
   199
        , char const* doc_
sl@0
   200
        , detail::keyword_range const& keywords
sl@0
   201
        )
sl@0
   202
        : base(doc_, keywords)
sl@0
   203
        , m_policies(policies_)
sl@0
   204
    {}
sl@0
   205
sl@0
   206
    CallPoliciesT const& call_policies() const
sl@0
   207
    {
sl@0
   208
        return this->m_policies;
sl@0
   209
    }
sl@0
   210
    
sl@0
   211
 private: // data members
sl@0
   212
    CallPoliciesT m_policies;
sl@0
   213
};
sl@0
   214
sl@0
   215
//
sl@0
   216
// drop1<S> is the initial length(S) elements of S
sl@0
   217
//
sl@0
   218
namespace detail
sl@0
   219
{
sl@0
   220
  template <class S>
sl@0
   221
  struct drop1
sl@0
   222
    : mpl::iterator_range<
sl@0
   223
          typename mpl::begin<S>::type
sl@0
   224
        , typename mpl::prior<
sl@0
   225
              typename mpl::end<S>::type
sl@0
   226
          >::type
sl@0
   227
      >
sl@0
   228
  {};
sl@0
   229
}
sl@0
   230
sl@0
   231
template <BOOST_PYTHON_OVERLOAD_TYPES>
sl@0
   232
class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
sl@0
   233
{
sl@0
   234
    typedef init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> > base;
sl@0
   235
 public:
sl@0
   236
    typedef init<BOOST_PYTHON_OVERLOAD_ARGS> self_t;
sl@0
   237
sl@0
   238
    init(char const* doc_ = 0)
sl@0
   239
        : base(doc_)
sl@0
   240
    {
sl@0
   241
    }
sl@0
   242
sl@0
   243
    template <std::size_t N>
sl@0
   244
    init(char const* doc_, detail::keywords<N> const& kw)
sl@0
   245
        : base(doc_, kw.range())
sl@0
   246
    {
sl@0
   247
        typedef typename detail::error::more_keywords_than_init_arguments<
sl@0
   248
            N, n_arguments::value
sl@0
   249
            >::too_many_keywords assertion;
sl@0
   250
    }
sl@0
   251
sl@0
   252
    template <std::size_t N>
sl@0
   253
    init(detail::keywords<N> const& kw, char const* doc_ = 0)
sl@0
   254
        : base(doc_, kw.range())
sl@0
   255
    {
sl@0
   256
        typedef typename detail::error::more_keywords_than_init_arguments<
sl@0
   257
            N, n_arguments::value
sl@0
   258
            >::too_many_keywords assertion;
sl@0
   259
    }
sl@0
   260
sl@0
   261
    template <class CallPoliciesT>
sl@0
   262
    init_with_call_policies<CallPoliciesT, self_t>
sl@0
   263
    operator[](CallPoliciesT const& policies) const
sl@0
   264
    {
sl@0
   265
        return init_with_call_policies<CallPoliciesT, self_t>(
sl@0
   266
            policies, this->doc_string(), this->keywords());
sl@0
   267
    }
sl@0
   268
sl@0
   269
    typedef detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS> signature_;
sl@0
   270
sl@0
   271
    typedef detail::is_optional<
sl@0
   272
        typename mpl::eval_if<
sl@0
   273
            mpl::empty<signature_>
sl@0
   274
          , mpl::false_
sl@0
   275
          , mpl::back<signature_>
sl@0
   276
        >::type
sl@0
   277
    > back_is_optional;
sl@0
   278
    
sl@0
   279
    typedef typename mpl::eval_if<
sl@0
   280
        back_is_optional
sl@0
   281
      , mpl::back<signature_>
sl@0
   282
      , mpl::vector0<>
sl@0
   283
    >::type optional_args;
sl@0
   284
sl@0
   285
    typedef typename mpl::eval_if<
sl@0
   286
        back_is_optional
sl@0
   287
      , mpl::if_<
sl@0
   288
            mpl::empty<optional_args>
sl@0
   289
          , detail::drop1<signature_>
sl@0
   290
          , mpl::joint_view<
sl@0
   291
                detail::drop1<signature_>
sl@0
   292
              , optional_args
sl@0
   293
            >
sl@0
   294
        >
sl@0
   295
      , signature_
sl@0
   296
    >::type signature;
sl@0
   297
sl@0
   298
    // TODO: static assert to make sure there are no other optional elements
sl@0
   299
sl@0
   300
    // Count the number of default args
sl@0
   301
    typedef mpl::size<optional_args> n_defaults;
sl@0
   302
    typedef mpl::size<signature> n_arguments;
sl@0
   303
};
sl@0
   304
sl@0
   305
///////////////////////////////////////////////////////////////////////////////
sl@0
   306
//
sl@0
   307
//  optional
sl@0
   308
//
sl@0
   309
//      optional<T0...TN>::type returns a typelist.
sl@0
   310
//
sl@0
   311
///////////////////////////////////////////////////////////////////////////////
sl@0
   312
template <BOOST_PYTHON_OVERLOAD_TYPES>
sl@0
   313
struct optional
sl@0
   314
    : detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS>
sl@0
   315
{
sl@0
   316
};
sl@0
   317
sl@0
   318
namespace detail
sl@0
   319
{
sl@0
   320
  template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
sl@0
   321
  inline void def_init_aux(
sl@0
   322
      ClassT& cl
sl@0
   323
      , Signature const&
sl@0
   324
      , NArgs
sl@0
   325
      , CallPoliciesT const& policies
sl@0
   326
      , char const* doc
sl@0
   327
      , detail::keyword_range const& keywords_
sl@0
   328
      )
sl@0
   329
  {
sl@0
   330
      cl.def(
sl@0
   331
          "__init__"
sl@0
   332
        , detail::make_keyword_range_constructor<Signature,NArgs>(
sl@0
   333
              policies
sl@0
   334
            , keywords_
sl@0
   335
            , (typename ClassT::metadata::holder*)0
sl@0
   336
          )
sl@0
   337
        , doc
sl@0
   338
      );
sl@0
   339
  }
sl@0
   340
sl@0
   341
  ///////////////////////////////////////////////////////////////////////////////
sl@0
   342
  //
sl@0
   343
  //  define_class_init_helper<N>::apply
sl@0
   344
  //
sl@0
   345
  //      General case
sl@0
   346
  //
sl@0
   347
  //      Accepts a class_ and an arguments list. Defines a constructor
sl@0
   348
  //      for the class given the arguments and recursively calls
sl@0
   349
  //      define_class_init_helper<N-1>::apply with one fewer argument (the
sl@0
   350
  //      rightmost argument is shaved off)
sl@0
   351
  //
sl@0
   352
  ///////////////////////////////////////////////////////////////////////////////
sl@0
   353
  template <int NDefaults>
sl@0
   354
  struct define_class_init_helper
sl@0
   355
  {
sl@0
   356
sl@0
   357
      template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
sl@0
   358
      static void apply(
sl@0
   359
          ClassT& cl
sl@0
   360
          , CallPoliciesT const& policies
sl@0
   361
          , Signature const& args
sl@0
   362
          , NArgs
sl@0
   363
          , char const* doc
sl@0
   364
          , detail::keyword_range keywords)
sl@0
   365
      {
sl@0
   366
          detail::def_init_aux(cl, args, NArgs(), policies, 0, keywords);
sl@0
   367
sl@0
   368
          if (keywords.second > keywords.first)
sl@0
   369
              --keywords.second;
sl@0
   370
sl@0
   371
          typedef typename mpl::prior<NArgs>::type next_nargs;
sl@0
   372
          define_class_init_helper<NDefaults-1>::apply(
sl@0
   373
              cl, policies, Signature(), next_nargs(), doc, keywords);
sl@0
   374
      }
sl@0
   375
  };
sl@0
   376
sl@0
   377
  ///////////////////////////////////////////////////////////////////////////////
sl@0
   378
  //
sl@0
   379
  //  define_class_init_helper<0>::apply
sl@0
   380
  //
sl@0
   381
  //      Terminal case
sl@0
   382
  //
sl@0
   383
  //      Accepts a class_ and an arguments list. Defines a constructor
sl@0
   384
  //      for the class given the arguments.
sl@0
   385
  //
sl@0
   386
  ///////////////////////////////////////////////////////////////////////////////
sl@0
   387
  template <>
sl@0
   388
  struct define_class_init_helper<0> {
sl@0
   389
sl@0
   390
      template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
sl@0
   391
      static void apply(
sl@0
   392
          ClassT& cl
sl@0
   393
        , CallPoliciesT const& policies
sl@0
   394
        , Signature const& args
sl@0
   395
        , NArgs
sl@0
   396
        , char const* doc
sl@0
   397
        , detail::keyword_range const& keywords)
sl@0
   398
      {
sl@0
   399
          detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
sl@0
   400
      }
sl@0
   401
  };
sl@0
   402
}
sl@0
   403
sl@0
   404
}} // namespace boost::python
sl@0
   405
sl@0
   406
#undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT
sl@0
   407
#undef BOOST_PYTHON_OVERLOAD_TYPES
sl@0
   408
#undef BOOST_PYTHON_OVERLOAD_ARGS
sl@0
   409
#undef BOOST_PYTHON_IS_OPTIONAL_VALUE
sl@0
   410
#undef BOOST_PYTHON_APPEND_TO_INIT
sl@0
   411
sl@0
   412
///////////////////////////////////////////////////////////////////////////////
sl@0
   413
#endif // INIT_JDG20020820_HPP
sl@0
   414
sl@0
   415
sl@0
   416
sl@0
   417
sl@0
   418
sl@0
   419
sl@0
   420
sl@0
   421