operator_lambda_func_base.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. // Boost Lambda Library - operator_lambda_func_base.hpp -----------------
  2. //
  3. // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // For more information, see www.boost.org
  10. // ------------------------------------------------------------
  11. #ifndef BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP
  12. #define BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP
  13. namespace boost {
  14. namespace lambda {
  15. // These operators cannot be implemented as apply functions of action
  16. // templates
  17. // Specialization for comma.
  18. template<class Args>
  19. class lambda_functor_base<other_action<comma_action>, Args> {
  20. public:
  21. Args args;
  22. public:
  23. explicit lambda_functor_base(const Args& a) : args(a) {}
  24. template<class RET, CALL_TEMPLATE_ARGS>
  25. RET call(CALL_FORMAL_ARGS) const {
  26. return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS),
  27. detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
  28. }
  29. template<class SigArgs> struct sig {
  30. private:
  31. typedef typename
  32. detail::deduce_argument_types<Args, SigArgs>::type rets_t;
  33. public:
  34. typedef typename return_type_2_comma< // comma needs special handling
  35. typename detail::element_or_null<0, rets_t>::type,
  36. typename detail::element_or_null<1, rets_t>::type
  37. >::type type;
  38. };
  39. };
  40. namespace detail {
  41. // helper traits to make the expression shorter, takes binary action
  42. // bound argument tuple, open argument tuple and gives the return type
  43. template<class Action, class Bound, class Open> class binary_rt {
  44. private:
  45. typedef typename
  46. detail::deduce_argument_types<Bound, Open>::type rets_t;
  47. public:
  48. typedef typename return_type_2_prot<
  49. Action,
  50. typename detail::element_or_null<0, rets_t>::type,
  51. typename detail::element_or_null<1, rets_t>::type
  52. >::type type;
  53. };
  54. // same for unary actions
  55. template<class Action, class Bound, class Open> class unary_rt {
  56. private:
  57. typedef typename
  58. detail::deduce_argument_types<Bound, Open>::type rets_t;
  59. public:
  60. typedef typename return_type_1_prot<
  61. Action,
  62. typename detail::element_or_null<0, rets_t>::type
  63. >::type type;
  64. };
  65. } // end detail
  66. // Specialization for logical and (to preserve shortcircuiting)
  67. // this could be done with a macro as the others, code used to be different
  68. template<class Args>
  69. class lambda_functor_base<logical_action<and_action>, Args> {
  70. public:
  71. Args args;
  72. public:
  73. explicit lambda_functor_base(const Args& a) : args(a) {}
  74. template<class RET, CALL_TEMPLATE_ARGS>
  75. RET call(CALL_FORMAL_ARGS) const {
  76. return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) &&
  77. detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
  78. }
  79. template<class SigArgs> struct sig {
  80. typedef typename
  81. detail::binary_rt<logical_action<and_action>, Args, SigArgs>::type type;
  82. };
  83. };
  84. // Specialization for logical or (to preserve shortcircuiting)
  85. // this could be done with a macro as the others, code used to be different
  86. template<class Args>
  87. class lambda_functor_base<logical_action< or_action>, Args> {
  88. public:
  89. Args args;
  90. public:
  91. explicit lambda_functor_base(const Args& a) : args(a) {}
  92. template<class RET, CALL_TEMPLATE_ARGS>
  93. RET call(CALL_FORMAL_ARGS) const {
  94. return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ||
  95. detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
  96. }
  97. template<class SigArgs> struct sig {
  98. typedef typename
  99. detail::binary_rt<logical_action<or_action>, Args, SigArgs>::type type;
  100. };
  101. };
  102. // Specialization for subscript
  103. template<class Args>
  104. class lambda_functor_base<other_action<subscript_action>, Args> {
  105. public:
  106. Args args;
  107. public:
  108. explicit lambda_functor_base(const Args& a) : args(a) {}
  109. template<class RET, CALL_TEMPLATE_ARGS>
  110. RET call(CALL_FORMAL_ARGS) const {
  111. return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)
  112. [detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)];
  113. }
  114. template<class SigArgs> struct sig {
  115. typedef typename
  116. detail::binary_rt<other_action<subscript_action>, Args, SigArgs>::type
  117. type;
  118. };
  119. };
  120. #define BOOST_LAMBDA_BINARY_ACTION(SYMBOL, ACTION_CLASS) \
  121. template<class Args> \
  122. class lambda_functor_base<ACTION_CLASS, Args> { \
  123. public: \
  124. Args args; \
  125. public: \
  126. explicit lambda_functor_base(const Args& a) : args(a) {} \
  127. \
  128. template<class RET, CALL_TEMPLATE_ARGS> \
  129. RET call(CALL_FORMAL_ARGS) const { \
  130. return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) \
  131. SYMBOL \
  132. detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); \
  133. } \
  134. template<class SigArgs> struct sig { \
  135. typedef typename \
  136. detail::binary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
  137. }; \
  138. };
  139. #define BOOST_LAMBDA_PREFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS) \
  140. template<class Args> \
  141. class lambda_functor_base<ACTION_CLASS, Args> { \
  142. public: \
  143. Args args; \
  144. public: \
  145. explicit lambda_functor_base(const Args& a) : args(a) {} \
  146. \
  147. template<class RET, CALL_TEMPLATE_ARGS> \
  148. RET call(CALL_FORMAL_ARGS) const { \
  149. return SYMBOL \
  150. detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); \
  151. } \
  152. template<class SigArgs> struct sig { \
  153. typedef typename \
  154. detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
  155. }; \
  156. };
  157. #define BOOST_LAMBDA_POSTFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS) \
  158. template<class Args> \
  159. class lambda_functor_base<ACTION_CLASS, Args> { \
  160. public: \
  161. Args args; \
  162. public: \
  163. explicit lambda_functor_base(const Args& a) : args(a) {} \
  164. \
  165. template<class RET, CALL_TEMPLATE_ARGS> \
  166. RET call(CALL_FORMAL_ARGS) const { \
  167. return \
  168. detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) SYMBOL; \
  169. } \
  170. template<class SigArgs> struct sig { \
  171. typedef typename \
  172. detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
  173. }; \
  174. };
  175. BOOST_LAMBDA_BINARY_ACTION(+,arithmetic_action<plus_action>)
  176. BOOST_LAMBDA_BINARY_ACTION(-,arithmetic_action<minus_action>)
  177. BOOST_LAMBDA_BINARY_ACTION(*,arithmetic_action<multiply_action>)
  178. BOOST_LAMBDA_BINARY_ACTION(/,arithmetic_action<divide_action>)
  179. BOOST_LAMBDA_BINARY_ACTION(%,arithmetic_action<remainder_action>)
  180. BOOST_LAMBDA_BINARY_ACTION(<<,bitwise_action<leftshift_action>)
  181. BOOST_LAMBDA_BINARY_ACTION(>>,bitwise_action<rightshift_action>)
  182. BOOST_LAMBDA_BINARY_ACTION(&,bitwise_action<and_action>)
  183. BOOST_LAMBDA_BINARY_ACTION(|,bitwise_action<or_action>)
  184. BOOST_LAMBDA_BINARY_ACTION(^,bitwise_action<xor_action>)
  185. BOOST_LAMBDA_BINARY_ACTION(<,relational_action<less_action>)
  186. BOOST_LAMBDA_BINARY_ACTION(>,relational_action<greater_action>)
  187. BOOST_LAMBDA_BINARY_ACTION(<=,relational_action<lessorequal_action>)
  188. BOOST_LAMBDA_BINARY_ACTION(>=,relational_action<greaterorequal_action>)
  189. BOOST_LAMBDA_BINARY_ACTION(==,relational_action<equal_action>)
  190. BOOST_LAMBDA_BINARY_ACTION(!=,relational_action<notequal_action>)
  191. BOOST_LAMBDA_BINARY_ACTION(+=,arithmetic_assignment_action<plus_action>)
  192. BOOST_LAMBDA_BINARY_ACTION(-=,arithmetic_assignment_action<minus_action>)
  193. BOOST_LAMBDA_BINARY_ACTION(*=,arithmetic_assignment_action<multiply_action>)
  194. BOOST_LAMBDA_BINARY_ACTION(/=,arithmetic_assignment_action<divide_action>)
  195. BOOST_LAMBDA_BINARY_ACTION(%=,arithmetic_assignment_action<remainder_action>)
  196. BOOST_LAMBDA_BINARY_ACTION(<<=,bitwise_assignment_action<leftshift_action>)
  197. BOOST_LAMBDA_BINARY_ACTION(>>=,bitwise_assignment_action<rightshift_action>)
  198. BOOST_LAMBDA_BINARY_ACTION(&=,bitwise_assignment_action<and_action>)
  199. BOOST_LAMBDA_BINARY_ACTION(|=,bitwise_assignment_action<or_action>)
  200. BOOST_LAMBDA_BINARY_ACTION(^=,bitwise_assignment_action<xor_action>)
  201. BOOST_LAMBDA_BINARY_ACTION(=,other_action< assignment_action>)
  202. BOOST_LAMBDA_PREFIX_UNARY_ACTION(+, unary_arithmetic_action<plus_action>)
  203. BOOST_LAMBDA_PREFIX_UNARY_ACTION(-, unary_arithmetic_action<minus_action>)
  204. BOOST_LAMBDA_PREFIX_UNARY_ACTION(~, bitwise_action<not_action>)
  205. BOOST_LAMBDA_PREFIX_UNARY_ACTION(!, logical_action<not_action>)
  206. BOOST_LAMBDA_PREFIX_UNARY_ACTION(++, pre_increment_decrement_action<increment_action>)
  207. BOOST_LAMBDA_PREFIX_UNARY_ACTION(--, pre_increment_decrement_action<decrement_action>)
  208. BOOST_LAMBDA_PREFIX_UNARY_ACTION(&,other_action<addressof_action>)
  209. BOOST_LAMBDA_PREFIX_UNARY_ACTION(*,other_action<contentsof_action>)
  210. BOOST_LAMBDA_POSTFIX_UNARY_ACTION(++, post_increment_decrement_action<increment_action>)
  211. BOOST_LAMBDA_POSTFIX_UNARY_ACTION(--, post_increment_decrement_action<decrement_action>)
  212. #undef BOOST_LAMBDA_POSTFIX_UNARY_ACTION
  213. #undef BOOST_LAMBDA_PREFIX_UNARY_ACTION
  214. #undef BOOST_LAMBDA_BINARY_ACTION
  215. } // namespace lambda
  216. } // namespace boost
  217. #endif