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