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 +