the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 508 lines 17 kB view raw
1// Boost Lambda Library -- switch.hpp ----------------------------------- 2// 3// Copyright (C) 2000 Gary Powell (powellg@amazon.com) 4// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) 5// 6// Distributed under the Boost Software License, Version 1.0. (See 7// accompanying file LICENSE_1_0.txt or copy at 8// http://www.boost.org/LICENSE_1_0.txt) 9// 10// For more information, see www.boost.org 11 12// -------------------------------------------------------------------------- 13 14#if !defined(BOOST_LAMBDA_SWITCH_HPP) 15#define BOOST_LAMBDA_SWITCH_HPP 16 17#include "boost/lambda/core.hpp" 18#include "boost/lambda/detail/control_constructs_common.hpp" 19 20#include "boost/preprocessor/enum_shifted_params.hpp" 21#include "boost/preprocessor/repeat_2nd.hpp" 22#include "boost/preprocessor/tuple.hpp" 23 24namespace boost { 25namespace lambda { 26 27// Switch actions 28template <int N, class Switch1 = null_type, class Switch2 = null_type, 29 class Switch3 = null_type, class Switch4 = null_type, 30 class Switch5 = null_type, class Switch6 = null_type, 31 class Switch7 = null_type, class Switch8 = null_type, 32 class Switch9 = null_type> 33struct switch_action {}; 34 35 36namespace detail { 37 38 // templates to represent special lambda functors for the cases in 39 // switch statements 40 41template <int Value> struct case_label {}; 42struct default_label {}; 43 44template<class Type> struct switch_case_tag {}; 45 46 // a normal case is represented as: 47 // tagged_lambda_functor<switch_case_tag<case_label<N> > >, LambdaFunctor> 48 49 // the default case as: 50 // tagged_lambda_functor<switch_case_tag<default_label> >, LambdaFunctor> 51 52 53} // end detail 54 55 56/// create switch_case_tag tagged_lambda_functors 57template <int CaseValue, class Arg> 58inline const 59tagged_lambda_functor< 60 detail::switch_case_tag<detail::case_label<CaseValue> >, 61 lambda_functor<Arg> 62> 63case_statement(const lambda_functor<Arg>& a) { 64 return 65 tagged_lambda_functor< 66 detail::switch_case_tag<detail::case_label<CaseValue> >, 67 lambda_functor<Arg> 68 >(a); 69} 70 71// No case body case. 72template <int CaseValue> 73inline const 74tagged_lambda_functor< 75 detail::switch_case_tag<detail::case_label<CaseValue> >, 76 lambda_functor< 77 lambda_functor_base< 78 do_nothing_action, 79 null_type 80 > 81 > 82> 83case_statement() { 84return 85 tagged_lambda_functor< 86 detail::switch_case_tag<detail::case_label<CaseValue> >, 87 lambda_functor< 88 lambda_functor_base< 89 do_nothing_action, 90 null_type 91 > 92 > 93 > () ; 94} 95 96// default label 97template <class Arg> 98inline const 99tagged_lambda_functor< 100 detail::switch_case_tag<detail::default_label>, 101 lambda_functor<Arg> 102> 103default_statement(const lambda_functor<Arg>& a) { 104 return 105 tagged_lambda_functor< 106 detail::switch_case_tag<detail::default_label>, 107 lambda_functor<Arg> 108 >(a); 109} 110 111// default lable, no case body case. 112inline const 113tagged_lambda_functor< 114 detail::switch_case_tag<detail::default_label>, 115 lambda_functor< 116 lambda_functor_base< 117 do_nothing_action, 118 null_type 119 > 120 > 121> 122default_statement() { 123return 124 lambda_functor_base< 125 do_nothing_action, 126 null_type 127 > () ; 128} 129 130 131// Specializations for lambda_functor_base of case_statement ----------------- 132 133// 0 case type: 134// useless (just the condition part) but provided for completeness. 135template<class Args> 136class 137lambda_functor_base< 138 switch_action<1>, 139 Args 140> 141{ 142public: 143 Args args; 144 template <class SigArgs> struct sig { typedef void type; }; 145public: 146 explicit lambda_functor_base(const Args& a) : args(a) {} 147 148 template<class RET, CALL_TEMPLATE_ARGS> 149 RET call(CALL_FORMAL_ARGS) const { 150 detail::select(::boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); 151 } 152}; 153 154// 1 case type: 155// template<class Args, int Case1> 156// class 157// lambda_functor_base< 158// action< 159// 2, 160// return_void_action<switch_action<detail::case_label<Case1> > > 161// >, 162// Args 163// > 164// { 165// Args args; 166// public: 167// explicit lambda_functor_base(const Args& a) : args(a) {} 168 169// template<class RET, class A, class B, class C> 170// RET call(A& a, B& b, C& c) const { 171// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) ) 172// { 173// case Case1: 174// detail::select(::boost::tuples::get<1>(args), a, b, c); 175// break; 176// } 177// } 178// }; 179 180// switch with default being the sole label - doesn't make much sense but 181// it is there for completeness 182// template<class Args> 183// class 184// lambda_functor_base< 185// action< 186// 2, 187// return_void_action<switch_action<detail::default_label> > 188// >, 189// Args 190// > 191// { 192// Args args; 193// public: 194// explicit lambda_functor_base(const Args& a) : args(a) {} 195// 196// template<class RET, class A, class B, class C> 197// RET call(A& a, B& b, C& c) const { 198// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) ) 199// { 200// default: 201// detail::select(::boost::tuples::get<1>(args), a, b, c); 202// break; 203// } 204// } 205// }; 206 207 208 209// // 2 case type: 210// The different specializations are generated with Vesa Karvonen's 211// preprocessor library. 212 213// This is just a comment to show what the generated classes look like 214 215// template<class Args, int Case1, int Case2> 216// class 217// lambda_functor_base< 218// action<3, 219// return_void_action< 220// switch_action< 221// detail::case_label<Case1>, 222// detail::case_label<Case2> 223// > 224// > 225// >, 226// Args 227// > 228// { 229// Args args; 230// public: 231// explicit lambda_functor_base(const Args& a) : args(a) {} 232 233// template<class RET, class A, class B, class C> 234// RET call(A& a, B& b, C& c) const { 235// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) ) 236// { 237// case Case1: 238// detail::select(::boost::tuples::get<1>(args), a, b, c); 239// break; 240// case Case2: 241// detail::select(::boost::tuples::get<2>(args), a, b, c); 242// break; 243// } 244// } 245// }; 246 247// template<class Args, int Case1> 248// class 249// lambda_functor_base< 250// action<3, 251// return_void_action< 252// switch_action< 253// detail::case_label<Case1>, 254// detail::default_label 255// > 256// > 257// >, 258// Args 259// > 260// { 261// Args args; 262// public: 263// explicit lambda_functor_base(const Args& a) : args(a) {} 264 265// template<class RET, class A, class B, class C> 266// RET call(A& a, B& b, C& c) const { 267// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) ) 268// { 269// case Case1: 270// detail::select(::boost::tuples::get<1>(args), a, b, c); 271// break; 272// default: 273// detail::select(::boost::tuples::get<2>(args), a, b, c); 274// break; 275// } 276// } 277// }; 278// ------------------------- 279 280// Some helper preprocessor macros --------------------------------- 281 282// BOOST_LAMBDA_A_I_LIST(N, X) is a list of form X0, X1, ..., XN 283// BOOST_LAMBDA_A_I_B_LIST(N, X, Y) is a list of form X0 Y, X1 Y, ..., XN Y 284 285#define BOOST_LAMBDA_A_I(z, i, A) \ 286BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A,i) 287 288#define BOOST_LAMBDA_A_I_B(z, i, T) \ 289BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,T),i) BOOST_PP_TUPLE_ELEM(2,1,T) 290 291#define BOOST_LAMBDA_A_I_LIST(i, A) \ 292BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I, A) 293 294#define BOOST_LAMBDA_A_I_B_LIST(i, A, B) \ 295BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I_B, (A,B)) 296 297 298// Switch related macros ------------------------------------------- 299#define BOOST_LAMBDA_SWITCH_CASE_BLOCK(z, N, A) \ 300 case Case##N: \ 301 detail::select(::boost::tuples::get<BOOST_PP_INC(N)>(args), CALL_ACTUAL_ARGS); \ 302 break; 303 304#define BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \ 305BOOST_PP_REPEAT(N, BOOST_LAMBDA_SWITCH_CASE_BLOCK, FOO) 306// 2 case type: 307 308#define BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \ 309template<class Args, BOOST_LAMBDA_A_I_LIST(N, int Case)> \ 310class \ 311lambda_functor_base< \ 312 switch_action<BOOST_PP_INC(N), \ 313 BOOST_LAMBDA_A_I_B_LIST(N, detail::case_label<Case,>) \ 314 >, \ 315 Args \ 316> \ 317{ \ 318public: \ 319 Args args; \ 320 template <class SigArgs> struct sig { typedef void type; }; \ 321public: \ 322 explicit lambda_functor_base(const Args& a) : args(a) {} \ 323 \ 324 template<class RET, CALL_TEMPLATE_ARGS> \ 325 RET call(CALL_FORMAL_ARGS) const { \ 326 switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \ 327 { \ 328 BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \ 329 } \ 330 } \ 331}; 332 333 334 335#define BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N) \ 336template< \ 337 class Args BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \ 338 BOOST_LAMBDA_A_I_LIST(BOOST_PP_DEC(N), int Case) \ 339> \ 340class \ 341lambda_functor_base< \ 342 switch_action<BOOST_PP_INC(N), \ 343 BOOST_LAMBDA_A_I_B_LIST(BOOST_PP_DEC(N), \ 344 detail::case_label<Case, >) \ 345 BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \ 346 detail::default_label \ 347 >, \ 348 Args \ 349> \ 350{ \ 351public: \ 352 Args args; \ 353 template <class SigArgs> struct sig { typedef void type; }; \ 354public: \ 355 explicit lambda_functor_base(const Args& a) : args(a) {} \ 356 \ 357 template<class RET, CALL_TEMPLATE_ARGS> \ 358 RET call(CALL_FORMAL_ARGS) const { \ 359 switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \ 360 { \ 361 BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(BOOST_PP_DEC(N)) \ 362 default: \ 363 detail::select(::boost::tuples::get<N>(args), CALL_ACTUAL_ARGS); \ 364 break; \ 365 } \ 366 } \ 367}; 368 369 370 371 372 373 374// switch_statement bind functions ------------------------------------- 375 376// The zero argument case, for completeness sake 377inline const 378lambda_functor< 379 lambda_functor_base< 380 do_nothing_action, 381 null_type 382 > 383> 384switch_statement() { 385 return 386 lambda_functor_base< 387 do_nothing_action, 388 null_type 389 > 390 (); 391} 392 393// 1 argument case, this is useless as well, just the condition part 394template <class TestArg> 395inline const 396lambda_functor< 397 lambda_functor_base< 398 switch_action<1>, 399 tuple<lambda_functor<TestArg> > 400 > 401> 402switch_statement(const lambda_functor<TestArg>& a1) { 403 return 404 lambda_functor_base< 405 switch_action<1>, 406 tuple< lambda_functor<TestArg> > 407 > 408 ( tuple<lambda_functor<TestArg> >(a1)); 409} 410 411 412#define HELPER(z, N, FOO) \ 413BOOST_PP_COMMA_IF(N) \ 414BOOST_PP_CAT( \ 415 const tagged_lambda_functor<detail::switch_case_tag<TagData, \ 416 N>) \ 417BOOST_PP_COMMA() Arg##N>& a##N 418 419#define HELPER_LIST(N) BOOST_PP_REPEAT(N, HELPER, FOO) 420 421 422#define BOOST_LAMBDA_SWITCH_STATEMENT(N) \ 423template <class TestArg, \ 424 BOOST_LAMBDA_A_I_LIST(N, class TagData), \ 425 BOOST_LAMBDA_A_I_LIST(N, class Arg)> \ 426inline const \ 427lambda_functor< \ 428 lambda_functor_base< \ 429 switch_action<BOOST_PP_INC(N), \ 430 BOOST_LAMBDA_A_I_LIST(N, TagData) \ 431 >, \ 432 tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \ 433 > \ 434> \ 435switch_statement( \ 436 const lambda_functor<TestArg>& ta, \ 437 HELPER_LIST(N) \ 438) \ 439{ \ 440 return \ 441 lambda_functor_base< \ 442 switch_action<BOOST_PP_INC(N), \ 443 BOOST_LAMBDA_A_I_LIST(N, TagData) \ 444 >, \ 445 tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \ 446 > \ 447 ( tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \ 448 (ta, BOOST_LAMBDA_A_I_LIST(N, a) )); \ 449} 450 451 452 453 454// Here's the actual generation 455 456#define BOOST_LAMBDA_SWITCH(N) \ 457BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \ 458BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N) 459 460// Use this to avoid case 0, these macros work only from case 1 upwards 461#define BOOST_LAMBDA_SWITCH_HELPER(z, N, A) \ 462BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) ) 463 464// Use this to avoid cases 0 and 1, these macros work only from case 2 upwards 465#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \ 466BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N)) 467 468#ifdef BOOST_MSVC 469#pragma warning(push) 470#pragma warning(disable:4065) 471#endif 472 473 // up to 9 cases supported (counting default:) 474BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_HELPER,FOO) 475BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_STATEMENT_HELPER,FOO) 476 477#ifdef BOOST_MSVC 478#pragma warning(pop) 479#endif 480 481} // namespace lambda 482} // namespace boost 483 484 485#undef HELPER 486#undef HELPER_LIST 487 488#undef BOOST_LAMBDA_SWITCH_HELPER 489#undef BOOST_LAMBDA_SWITCH 490#undef BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE 491#undef BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE 492 493#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK 494#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST 495 496#undef BOOST_LAMBDA_SWITCH_STATEMENT 497#undef BOOST_LAMBDA_SWITCH_STATEMENT_HELPER 498 499 500 501#endif 502 503 504 505 506 507 508