1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/lambda/switch.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,502 @@
1.4 +// Boost Lambda Library -- switch.hpp -----------------------------------
1.5 +//
1.6 +// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
1.7 +// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
1.8 +//
1.9 +// Distributed under the Boost Software License, Version 1.0. (See
1.10 +// accompanying file LICENSE_1_0.txt or copy at
1.11 +// http://www.boost.org/LICENSE_1_0.txt)
1.12 +//
1.13 +// For more information, see www.boost.org
1.14 +
1.15 +// --------------------------------------------------------------------------
1.16 +
1.17 +#if !defined(BOOST_LAMBDA_SWITCH_HPP)
1.18 +#define BOOST_LAMBDA_SWITCH_HPP
1.19 +
1.20 +#include "boost/lambda/core.hpp"
1.21 +#include "boost/lambda/detail/control_constructs_common.hpp"
1.22 +
1.23 +#include "boost/preprocessor/enum_shifted_params.hpp"
1.24 +#include "boost/preprocessor/repeat_2nd.hpp"
1.25 +#include "boost/preprocessor/tuple.hpp"
1.26 +
1.27 +namespace boost {
1.28 +namespace lambda {
1.29 +
1.30 +// Switch actions
1.31 +template <int N, class Switch1 = null_type, class Switch2 = null_type,
1.32 + class Switch3 = null_type, class Switch4 = null_type,
1.33 + class Switch5 = null_type, class Switch6 = null_type,
1.34 + class Switch7 = null_type, class Switch8 = null_type,
1.35 + class Switch9 = null_type>
1.36 +struct switch_action {};
1.37 +
1.38 +
1.39 +namespace detail {
1.40 +
1.41 + // templates to represent special lambda functors for the cases in
1.42 + // switch statements
1.43 +
1.44 +template <int Value> struct case_label {};
1.45 +struct default_label {};
1.46 +
1.47 +template<class Type> struct switch_case_tag {};
1.48 +
1.49 + // a normal case is represented as:
1.50 + // tagged_lambda_functor<switch_case_tag<case_label<N> > >, LambdaFunctor>
1.51 +
1.52 + // the default case as:
1.53 + // tagged_lambda_functor<switch_case_tag<default_label> >, LambdaFunctor>
1.54 +
1.55 +
1.56 +} // end detail
1.57 +
1.58 +
1.59 +/// create switch_case_tag tagged_lambda_functors
1.60 +template <int CaseValue, class Arg>
1.61 +inline const
1.62 +tagged_lambda_functor<
1.63 + detail::switch_case_tag<detail::case_label<CaseValue> >,
1.64 + lambda_functor<Arg>
1.65 +>
1.66 +case_statement(const lambda_functor<Arg>& a) {
1.67 + return
1.68 + tagged_lambda_functor<
1.69 + detail::switch_case_tag<detail::case_label<CaseValue> >,
1.70 + lambda_functor<Arg>
1.71 + >(a);
1.72 +}
1.73 +
1.74 +// No case body case.
1.75 +template <int CaseValue>
1.76 +inline const
1.77 +tagged_lambda_functor<
1.78 + detail::switch_case_tag<detail::case_label<CaseValue> >,
1.79 + lambda_functor<
1.80 + lambda_functor_base<
1.81 + do_nothing_action,
1.82 + null_type
1.83 + >
1.84 + >
1.85 +>
1.86 +case_statement() {
1.87 +return
1.88 + tagged_lambda_functor<
1.89 + detail::switch_case_tag<detail::case_label<CaseValue> >,
1.90 + lambda_functor<
1.91 + lambda_functor_base<
1.92 + do_nothing_action,
1.93 + null_type
1.94 + >
1.95 + >
1.96 + > () ;
1.97 +}
1.98 +
1.99 +// default label
1.100 +template <class Arg>
1.101 +inline const
1.102 +tagged_lambda_functor<
1.103 + detail::switch_case_tag<detail::default_label>,
1.104 + lambda_functor<Arg>
1.105 +>
1.106 +default_statement(const lambda_functor<Arg>& a) {
1.107 + return
1.108 + tagged_lambda_functor<
1.109 + detail::switch_case_tag<detail::default_label>,
1.110 + lambda_functor<Arg>
1.111 + >(a);
1.112 +}
1.113 +
1.114 +// default lable, no case body case.
1.115 +inline const
1.116 +tagged_lambda_functor<
1.117 + detail::switch_case_tag<detail::default_label>,
1.118 + lambda_functor<
1.119 + lambda_functor_base<
1.120 + do_nothing_action,
1.121 + null_type
1.122 + >
1.123 + >
1.124 +>
1.125 +default_statement() {
1.126 +return
1.127 + lambda_functor_base<
1.128 + do_nothing_action,
1.129 + null_type
1.130 + > () ;
1.131 +}
1.132 +
1.133 +
1.134 +// Specializations for lambda_functor_base of case_statement -----------------
1.135 +
1.136 +// 0 case type:
1.137 +// useless (just the condition part) but provided for completeness.
1.138 +template<class Args>
1.139 +class
1.140 +lambda_functor_base<
1.141 + switch_action<1>,
1.142 + Args
1.143 +>
1.144 +{
1.145 +public:
1.146 + Args args;
1.147 + template <class SigArgs> struct sig { typedef void type; };
1.148 +public:
1.149 + explicit lambda_functor_base(const Args& a) : args(a) {}
1.150 +
1.151 + template<class RET, CALL_TEMPLATE_ARGS>
1.152 + RET call(CALL_FORMAL_ARGS) const {
1.153 + detail::select(::boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
1.154 + }
1.155 +};
1.156 +
1.157 +// 1 case type:
1.158 +// template<class Args, int Case1>
1.159 +// class
1.160 +// lambda_functor_base<
1.161 +// action<
1.162 +// 2,
1.163 +// return_void_action<switch_action<detail::case_label<Case1> > >
1.164 +// >,
1.165 +// Args
1.166 +// >
1.167 +// {
1.168 +// Args args;
1.169 +// public:
1.170 +// explicit lambda_functor_base(const Args& a) : args(a) {}
1.171 +
1.172 +// template<class RET, class A, class B, class C>
1.173 +// RET call(A& a, B& b, C& c) const {
1.174 +// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
1.175 +// {
1.176 +// case Case1:
1.177 +// detail::select(::boost::tuples::get<1>(args), a, b, c);
1.178 +// break;
1.179 +// }
1.180 +// }
1.181 +// };
1.182 +
1.183 +// switch with default being the sole label - doesn't make much sense but
1.184 +// it is there for completeness
1.185 +// template<class Args>
1.186 +// class
1.187 +// lambda_functor_base<
1.188 +// action<
1.189 +// 2,
1.190 +// return_void_action<switch_action<detail::default_label> >
1.191 +// >,
1.192 +// Args
1.193 +// >
1.194 +// {
1.195 +// Args args;
1.196 +// public:
1.197 +// explicit lambda_functor_base(const Args& a) : args(a) {}
1.198 +//
1.199 +// template<class RET, class A, class B, class C>
1.200 +// RET call(A& a, B& b, C& c) const {
1.201 +// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
1.202 +// {
1.203 +// default:
1.204 +// detail::select(::boost::tuples::get<1>(args), a, b, c);
1.205 +// break;
1.206 +// }
1.207 +// }
1.208 +// };
1.209 +
1.210 +
1.211 +
1.212 +// // 2 case type:
1.213 +// The different specializations are generated with Vesa Karvonen's
1.214 +// preprocessor library.
1.215 +
1.216 +// This is just a comment to show what the generated classes look like
1.217 +
1.218 +// template<class Args, int Case1, int Case2>
1.219 +// class
1.220 +// lambda_functor_base<
1.221 +// action<3,
1.222 +// return_void_action<
1.223 +// switch_action<
1.224 +// detail::case_label<Case1>,
1.225 +// detail::case_label<Case2>
1.226 +// >
1.227 +// >
1.228 +// >,
1.229 +// Args
1.230 +// >
1.231 +// {
1.232 +// Args args;
1.233 +// public:
1.234 +// explicit lambda_functor_base(const Args& a) : args(a) {}
1.235 +
1.236 +// template<class RET, class A, class B, class C>
1.237 +// RET call(A& a, B& b, C& c) const {
1.238 +// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
1.239 +// {
1.240 +// case Case1:
1.241 +// detail::select(::boost::tuples::get<1>(args), a, b, c);
1.242 +// break;
1.243 +// case Case2:
1.244 +// detail::select(::boost::tuples::get<2>(args), a, b, c);
1.245 +// break;
1.246 +// }
1.247 +// }
1.248 +// };
1.249 +
1.250 +// template<class Args, int Case1>
1.251 +// class
1.252 +// lambda_functor_base<
1.253 +// action<3,
1.254 +// return_void_action<
1.255 +// switch_action<
1.256 +// detail::case_label<Case1>,
1.257 +// detail::default_label
1.258 +// >
1.259 +// >
1.260 +// >,
1.261 +// Args
1.262 +// >
1.263 +// {
1.264 +// Args args;
1.265 +// public:
1.266 +// explicit lambda_functor_base(const Args& a) : args(a) {}
1.267 +
1.268 +// template<class RET, class A, class B, class C>
1.269 +// RET call(A& a, B& b, C& c) const {
1.270 +// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
1.271 +// {
1.272 +// case Case1:
1.273 +// detail::select(::boost::tuples::get<1>(args), a, b, c);
1.274 +// break;
1.275 +// default:
1.276 +// detail::select(::boost::tuples::get<2>(args), a, b, c);
1.277 +// break;
1.278 +// }
1.279 +// }
1.280 +// };
1.281 +// -------------------------
1.282 +
1.283 +// Some helper preprocessor macros ---------------------------------
1.284 +
1.285 +// BOOST_LAMBDA_A_I_LIST(N, X) is a list of form X0, X1, ..., XN
1.286 +// BOOST_LAMBDA_A_I_B_LIST(N, X, Y) is a list of form X0 Y, X1 Y, ..., XN Y
1.287 +
1.288 +#define BOOST_LAMBDA_A_I(z, i, A) \
1.289 +BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A,i)
1.290 +
1.291 +#define BOOST_LAMBDA_A_I_B(z, i, T) \
1.292 +BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,T),i) BOOST_PP_TUPLE_ELEM(2,1,T)
1.293 +
1.294 +#define BOOST_LAMBDA_A_I_LIST(i, A) \
1.295 +BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I, A)
1.296 +
1.297 +#define BOOST_LAMBDA_A_I_B_LIST(i, A, B) \
1.298 +BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I_B, (A,B))
1.299 +
1.300 +
1.301 +// Switch related macros -------------------------------------------
1.302 +#define BOOST_LAMBDA_SWITCH_CASE_BLOCK(z, N, A) \
1.303 + case Case##N: \
1.304 + detail::select(::boost::tuples::get<BOOST_PP_INC(N)>(args), CALL_ACTUAL_ARGS); \
1.305 + break;
1.306 +
1.307 +#define BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \
1.308 +BOOST_PP_REPEAT(N, BOOST_LAMBDA_SWITCH_CASE_BLOCK, FOO)
1.309 +// 2 case type:
1.310 +
1.311 +#define BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \
1.312 +template<class Args, BOOST_LAMBDA_A_I_LIST(N, int Case)> \
1.313 +class \
1.314 +lambda_functor_base< \
1.315 + switch_action<BOOST_PP_INC(N), \
1.316 + BOOST_LAMBDA_A_I_B_LIST(N, detail::case_label<Case,>) \
1.317 + >, \
1.318 + Args \
1.319 +> \
1.320 +{ \
1.321 +public: \
1.322 + Args args; \
1.323 + template <class SigArgs> struct sig { typedef void type; }; \
1.324 +public: \
1.325 + explicit lambda_functor_base(const Args& a) : args(a) {} \
1.326 + \
1.327 + template<class RET, CALL_TEMPLATE_ARGS> \
1.328 + RET call(CALL_FORMAL_ARGS) const { \
1.329 + switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
1.330 + { \
1.331 + BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \
1.332 + } \
1.333 + } \
1.334 +};
1.335 +
1.336 +
1.337 +
1.338 +#define BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N) \
1.339 +template< \
1.340 + class Args BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \
1.341 + BOOST_LAMBDA_A_I_LIST(BOOST_PP_DEC(N), int Case) \
1.342 +> \
1.343 +class \
1.344 +lambda_functor_base< \
1.345 + switch_action<BOOST_PP_INC(N), \
1.346 + BOOST_LAMBDA_A_I_B_LIST(BOOST_PP_DEC(N), \
1.347 + detail::case_label<Case, >) \
1.348 + BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \
1.349 + detail::default_label \
1.350 + >, \
1.351 + Args \
1.352 +> \
1.353 +{ \
1.354 +public: \
1.355 + Args args; \
1.356 + template <class SigArgs> struct sig { typedef void type; }; \
1.357 +public: \
1.358 + explicit lambda_functor_base(const Args& a) : args(a) {} \
1.359 + \
1.360 + template<class RET, CALL_TEMPLATE_ARGS> \
1.361 + RET call(CALL_FORMAL_ARGS) const { \
1.362 + switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
1.363 + { \
1.364 + BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(BOOST_PP_DEC(N)) \
1.365 + default: \
1.366 + detail::select(::boost::tuples::get<N>(args), CALL_ACTUAL_ARGS); \
1.367 + break; \
1.368 + } \
1.369 + } \
1.370 +};
1.371 +
1.372 +
1.373 +
1.374 +
1.375 +
1.376 +
1.377 +// switch_statement bind functions -------------------------------------
1.378 +
1.379 +// The zero argument case, for completeness sake
1.380 +inline const
1.381 +lambda_functor<
1.382 + lambda_functor_base<
1.383 + do_nothing_action,
1.384 + null_type
1.385 + >
1.386 +>
1.387 +switch_statement() {
1.388 + return
1.389 + lambda_functor_base<
1.390 + do_nothing_action,
1.391 + null_type
1.392 + >
1.393 + ();
1.394 +}
1.395 +
1.396 +// 1 argument case, this is useless as well, just the condition part
1.397 +template <class TestArg>
1.398 +inline const
1.399 +lambda_functor<
1.400 + lambda_functor_base<
1.401 + switch_action<1>,
1.402 + tuple<lambda_functor<TestArg> >
1.403 + >
1.404 +>
1.405 +switch_statement(const lambda_functor<TestArg>& a1) {
1.406 + return
1.407 + lambda_functor_base<
1.408 + switch_action<1>,
1.409 + tuple< lambda_functor<TestArg> >
1.410 + >
1.411 + ( tuple<lambda_functor<TestArg> >(a1));
1.412 +}
1.413 +
1.414 +
1.415 +#define HELPER(z, N, FOO) \
1.416 +BOOST_PP_COMMA_IF(N) \
1.417 +BOOST_PP_CAT( \
1.418 + const tagged_lambda_functor<detail::switch_case_tag<TagData, \
1.419 + N>) \
1.420 +BOOST_PP_COMMA() Arg##N>& a##N
1.421 +
1.422 +#define HELPER_LIST(N) BOOST_PP_REPEAT(N, HELPER, FOO)
1.423 +
1.424 +
1.425 +#define BOOST_LAMBDA_SWITCH_STATEMENT(N) \
1.426 +template <class TestArg, \
1.427 + BOOST_LAMBDA_A_I_LIST(N, class TagData), \
1.428 + BOOST_LAMBDA_A_I_LIST(N, class Arg)> \
1.429 +inline const \
1.430 +lambda_functor< \
1.431 + lambda_functor_base< \
1.432 + switch_action<BOOST_PP_INC(N), \
1.433 + BOOST_LAMBDA_A_I_LIST(N, TagData) \
1.434 + >, \
1.435 + tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
1.436 + > \
1.437 +> \
1.438 +switch_statement( \
1.439 + const lambda_functor<TestArg>& ta, \
1.440 + HELPER_LIST(N) \
1.441 +) \
1.442 +{ \
1.443 + return \
1.444 + lambda_functor_base< \
1.445 + switch_action<BOOST_PP_INC(N), \
1.446 + BOOST_LAMBDA_A_I_LIST(N, TagData) \
1.447 + >, \
1.448 + tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
1.449 + > \
1.450 + ( tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
1.451 + (ta, BOOST_LAMBDA_A_I_LIST(N, a) )); \
1.452 +}
1.453 +
1.454 +
1.455 +
1.456 +
1.457 +// Here's the actual generation
1.458 +
1.459 +#define BOOST_LAMBDA_SWITCH(N) \
1.460 +BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \
1.461 +BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N)
1.462 +
1.463 +// Use this to avoid case 0, these macros work only from case 1 upwards
1.464 +#define BOOST_LAMBDA_SWITCH_HELPER(z, N, A) \
1.465 +BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) )
1.466 +
1.467 +// Use this to avoid cases 0 and 1, these macros work only from case 2 upwards
1.468 +#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \
1.469 +BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N))
1.470 +
1.471 +
1.472 +
1.473 + // up to 9 cases supported (counting default:)
1.474 +BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_HELPER,FOO)
1.475 +BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_STATEMENT_HELPER,FOO)
1.476 +
1.477 +
1.478 +} // namespace lambda
1.479 +} // namespace boost
1.480 +
1.481 +
1.482 +#undef HELPER
1.483 +#undef HELPER_LIST
1.484 +
1.485 +#undef BOOST_LAMBDA_SWITCH_HELPER
1.486 +#undef BOOST_LAMBDA_SWITCH
1.487 +#undef BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE
1.488 +#undef BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE
1.489 +
1.490 +#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK
1.491 +#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST
1.492 +
1.493 +#undef BOOST_LAMBDA_SWITCH_STATEMENT
1.494 +#undef BOOST_LAMBDA_SWITCH_STATEMENT_HELPER
1.495 +
1.496 +
1.497 +
1.498 +#endif
1.499 +
1.500 +
1.501 +
1.502 +
1.503 +
1.504 +
1.505 +