[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/boostorg/python/develop/include/boost/python/init.hpp [Back]  [Original]

///////////////////////////////////////////////////////////////////////////////
//
// Copyright David Abrahams 2002, Joel de Guzman, 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
///////////////////////////////////////////////////////////////////////////////
#ifndef INIT_JDG20020820_HPP
#define INIT_JDG20020820_HPP

# include 

#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 

#include 
#include 

#include 

///////////////////////////////////////////////////////////////////////////////
#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT                                \
    BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(                                        \
        BOOST_PYTHON_MAX_ARITY,                                                 \
        class T,                                                                \
        mpl::void_)                                                             \

#define BOOST_PYTHON_OVERLOAD_TYPES                                             \
    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
        BOOST_PYTHON_MAX_ARITY,                                                 \
        class T)                                                                \

#define BOOST_PYTHON_OVERLOAD_ARGS                                              \
    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
        BOOST_PYTHON_MAX_ARITY,                                                 \
        T)                                                                      \

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace python {

template 
class init; // forward declaration


template 
struct optional; // forward declaration

namespace detail
{
  namespace error
  {
    template 
    struct more_keywords_than_init_arguments
    {
        typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1] BOOST_ATTRIBUTE_UNUSED;
    };
  }

  //  is_optional::value
  //
  //      This metaprogram checks if T is an optional
  //

    template 
    struct is_optional
      : mpl::false_
    {};

    template 
    struct is_optional
      : mpl::true_
    {};
  

  template 
  struct define_class_init_helper;

} // namespace detail

template 
struct init_base : def_visitor
{
    init_base(char const* doc_, detail::keyword_range const& keywords_)
        : m_doc(doc_), m_keywords(keywords_)
    {}
        
    init_base(char const* doc_)
        : m_doc(doc_)
    {}

    DerivedT const& derived() const
    {
        return *static_cast(this);
    }
    
    char const* doc_string() const
    {
        return m_doc;
    }

    detail::keyword_range const& keywords() const
    {
        return m_keywords;
    }

    static default_call_policies call_policies()
    {
        return default_call_policies();
    }

 private:
    //  visit
    //
    //      Defines a set of n_defaults + 1 constructors for its
    //      class_ argument. Each constructor after the first has
    //      one less argument to its right. Example:
    //
    //          init
    //
    //      Defines:
    //
    //          __init__(int, char, long, double)
    //          __init__(int, char, long)
    //          __init__(int, char)
    //          __init__(int)
    template 
    void visit(classT& cl) const
    {
        typedef typename DerivedT::signature signature;
        typedef typename DerivedT::n_arguments n_arguments;
        typedef typename DerivedT::n_defaults n_defaults;
    
        detail::define_class_init_helper::apply(
            cl
          , derived().call_policies()
          , signature()
          , n_arguments()
          , derived().doc_string()
          , derived().keywords());
    }
    
    friend class python::def_visitor_access;
    
 private: // data members
    char const* m_doc;
    detail::keyword_range m_keywords;
};

template 
class init_with_call_policies
    : public init_base
{
    typedef init_base base;
 public:
    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_
        , char const* doc_
        , detail::keyword_range const& keywords
        )
        : base(doc_, keywords)
        , m_policies(policies_)
    {}

    CallPoliciesT const& call_policies() const
    {
        return this->m_policies;
    }
    
 private: // data members
    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
{
    typedef init_base base;
 public:
    typedef init self_t;

    init(char const* doc_ = 0)
        : base(doc_)
    {
    }

    template 
    init(char const* doc_, detail::keywords const& kw)
        : base(doc_, kw.range())
    {
        typedef typename detail::error::more_keywords_than_init_arguments<
            N, n_arguments::value + 1
            >::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;
    }

    template 
    init(detail::keywords const& kw, char const* doc_ = 0)
        : base(doc_, kw.range())
    {
        typedef typename detail::error::more_keywords_than_init_arguments<
            N, n_arguments::value + 1
            >::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;
    }

    template 
    init_with_call_policies
    operator[](CallPoliciesT const& policies) const
    {
        return init_with_call_policies(
            policies, this->doc_string(), this->keywords());
    }

    typedef detail::type_list signature_;

    typedef detail::is_optional<
        typename mpl::eval_if<
            mpl::empty
          , mpl::false_
          , mpl::back
        >::type
    > back_is_optional;
    
    typedef typename mpl::eval_if<
        back_is_optional
      , mpl::back
      , mpl::vector0
    >::type optional_args;

    typedef typename mpl::eval_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
    typedef mpl::size n_defaults;
    typedef mpl::size n_arguments;
};

///////////////////////////////////////////////////////////////////////////////
//
//  optional
//
//      optional::type returns a typelist.
//
///////////////////////////////////////////////////////////////////////////////
template 
struct optional
    : detail::type_list
{
};

namespace detail
{
  template 
  inline void def_init_aux(
      ClassT& cl
      , Signature const&
      , NArgs
      , CallPoliciesT const& policies
      , char const* doc
      , detail::keyword_range const& keywords_
      )
  {
      cl.def(
          "__init__"
        , detail::make_keyword_range_constructor(
              policies
            , keywords_
            , (typename ClassT::metadata::holder*)0
          )
        , doc
      );
  }

  ///////////////////////////////////////////////////////////////////////////////
  //
  //  define_class_init_helper::apply
  //
  //      General case
  //
  //      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 fewer argument (the
  //      rightmost argument is shaved off)
  //
  ///////////////////////////////////////////////////////////////////////////////
  template 
  struct define_class_init_helper
  {

      template 
      static void apply(
          ClassT& cl
          , CallPoliciesT const& policies
          , Signature const& args
          , NArgs
          , char const* doc
          , detail::keyword_range keywords)
      {
          detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);

          if (keywords.second > keywords.first)
              --keywords.second;

          typedef typename mpl::prior::type next_nargs;
          define_class_init_helper::apply(
              cl, policies, Signature(), next_nargs(), doc, keywords);
      }
  };

  ///////////////////////////////////////////////////////////////////////////////
  //
  //  define_class_init_helper::apply
  //
  //      Terminal case
  //
  //      Accepts a class_ and an arguments list. Defines a constructor
  //      for the class given the arguments.
  //
  ///////////////////////////////////////////////////////////////////////////////
  template 
  struct define_class_init_helper {

      template 
      static void apply(
          ClassT& cl
        , CallPoliciesT const& policies
        , Signature const& args
        , NArgs
        , char const* doc
        , detail::keyword_range const& keywords)
      {
          detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
      }
  };
}

}} // namespace boost::python

#undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT
#undef BOOST_PYTHON_OVERLOAD_TYPES
#undef BOOST_PYTHON_OVERLOAD_ARGS
#undef BOOST_PYTHON_IS_OPTIONAL_VALUE
#undef BOOST_PYTHON_APPEND_TO_INIT

///////////////////////////////////////////////////////////////////////////////
#endif // INIT_JDG20020820_HPP



Web Proxy Viewer  |  New URL  |  Original Page