annotate DEPENDENCIES/generic/include/boost/lambda/switch.hpp @ 133:4acb5d8d80b6 tip

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