ossrv_pub/boost_apis/boost/lambda/switch.hpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ossrv_pub/boost_apis/boost/lambda/switch.hpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,502 @@
+// Boost Lambda Library -- switch.hpp -----------------------------------
+//
+// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
+// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+
+// --------------------------------------------------------------------------
+
+#if !defined(BOOST_LAMBDA_SWITCH_HPP)
+#define BOOST_LAMBDA_SWITCH_HPP
+
+#include "boost/lambda/core.hpp"
+#include "boost/lambda/detail/control_constructs_common.hpp"
+
+#include "boost/preprocessor/enum_shifted_params.hpp"
+#include "boost/preprocessor/repeat_2nd.hpp"
+#include "boost/preprocessor/tuple.hpp"
+
+namespace boost { 
+namespace lambda {
+
+// Switch actions
+template <int N, class Switch1 = null_type, class Switch2 = null_type, 
+          class Switch3 = null_type, class Switch4 = null_type,
+          class Switch5 = null_type, class Switch6 = null_type, 
+          class Switch7 = null_type, class Switch8 = null_type, 
+          class Switch9 = null_type>
+struct switch_action {};
+
+
+namespace detail {
+
+  // templates to represent special lambda functors for the cases in 
+  // switch statements
+  
+template <int Value> struct case_label {};
+struct default_label {};
+
+template<class Type> struct switch_case_tag {};
+
+  // a normal case is represented as:
+  // tagged_lambda_functor<switch_case_tag<case_label<N> > >, LambdaFunctor>
+  
+  // the default case as:
+  // tagged_lambda_functor<switch_case_tag<default_label> >, LambdaFunctor>
+
+
+} // end detail
+
+
+/// create switch_case_tag tagged_lambda_functors
+template <int CaseValue, class Arg>
+inline const 
+tagged_lambda_functor<
+  detail::switch_case_tag<detail::case_label<CaseValue> >, 
+  lambda_functor<Arg> 
+> 
+case_statement(const lambda_functor<Arg>& a) { 
+  return 
+    tagged_lambda_functor<
+      detail::switch_case_tag<detail::case_label<CaseValue> >, 
+      lambda_functor<Arg> 
+    >(a); 
+}
+
+// No case body case.
+template <int CaseValue>
+inline const 
+tagged_lambda_functor<
+  detail::switch_case_tag<detail::case_label<CaseValue> >,
+  lambda_functor< 
+    lambda_functor_base< 
+      do_nothing_action, 
+      null_type
+    > 
+  > 
+> 
+case_statement() { 
+return 
+  tagged_lambda_functor<
+    detail::switch_case_tag<detail::case_label<CaseValue> >,
+    lambda_functor< 
+      lambda_functor_base< 
+        do_nothing_action, 
+        null_type
+      > 
+    > 
+  > () ;
+}
+
+// default label
+template <class Arg>
+inline const 
+tagged_lambda_functor<
+  detail::switch_case_tag<detail::default_label>, 
+  lambda_functor<Arg> 
+> 
+default_statement(const lambda_functor<Arg>& a) { 
+  return 
+    tagged_lambda_functor<
+      detail::switch_case_tag<detail::default_label>, 
+      lambda_functor<Arg> 
+    >(a); 
+}
+
+// default lable, no case body case.
+inline const 
+tagged_lambda_functor<
+  detail::switch_case_tag<detail::default_label>,
+  lambda_functor< 
+    lambda_functor_base< 
+      do_nothing_action, 
+      null_type
+    > 
+  > 
+> 
+default_statement() { 
+return 
+      lambda_functor_base< 
+        do_nothing_action, 
+        null_type 
+      > () ;
+}
+
+
+// Specializations for lambda_functor_base of case_statement -----------------
+
+// 0 case type:
+// useless (just the condition part) but provided for completeness.
+template<class Args>
+class 
+lambda_functor_base<
+  switch_action<1>, 
+  Args
+> 
+{
+public:
+  Args args;
+  template <class SigArgs> struct sig { typedef void type; };
+public:
+  explicit lambda_functor_base(const Args& a) : args(a) {}
+
+  template<class RET, CALL_TEMPLATE_ARGS>
+  RET call(CALL_FORMAL_ARGS) const {
+    detail::select(::boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);  
+  }
+};
+
+// 1 case type:
+// template<class Args, int Case1>
+// class 
+// lambda_functor_base<
+//   action<
+//     2, 
+//     return_void_action<switch_action<detail::case_label<Case1> > > 
+//   >, 
+//   Args
+// > 
+// {
+//   Args args;
+// public:
+//   explicit lambda_functor_base(const Args& a) : args(a) {}
+
+//   template<class RET, class A, class B, class C>
+//   RET call(A& a, B& b, C& c) const {
+//     switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )  
+//     {
+//       case Case1:                
+//         detail::select(::boost::tuples::get<1>(args), a, b, c);
+//         break;
+//     }
+//   }
+// };
+
+// switch with default being the sole label - doesn't make much sense but
+// it is there for completeness
+// template<class Args>
+// class
+// lambda_functor_base<
+//   action<
+//     2,
+//     return_void_action<switch_action<detail::default_label> >
+//   >,
+//   Args
+// >
+// {
+//   Args args;
+// public:
+//   explicit lambda_functor_base(const Args& a) : args(a) {}
+// 
+//   template<class RET, class A, class B, class C>
+//   RET call(A& a, B& b, C& c) const {
+//     switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
+//     {
+//       default:
+//         detail::select(::boost::tuples::get<1>(args), a, b, c);
+//         break;
+//     }
+//   }
+// };
+
+
+
+// // 2 case type:
+// The different specializations are generated with Vesa Karvonen's 
+// preprocessor library.
+
+// This is just a comment to show what the generated classes look like
+
+// template<class Args, int Case1, int Case2>
+// class 
+// lambda_functor_base<
+//   action<3, 
+//     return_void_action< 
+//       switch_action< 
+//         detail::case_label<Case1>,
+//         detail::case_label<Case2>
+//       > 
+//     > 
+//   >, 
+//   Args
+// > 
+// {
+//   Args args;
+// public:
+//   explicit lambda_functor_base(const Args& a) : args(a) {}
+
+//   template<class RET, class A, class B, class C>
+//   RET call(A& a, B& b, C& c) const {
+//     switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )  
+//     {
+//       case Case1:                
+//         detail::select(::boost::tuples::get<1>(args), a, b, c);
+//         break;
+//       case Case2:                
+//         detail::select(::boost::tuples::get<2>(args), a, b, c);
+//         break;
+//     }
+//   }
+// };
+
+// template<class Args, int Case1>
+// class 
+// lambda_functor_base<
+//   action<3, 
+//     return_void_action< 
+//       switch_action< 
+//         detail::case_label<Case1>,
+//         detail::default_label 
+//       > 
+//     > 
+//   >, 
+//   Args
+// > 
+// {
+//   Args args;
+// public:
+//   explicit lambda_functor_base(const Args& a) : args(a) {}
+
+//   template<class RET, class A, class B, class C>
+//   RET call(A& a, B& b, C& c) const {
+//     switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )  
+//     {
+//       case Case1:                
+//         detail::select(::boost::tuples::get<1>(args), a, b, c);
+//         break;
+//       default:                
+//         detail::select(::boost::tuples::get<2>(args), a, b, c);
+//         break;
+//     }
+//   }
+// };
+// -------------------------
+
+// Some helper preprocessor macros ---------------------------------
+
+// BOOST_LAMBDA_A_I_LIST(N, X) is a list of form X0, X1, ..., XN
+// BOOST_LAMBDA_A_I_B_LIST(N, X, Y) is a list of form X0 Y, X1 Y, ..., XN Y
+
+#define BOOST_LAMBDA_A_I(z, i, A) \
+BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A,i)
+
+#define BOOST_LAMBDA_A_I_B(z, i, T) \
+BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,T),i) BOOST_PP_TUPLE_ELEM(2,1,T)
+
+#define BOOST_LAMBDA_A_I_LIST(i, A) \
+BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I, A) 
+
+#define BOOST_LAMBDA_A_I_B_LIST(i, A, B) \
+BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I_B, (A,B)) 
+
+
+// Switch related macros -------------------------------------------
+#define BOOST_LAMBDA_SWITCH_CASE_BLOCK(z, N, A) \
+  case Case##N: \
+  detail::select(::boost::tuples::get<BOOST_PP_INC(N)>(args), CALL_ACTUAL_ARGS); \
+  break;
+
+#define BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \
+BOOST_PP_REPEAT(N, BOOST_LAMBDA_SWITCH_CASE_BLOCK, FOO)
+// 2 case type:
+
+#define BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N)                                \
+template<class Args, BOOST_LAMBDA_A_I_LIST(N, int Case)>                      \
+class                                                                         \
+lambda_functor_base<                                                          \
+      switch_action<BOOST_PP_INC(N),                                          \
+        BOOST_LAMBDA_A_I_B_LIST(N, detail::case_label<Case,>)                 \
+      >,                                                                      \
+  Args                                                                        \
+>                                                                             \
+{                                                                             \
+public:                                                                       \
+  Args args;                                                                  \
+  template <class SigArgs> struct sig { typedef void type; };                 \
+public:                                                                       \
+  explicit lambda_functor_base(const Args& a) : args(a) {}                    \
+                                                                              \
+  template<class RET, CALL_TEMPLATE_ARGS>                                     \
+  RET call(CALL_FORMAL_ARGS) const {                                          \
+    switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
+    {                                                                         \
+      BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N)                                  \
+    }                                                                         \
+  }                                                                           \
+};
+
+        
+
+#define BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N)                              \
+template<                                                                     \
+  class Args BOOST_PP_COMMA_IF(BOOST_PP_DEC(N))                               \
+  BOOST_LAMBDA_A_I_LIST(BOOST_PP_DEC(N), int Case)                            \
+>                                                                             \
+class                                                                         \
+lambda_functor_base<                                                          \
+      switch_action<BOOST_PP_INC(N),                                          \
+        BOOST_LAMBDA_A_I_B_LIST(BOOST_PP_DEC(N),                              \
+                                detail::case_label<Case, >)                   \
+        BOOST_PP_COMMA_IF(BOOST_PP_DEC(N))                                    \
+        detail::default_label                                                 \
+      >,                                                                      \
+  Args                                                                        \
+>                                                                             \
+{                                                                             \
+public:                                                                       \
+  Args args;                                                                  \
+  template <class SigArgs> struct sig { typedef void type; };                 \
+public:                                                                       \
+  explicit lambda_functor_base(const Args& a) : args(a) {}                    \
+                                                                              \
+  template<class RET, CALL_TEMPLATE_ARGS>                                     \
+  RET call(CALL_FORMAL_ARGS) const {                                          \
+    switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
+    {                                                                         \
+        BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(BOOST_PP_DEC(N))                  \
+      default:                                                                \
+        detail::select(::boost::tuples::get<N>(args), CALL_ACTUAL_ARGS);      \
+        break;                                                                \
+    }                                                                         \
+  }                                                                           \
+};
+
+
+
+
+
+
+// switch_statement bind functions -------------------------------------
+
+// The zero argument case, for completeness sake
+inline const 
+lambda_functor< 
+  lambda_functor_base< 
+    do_nothing_action, 
+    null_type
+  > 
+>
+switch_statement() { 
+  return 
+      lambda_functor_base< 
+        do_nothing_action, 
+        null_type
+      > 
+  ();
+}
+
+// 1 argument case, this is useless as well, just the condition part
+template <class TestArg>
+inline const 
+lambda_functor< 
+  lambda_functor_base< 
+    switch_action<1>, 
+    tuple<lambda_functor<TestArg> >
+  > 
+>
+switch_statement(const lambda_functor<TestArg>& a1) { 
+  return 
+      lambda_functor_base< 
+         switch_action<1>, 
+         tuple< lambda_functor<TestArg> > 
+      > 
+    ( tuple<lambda_functor<TestArg> >(a1));
+}
+
+
+#define HELPER(z, N, FOO)                                      \
+BOOST_PP_COMMA_IF(N)                                           \
+BOOST_PP_CAT(                                                  \
+  const tagged_lambda_functor<detail::switch_case_tag<TagData, \
+  N>)                                                          \
+BOOST_PP_COMMA() Arg##N>& a##N
+
+#define HELPER_LIST(N) BOOST_PP_REPEAT(N, HELPER, FOO)
+
+
+#define BOOST_LAMBDA_SWITCH_STATEMENT(N)                              \
+template <class TestArg,                                              \
+          BOOST_LAMBDA_A_I_LIST(N, class TagData),                    \
+          BOOST_LAMBDA_A_I_LIST(N, class Arg)>                        \
+inline const                                                          \
+lambda_functor<                                                       \
+  lambda_functor_base<                                                \
+        switch_action<BOOST_PP_INC(N),                                \
+          BOOST_LAMBDA_A_I_LIST(N, TagData)                           \
+        >,                                                            \
+    tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)>     \
+  >                                                                   \
+>                                                                     \
+switch_statement(                                                     \
+  const lambda_functor<TestArg>& ta,                                  \
+  HELPER_LIST(N)                                                      \
+)                                                                     \
+{                                                                     \
+  return                                                              \
+      lambda_functor_base<                                            \
+            switch_action<BOOST_PP_INC(N),                            \
+              BOOST_LAMBDA_A_I_LIST(N, TagData)                       \
+            >,                                                        \
+        tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
+      >                                                               \
+    ( tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)>   \
+        (ta, BOOST_LAMBDA_A_I_LIST(N, a) ));                          \
+}
+
+
+
+
+// Here's the actual generation
+
+#define BOOST_LAMBDA_SWITCH(N)           \
+BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N)   \
+BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N)        
+
+// Use this to avoid case 0, these macros work only from case 1 upwards
+#define BOOST_LAMBDA_SWITCH_HELPER(z, N, A) \
+BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) )
+
+// Use this to avoid cases 0 and 1, these macros work only from case 2 upwards
+#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \
+BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N))
+
+
+
+  // up to 9 cases supported (counting default:)
+BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_HELPER,FOO)
+BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_STATEMENT_HELPER,FOO)
+
+
+} // namespace lambda 
+} // namespace boost
+
+
+#undef HELPER
+#undef HELPER_LIST
+
+#undef BOOST_LAMBDA_SWITCH_HELPER
+#undef BOOST_LAMBDA_SWITCH
+#undef BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE
+#undef BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE
+
+#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK
+#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST
+
+#undef BOOST_LAMBDA_SWITCH_STATEMENT
+#undef BOOST_LAMBDA_SWITCH_STATEMENT_HELPER
+
+
+
+#endif
+
+
+
+
+
+
+