extractor.hpp 11 KB

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