extractor.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // extractor.hpp
  3. //
  4. // Copyright 2005 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005
  8. #define BOOST_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005
  9. #include <boost/preprocessor/tuple/rem.hpp>
  10. #include <boost/preprocessor/array/size.hpp>
  11. #include <boost/preprocessor/array/data.hpp>
  12. #include <boost/preprocessor/array/elem.hpp>
  13. #include <boost/preprocessor/seq/to_array.hpp>
  14. #include <boost/preprocessor/seq/transform.hpp>
  15. #include <boost/preprocessor/repetition/enum_params.hpp>
  16. #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  17. #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
  18. #include <boost/parameter/binding.hpp>
  19. #include <boost/mpl/apply.hpp>
  20. #include <boost/mpl/eval_if.hpp>
  21. #include <boost/type_traits/remove_reference.hpp>
  22. #include <boost/accumulators/accumulators_fwd.hpp>
  23. #include <boost/accumulators/framework/parameters/accumulator.hpp>
  24. namespace boost { namespace accumulators
  25. {
  26. namespace detail
  27. {
  28. template<typename AccumulatorSet, typename Feature>
  29. struct accumulator_set_result
  30. {
  31. typedef typename as_feature<Feature>::type feature_type;
  32. typedef typename mpl::apply<AccumulatorSet, feature_type>::type::result_type type;
  33. };
  34. template<typename Args, typename Feature>
  35. struct argument_pack_result
  36. : accumulator_set_result<
  37. typename remove_reference<
  38. typename parameter::binding<Args, tag::accumulator>::type
  39. >::type
  40. , Feature
  41. >
  42. {
  43. };
  44. template<typename A, typename Feature>
  45. struct extractor_result
  46. : mpl::eval_if<
  47. detail::is_accumulator_set<A>
  48. , accumulator_set_result<A, Feature>
  49. , argument_pack_result<A, Feature>
  50. >
  51. {
  52. };
  53. template<typename Feature, typename AccumulatorSet>
  54. typename extractor_result<AccumulatorSet, Feature>::type
  55. do_extract(AccumulatorSet const &acc, mpl::true_)
  56. {
  57. typedef typename as_feature<Feature>::type feature_type;
  58. return extract_result<feature_type>(acc);
  59. }
  60. template<typename Feature, typename Args>
  61. typename extractor_result<Args, Feature>::type
  62. do_extract(Args const &args, mpl::false_)
  63. {
  64. typedef typename as_feature<Feature>::type feature_type;
  65. return find_accumulator<feature_type>(args[accumulator]).result(args);
  66. }
  67. } // namespace detail
  68. ///////////////////////////////////////////////////////////////////////////////
  69. /// Extracts the result associated with Feature from the specified accumulator_set.
  70. template<typename Feature>
  71. struct extractor
  72. {
  73. typedef extractor<Feature> this_type;
  74. /// The result meta-function for determining the return type of the extractor
  75. template<typename F>
  76. struct result;
  77. template<typename A1>
  78. struct result<this_type(A1)>
  79. : detail::extractor_result<A1, Feature>
  80. {
  81. };
  82. /// Extract the result associated with Feature from the accumulator set
  83. /// \param acc The accumulator set object from which to extract the result
  84. template<typename Arg1>
  85. typename detail::extractor_result<Arg1, Feature>::type
  86. operator ()(Arg1 const &arg1) const
  87. {
  88. // Arg1 could be an accumulator_set or an argument pack containing
  89. // an accumulator_set. Dispatch accordingly.
  90. return detail::do_extract<Feature>(arg1, detail::is_accumulator_set<Arg1>());
  91. }
  92. /// \overload
  93. ///
  94. /// \param a1 Optional named parameter to be passed to the accumulator's result() function.
  95. template<typename AccumulatorSet, typename A1>
  96. typename detail::extractor_result<AccumulatorSet, Feature>::type
  97. operator ()(AccumulatorSet const &acc, A1 const &a1) const
  98. {
  99. BOOST_MPL_ASSERT((detail::is_accumulator_set<AccumulatorSet>));
  100. typedef typename as_feature<Feature>::type feature_type;
  101. return extract_result<feature_type>(acc, a1);
  102. }
  103. // ... other overloads generated by Boost.Preprocessor:
  104. /// INTERNAL ONLY
  105. ///
  106. #define BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP(z, n, _) \
  107. template<BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
  108. struct result<this_type(BOOST_PP_ENUM_PARAMS_Z(z, n, A))> \
  109. : detail::extractor_result<A1, Feature> \
  110. {}; \
  111. template< \
  112. typename AccumulatorSet \
  113. BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
  114. > \
  115. typename detail::extractor_result<AccumulatorSet, Feature>::type \
  116. operator ()( \
  117. AccumulatorSet const &acc \
  118. BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \
  119. ) const \
  120. { \
  121. BOOST_MPL_ASSERT((detail::is_accumulator_set<AccumulatorSet>)); \
  122. typedef typename as_feature<Feature>::type feature_type; \
  123. return extract_result<feature_type>(acc BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a));\
  124. }
  125. BOOST_PP_REPEAT_FROM_TO(
  126. 2
  127. , BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS)
  128. , BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP
  129. , _
  130. )
  131. #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
  132. /// \overload
  133. ///
  134. template<typename AccumulatorSet, typename A1, typename A2, ...>
  135. typename detail::extractor_result<AccumulatorSet, Feature>::type
  136. operator ()(AccumulatorSet const &acc, A1 const &a1, A2 const &a2, ...);
  137. #endif
  138. };
  139. /// INTERNAL ONLY
  140. ///
  141. #define BOOST_ACCUMULATORS_ARRAY_REM(Array) \
  142. BOOST_PP_TUPLE_REM_CTOR(BOOST_PP_ARRAY_SIZE(Array), BOOST_PP_ARRAY_DATA(Array))
  143. /// INTERNAL ONLY
  144. ///
  145. #define BOOST_ACCUMULATORS_SEQ_REM(Seq) \
  146. BOOST_ACCUMULATORS_ARRAY_REM(BOOST_PP_SEQ_TO_ARRAY(Seq))
  147. /// INTERNAL ONLY
  148. ///
  149. #define BOOST_ACCUMULATORS_ARGS_OP(s, data, elem) \
  150. T ## s
  151. /// INTERNAL ONLY
  152. ///
  153. #define BOOST_ACCUMULATORS_PARAMS_OP(s, data, elem) \
  154. elem T ## s
  155. /// INTERNAL ONLY
  156. ///
  157. #define BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \
  158. Tag::Feature< \
  159. BOOST_ACCUMULATORS_SEQ_REM( \
  160. BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_ARGS_OP, ~, ParamsSeq) \
  161. ) \
  162. >
  163. /// INTERNAL ONLY
  164. ///
  165. #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL(z, n, Tag, Feature, ParamsSeq) \
  166. template< \
  167. BOOST_ACCUMULATORS_SEQ_REM( \
  168. BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_PARAMS_OP, ~, ParamsSeq) \
  169. ) \
  170. , typename Arg1 \
  171. BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
  172. > \
  173. typename boost::accumulators::detail::extractor_result< \
  174. Arg1 \
  175. , BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \
  176. >::type \
  177. Feature(Arg1 const &arg1 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) ) \
  178. { \
  179. typedef BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) feature_type; \
  180. return boost::accumulators::extractor<feature_type>()( \
  181. arg1 BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a)); \
  182. }
  183. /// INTERNAL ONLY
  184. ///
  185. #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN(z, n, _) \
  186. BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL( \
  187. z \
  188. , n \
  189. , BOOST_PP_ARRAY_ELEM(0, _) \
  190. , BOOST_PP_ARRAY_ELEM(1, _) \
  191. , BOOST_PP_ARRAY_ELEM(2, _) \
  192. )
  193. #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(Tag, Feature, ParamSeq) \
  194. BOOST_PP_REPEAT( \
  195. BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS) \
  196. , BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN \
  197. , (3, (Tag, Feature, ParamSeq)) \
  198. )
  199. }} // namespace boost::accumulators
  200. #endif