the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at master 421 lines 12 kB view raw
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