File indexing completed on 2025-01-18 09:39:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #if !defined(BOOST_LAMBDA_SWITCH_HPP)
0015 #define BOOST_LAMBDA_SWITCH_HPP
0016
0017 #include "boost/lambda/core.hpp"
0018 #include "boost/lambda/detail/control_constructs_common.hpp"
0019
0020 #include "boost/preprocessor/enum_shifted_params.hpp"
0021 #include "boost/preprocessor/repeat_2nd.hpp"
0022 #include "boost/preprocessor/tuple.hpp"
0023
0024 namespace boost {
0025 namespace lambda {
0026
0027
0028 template <int N, class Switch1 = null_type, class Switch2 = null_type,
0029 class Switch3 = null_type, class Switch4 = null_type,
0030 class Switch5 = null_type, class Switch6 = null_type,
0031 class Switch7 = null_type, class Switch8 = null_type,
0032 class Switch9 = null_type>
0033 struct switch_action {};
0034
0035
0036 namespace detail {
0037
0038
0039
0040
0041 template <int Value> struct case_label {};
0042 struct default_label {};
0043
0044 template<class Type> struct switch_case_tag {};
0045
0046
0047
0048
0049
0050
0051
0052
0053 }
0054
0055
0056
0057 template <int CaseValue, class Arg>
0058 inline const
0059 tagged_lambda_functor<
0060 detail::switch_case_tag<detail::case_label<CaseValue> >,
0061 lambda_functor<Arg>
0062 >
0063 case_statement(const lambda_functor<Arg>& a) {
0064 return
0065 tagged_lambda_functor<
0066 detail::switch_case_tag<detail::case_label<CaseValue> >,
0067 lambda_functor<Arg>
0068 >(a);
0069 }
0070
0071
0072 template <int CaseValue>
0073 inline const
0074 tagged_lambda_functor<
0075 detail::switch_case_tag<detail::case_label<CaseValue> >,
0076 lambda_functor<
0077 lambda_functor_base<
0078 do_nothing_action,
0079 null_type
0080 >
0081 >
0082 >
0083 case_statement() {
0084 return
0085 tagged_lambda_functor<
0086 detail::switch_case_tag<detail::case_label<CaseValue> >,
0087 lambda_functor<
0088 lambda_functor_base<
0089 do_nothing_action,
0090 null_type
0091 >
0092 >
0093 > () ;
0094 }
0095
0096
0097 template <class Arg>
0098 inline const
0099 tagged_lambda_functor<
0100 detail::switch_case_tag<detail::default_label>,
0101 lambda_functor<Arg>
0102 >
0103 default_statement(const lambda_functor<Arg>& a) {
0104 return
0105 tagged_lambda_functor<
0106 detail::switch_case_tag<detail::default_label>,
0107 lambda_functor<Arg>
0108 >(a);
0109 }
0110
0111
0112 inline const
0113 tagged_lambda_functor<
0114 detail::switch_case_tag<detail::default_label>,
0115 lambda_functor<
0116 lambda_functor_base<
0117 do_nothing_action,
0118 null_type
0119 >
0120 >
0121 >
0122 default_statement() {
0123 return
0124 lambda_functor_base<
0125 do_nothing_action,
0126 null_type
0127 > () ;
0128 }
0129
0130
0131
0132
0133
0134
0135 template<class Args>
0136 class
0137 lambda_functor_base<
0138 switch_action<1>,
0139 Args
0140 >
0141 {
0142 public:
0143 Args args;
0144 template <class SigArgs> struct sig { typedef void type; };
0145 public:
0146 explicit lambda_functor_base(const Args& a) : args(a) {}
0147
0148 template<class RET, CALL_TEMPLATE_ARGS>
0149 RET call(CALL_FORMAL_ARGS) const {
0150 detail::select(::boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
0151 }
0152 };
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 #define BOOST_LAMBDA_A_I(z, i, A) \
0286 BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A,i)
0287
0288 #define BOOST_LAMBDA_A_I_B(z, i, T) \
0289 BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,T),i) BOOST_PP_TUPLE_ELEM(2,1,T)
0290
0291 #define BOOST_LAMBDA_A_I_LIST(i, A) \
0292 BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I, A)
0293
0294 #define BOOST_LAMBDA_A_I_B_LIST(i, A, B) \
0295 BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I_B, (A,B))
0296
0297
0298
0299 #define BOOST_LAMBDA_SWITCH_CASE_BLOCK(z, N, A) \
0300 case Case##N: \
0301 detail::select(::boost::tuples::get<BOOST_PP_INC(N)>(args), CALL_ACTUAL_ARGS); \
0302 break;
0303
0304 #define BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \
0305 BOOST_PP_REPEAT(N, BOOST_LAMBDA_SWITCH_CASE_BLOCK, FOO)
0306
0307
0308 #define BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \
0309 template<class Args, BOOST_LAMBDA_A_I_LIST(N, int Case)> \
0310 class \
0311 lambda_functor_base< \
0312 switch_action<BOOST_PP_INC(N), \
0313 BOOST_LAMBDA_A_I_B_LIST(N, detail::case_label<Case,>) \
0314 >, \
0315 Args \
0316 > \
0317 { \
0318 public: \
0319 Args args; \
0320 template <class SigArgs> struct sig { typedef void type; }; \
0321 public: \
0322 explicit lambda_functor_base(const Args& a) : args(a) {} \
0323 \
0324 template<class RET, CALL_TEMPLATE_ARGS> \
0325 RET call(CALL_FORMAL_ARGS) const { \
0326 switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
0327 { \
0328 BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \
0329 } \
0330 } \
0331 };
0332
0333
0334
0335 #define BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N) \
0336 template< \
0337 class Args BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \
0338 BOOST_LAMBDA_A_I_LIST(BOOST_PP_DEC(N), int Case) \
0339 > \
0340 class \
0341 lambda_functor_base< \
0342 switch_action<BOOST_PP_INC(N), \
0343 BOOST_LAMBDA_A_I_B_LIST(BOOST_PP_DEC(N), \
0344 detail::case_label<Case, >) \
0345 BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \
0346 detail::default_label \
0347 >, \
0348 Args \
0349 > \
0350 { \
0351 public: \
0352 Args args; \
0353 template <class SigArgs> struct sig { typedef void type; }; \
0354 public: \
0355 explicit lambda_functor_base(const Args& a) : args(a) {} \
0356 \
0357 template<class RET, CALL_TEMPLATE_ARGS> \
0358 RET call(CALL_FORMAL_ARGS) const { \
0359 switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
0360 { \
0361 BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(BOOST_PP_DEC(N)) \
0362 default: \
0363 detail::select(::boost::tuples::get<N>(args), CALL_ACTUAL_ARGS); \
0364 break; \
0365 } \
0366 } \
0367 };
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 inline const
0378 lambda_functor<
0379 lambda_functor_base<
0380 do_nothing_action,
0381 null_type
0382 >
0383 >
0384 switch_statement() {
0385 return
0386 lambda_functor_base<
0387 do_nothing_action,
0388 null_type
0389 >
0390 ();
0391 }
0392
0393
0394 template <class TestArg>
0395 inline const
0396 lambda_functor<
0397 lambda_functor_base<
0398 switch_action<1>,
0399 tuple<lambda_functor<TestArg> >
0400 >
0401 >
0402 switch_statement(const lambda_functor<TestArg>& a1) {
0403 return
0404 lambda_functor_base<
0405 switch_action<1>,
0406 tuple< lambda_functor<TestArg> >
0407 >
0408 ( tuple<lambda_functor<TestArg> >(a1));
0409 }
0410
0411
0412 #define HELPER(z, N, FOO) \
0413 BOOST_PP_COMMA_IF(N) \
0414 BOOST_PP_CAT( \
0415 const tagged_lambda_functor<detail::switch_case_tag<TagData, \
0416 N>) \
0417 BOOST_PP_COMMA() Arg##N>& a##N
0418
0419 #define HELPER_LIST(N) BOOST_PP_REPEAT(N, HELPER, FOO)
0420
0421
0422 #define BOOST_LAMBDA_SWITCH_STATEMENT(N) \
0423 template <class TestArg, \
0424 BOOST_LAMBDA_A_I_LIST(N, class TagData), \
0425 BOOST_LAMBDA_A_I_LIST(N, class Arg)> \
0426 inline const \
0427 lambda_functor< \
0428 lambda_functor_base< \
0429 switch_action<BOOST_PP_INC(N), \
0430 BOOST_LAMBDA_A_I_LIST(N, TagData) \
0431 >, \
0432 tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
0433 > \
0434 > \
0435 switch_statement( \
0436 const lambda_functor<TestArg>& ta, \
0437 HELPER_LIST(N) \
0438 ) \
0439 { \
0440 return \
0441 lambda_functor_base< \
0442 switch_action<BOOST_PP_INC(N), \
0443 BOOST_LAMBDA_A_I_LIST(N, TagData) \
0444 >, \
0445 tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
0446 > \
0447 ( tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
0448 (ta, BOOST_LAMBDA_A_I_LIST(N, a) )); \
0449 }
0450
0451
0452
0453
0454
0455
0456 #define BOOST_LAMBDA_SWITCH(N) \
0457 BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \
0458 BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N)
0459
0460
0461 #define BOOST_LAMBDA_SWITCH_HELPER(z, N, A) \
0462 BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) )
0463
0464
0465 #define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \
0466 BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N))
0467
0468 #ifdef BOOST_MSVC
0469 #pragma warning(push)
0470 #pragma warning(disable:4065)
0471 #endif
0472
0473
0474 BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_HELPER,FOO)
0475 BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_STATEMENT_HELPER,FOO)
0476
0477 #ifdef BOOST_MSVC
0478 #pragma warning(pop)
0479 #endif
0480
0481 }
0482 }
0483
0484
0485 #undef HELPER
0486 #undef HELPER_LIST
0487
0488 #undef BOOST_LAMBDA_SWITCH_HELPER
0489 #undef BOOST_LAMBDA_SWITCH
0490 #undef BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE
0491 #undef BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE
0492
0493 #undef BOOST_LAMBDA_SWITCH_CASE_BLOCK
0494 #undef BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST
0495
0496 #undef BOOST_LAMBDA_SWITCH_STATEMENT
0497 #undef BOOST_LAMBDA_SWITCH_STATEMENT_HELPER
0498
0499
0500
0501 #endif
0502
0503
0504
0505
0506
0507
0508