File indexing completed on 2025-01-18 09:50:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef INIT_JDG20020820_HPP
0010 #define INIT_JDG20020820_HPP
0011
0012 # include <boost/python/detail/prefix.hpp>
0013
0014 #include <boost/python/detail/type_list.hpp>
0015 #include <boost/python/args_fwd.hpp>
0016 #include <boost/python/detail/make_keyword_range_fn.hpp>
0017 #include <boost/python/def_visitor.hpp>
0018
0019 #include <boost/mpl/if.hpp>
0020 #include <boost/mpl/eval_if.hpp>
0021 #include <boost/mpl/size.hpp>
0022 #include <boost/mpl/iterator_range.hpp>
0023 #include <boost/mpl/empty.hpp>
0024 #include <boost/mpl/begin_end.hpp>
0025 #include <boost/mpl/bool.hpp>
0026 #include <boost/mpl/prior.hpp>
0027 #include <boost/mpl/joint_view.hpp>
0028 #include <boost/mpl/back.hpp>
0029
0030 #include <boost/python/detail/type_traits.hpp>
0031
0032 #include <boost/preprocessor/enum_params_with_a_default.hpp>
0033 #include <boost/preprocessor/enum_params.hpp>
0034
0035 #include <utility>
0036
0037
0038 #define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT \
0039 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \
0040 BOOST_PYTHON_MAX_ARITY, \
0041 class T, \
0042 mpl::void_) \
0043
0044 #define BOOST_PYTHON_OVERLOAD_TYPES \
0045 BOOST_PP_ENUM_PARAMS_Z(1, \
0046 BOOST_PYTHON_MAX_ARITY, \
0047 class T) \
0048
0049 #define BOOST_PYTHON_OVERLOAD_ARGS \
0050 BOOST_PP_ENUM_PARAMS_Z(1, \
0051 BOOST_PYTHON_MAX_ARITY, \
0052 T) \
0053
0054
0055 namespace boost { namespace python {
0056
0057 template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
0058 class init;
0059
0060
0061 template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
0062 struct optional;
0063
0064 namespace detail
0065 {
0066 namespace error
0067 {
0068 template <int keywords, int init_args>
0069 struct more_keywords_than_init_arguments
0070 {
0071 typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1] BOOST_ATTRIBUTE_UNUSED;
0072 };
0073 }
0074
0075
0076
0077
0078
0079
0080 template <class T>
0081 struct is_optional
0082 : mpl::false_
0083 {};
0084
0085 template <BOOST_PYTHON_OVERLOAD_TYPES>
0086 struct is_optional<optional<BOOST_PYTHON_OVERLOAD_ARGS> >
0087 : mpl::true_
0088 {};
0089
0090
0091 template <int NDefaults>
0092 struct define_class_init_helper;
0093
0094 }
0095
0096 template <class DerivedT>
0097 struct init_base : def_visitor<DerivedT>
0098 {
0099 init_base(char const* doc_, detail::keyword_range const& keywords_)
0100 : m_doc(doc_), m_keywords(keywords_)
0101 {}
0102
0103 init_base(char const* doc_)
0104 : m_doc(doc_)
0105 {}
0106
0107 DerivedT const& derived() const
0108 {
0109 return *static_cast<DerivedT const*>(this);
0110 }
0111
0112 char const* doc_string() const
0113 {
0114 return m_doc;
0115 }
0116
0117 detail::keyword_range const& keywords() const
0118 {
0119 return m_keywords;
0120 }
0121
0122 static default_call_policies call_policies()
0123 {
0124 return default_call_policies();
0125 }
0126
0127 private:
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 template <class classT>
0143 void visit(classT& cl) const
0144 {
0145 typedef typename DerivedT::signature signature;
0146 typedef typename DerivedT::n_arguments n_arguments;
0147 typedef typename DerivedT::n_defaults n_defaults;
0148
0149 detail::define_class_init_helper<n_defaults::value>::apply(
0150 cl
0151 , derived().call_policies()
0152 , signature()
0153 , n_arguments()
0154 , derived().doc_string()
0155 , derived().keywords());
0156 }
0157
0158 friend class python::def_visitor_access;
0159
0160 private:
0161 char const* m_doc;
0162 detail::keyword_range m_keywords;
0163 };
0164
0165 template <class CallPoliciesT, class InitT>
0166 class init_with_call_policies
0167 : public init_base<init_with_call_policies<CallPoliciesT, InitT> >
0168 {
0169 typedef init_base<init_with_call_policies<CallPoliciesT, InitT> > base;
0170 public:
0171 typedef typename InitT::n_arguments n_arguments;
0172 typedef typename InitT::n_defaults n_defaults;
0173 typedef typename InitT::signature signature;
0174
0175 init_with_call_policies(
0176 CallPoliciesT const& policies_
0177 , char const* doc_
0178 , detail::keyword_range const& keywords
0179 )
0180 : base(doc_, keywords)
0181 , m_policies(policies_)
0182 {}
0183
0184 CallPoliciesT const& call_policies() const
0185 {
0186 return this->m_policies;
0187 }
0188
0189 private:
0190 CallPoliciesT m_policies;
0191 };
0192
0193
0194
0195
0196 namespace detail
0197 {
0198 template <class S>
0199 struct drop1
0200 : mpl::iterator_range<
0201 typename mpl::begin<S>::type
0202 , typename mpl::prior<
0203 typename mpl::end<S>::type
0204 >::type
0205 >
0206 {};
0207 }
0208
0209 template <BOOST_PYTHON_OVERLOAD_TYPES>
0210 class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
0211 {
0212 typedef init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> > base;
0213 public:
0214 typedef init<BOOST_PYTHON_OVERLOAD_ARGS> self_t;
0215
0216 init(char const* doc_ = 0)
0217 : base(doc_)
0218 {
0219 }
0220
0221 template <std::size_t N>
0222 init(char const* doc_, detail::keywords<N> const& kw)
0223 : base(doc_, kw.range())
0224 {
0225 typedef typename detail::error::more_keywords_than_init_arguments<
0226 N, n_arguments::value + 1
0227 >::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;
0228 }
0229
0230 template <std::size_t N>
0231 init(detail::keywords<N> const& kw, char const* doc_ = 0)
0232 : base(doc_, kw.range())
0233 {
0234 typedef typename detail::error::more_keywords_than_init_arguments<
0235 N, n_arguments::value + 1
0236 >::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;
0237 }
0238
0239 template <class CallPoliciesT>
0240 init_with_call_policies<CallPoliciesT, self_t>
0241 operator[](CallPoliciesT const& policies) const
0242 {
0243 return init_with_call_policies<CallPoliciesT, self_t>(
0244 policies, this->doc_string(), this->keywords());
0245 }
0246
0247 typedef detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS> signature_;
0248
0249 typedef detail::is_optional<
0250 typename mpl::eval_if<
0251 mpl::empty<signature_>
0252 , mpl::false_
0253 , mpl::back<signature_>
0254 >::type
0255 > back_is_optional;
0256
0257 typedef typename mpl::eval_if<
0258 back_is_optional
0259 , mpl::back<signature_>
0260 , mpl::vector0<>
0261 >::type optional_args;
0262
0263 typedef typename mpl::eval_if<
0264 back_is_optional
0265 , mpl::if_<
0266 mpl::empty<optional_args>
0267 , detail::drop1<signature_>
0268 , mpl::joint_view<
0269 detail::drop1<signature_>
0270 , optional_args
0271 >
0272 >
0273 , signature_
0274 >::type signature;
0275
0276
0277
0278
0279 typedef mpl::size<optional_args> n_defaults;
0280 typedef mpl::size<signature> n_arguments;
0281 };
0282
0283
0284
0285
0286
0287
0288
0289
0290 template <BOOST_PYTHON_OVERLOAD_TYPES>
0291 struct optional
0292 : detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS>
0293 {
0294 };
0295
0296 namespace detail
0297 {
0298 template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
0299 inline void def_init_aux(
0300 ClassT& cl
0301 , Signature const&
0302 , NArgs
0303 , CallPoliciesT const& policies
0304 , char const* doc
0305 , detail::keyword_range const& keywords_
0306 )
0307 {
0308 cl.def(
0309 "__init__"
0310 , detail::make_keyword_range_constructor<Signature,NArgs>(
0311 policies
0312 , keywords_
0313 , (typename ClassT::metadata::holder*)0
0314 )
0315 , doc
0316 );
0317 }
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 template <int NDefaults>
0332 struct define_class_init_helper
0333 {
0334
0335 template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
0336 static void apply(
0337 ClassT& cl
0338 , CallPoliciesT const& policies
0339 , Signature const& args
0340 , NArgs
0341 , char const* doc
0342 , detail::keyword_range keywords)
0343 {
0344 detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
0345
0346 if (keywords.second > keywords.first)
0347 --keywords.second;
0348
0349 typedef typename mpl::prior<NArgs>::type next_nargs;
0350 define_class_init_helper<NDefaults-1>::apply(
0351 cl, policies, Signature(), next_nargs(), doc, keywords);
0352 }
0353 };
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365 template <>
0366 struct define_class_init_helper<0> {
0367
0368 template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
0369 static void apply(
0370 ClassT& cl
0371 , CallPoliciesT const& policies
0372 , Signature const& args
0373 , NArgs
0374 , char const* doc
0375 , detail::keyword_range const& keywords)
0376 {
0377 detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
0378 }
0379 };
0380 }
0381
0382 }}
0383
0384 #undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT
0385 #undef BOOST_PYTHON_OVERLOAD_TYPES
0386 #undef BOOST_PYTHON_OVERLOAD_ARGS
0387 #undef BOOST_PYTHON_IS_OPTIONAL_VALUE
0388 #undef BOOST_PYTHON_APPEND_TO_INIT
0389
0390
0391 #endif
0392
0393
0394
0395
0396
0397
0398
0399