File indexing completed on 2025-12-16 09:42:43
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005
0009 #define BOOST_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005
0010
0011 #include <boost/preprocessor/cat.hpp>
0012 #include <boost/preprocessor/tuple/rem.hpp>
0013 #include <boost/preprocessor/array/size.hpp>
0014 #include <boost/preprocessor/array/data.hpp>
0015 #include <boost/preprocessor/array/elem.hpp>
0016 #include <boost/preprocessor/seq/to_array.hpp>
0017 #include <boost/preprocessor/seq/transform.hpp>
0018 #include <boost/preprocessor/repetition/enum_params.hpp>
0019 #include <boost/preprocessor/repetition/enum_trailing.hpp>
0020 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0021 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
0022 #include <boost/preprocessor/repetition/repeat.hpp>
0023 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
0024 #include <boost/parameter/binding.hpp>
0025 #include <boost/mpl/bool.hpp>
0026 #include <boost/mpl/if.hpp>
0027 #include <boost/mpl/eval_if.hpp>
0028 #include <boost/mpl/apply.hpp>
0029 #include <boost/type_traits/remove_const.hpp>
0030 #include <boost/type_traits/remove_reference.hpp>
0031 #include <boost/accumulators/accumulators_fwd.hpp>
0032 #include <boost/accumulators/framework/parameters/accumulator.hpp>
0033
0034 namespace boost { namespace accumulators
0035 {
0036
0037 namespace detail
0038 {
0039 template<typename AccumulatorSet, typename Feature>
0040 struct accumulator_set_result
0041 {
0042 typedef typename as_feature<Feature>::type feature_type;
0043 typedef typename mpl::apply<
0044 typename boost::remove_const<
0045 typename boost::remove_reference<AccumulatorSet>::type
0046 >::type
0047 , feature_type
0048 >::type::result_type type;
0049 };
0050
0051 template<typename Args, typename Feature>
0052 struct argument_pack_result
0053 : accumulator_set_result<
0054 typename boost::remove_reference<
0055 typename parameter::binding<
0056 typename boost::remove_const<
0057 typename boost::remove_reference<Args>::type
0058 >::type
0059 , tag::accumulator
0060 >::type
0061 >::type
0062 , Feature
0063 >
0064 {
0065 };
0066
0067 template<typename A, typename Feature>
0068 struct extractor_result
0069 : mpl::eval_if<
0070 detail::is_accumulator_set<A>
0071 , accumulator_set_result<A, Feature>
0072 , argument_pack_result<A, Feature>
0073 >
0074 {
0075 };
0076
0077 template<typename Feature, typename AccumulatorSet>
0078 typename extractor_result<AccumulatorSet, Feature>::type
0079 do_extract(AccumulatorSet const &acc, mpl::true_)
0080 {
0081 typedef typename as_feature<Feature>::type feature_type;
0082 return extract_result<feature_type>(acc);
0083 }
0084
0085 template<typename Feature, typename Args>
0086 typename extractor_result<Args, Feature>::type
0087 do_extract(Args const &args, mpl::false_)
0088 {
0089 typedef typename as_feature<Feature>::type feature_type;
0090 return find_accumulator<feature_type>(args[accumulator]).result(args);
0091 }
0092
0093 }
0094
0095
0096
0097
0098 template<typename Feature>
0099 struct extractor
0100 {
0101 typedef extractor<Feature> this_type;
0102
0103
0104 template<typename F>
0105 struct result;
0106
0107 template<typename A1>
0108 struct result<this_type(A1)>
0109 : detail::extractor_result<A1, Feature>
0110 {
0111 };
0112
0113
0114
0115 template<typename Arg1>
0116 typename detail::extractor_result<Arg1, Feature>::type
0117 operator ()(Arg1 const &arg1) const
0118 {
0119
0120
0121 return detail::do_extract<Feature>(arg1, detail::is_accumulator_set<Arg1>());
0122 }
0123
0124
0125
0126
0127 template<typename AccumulatorSet, typename A1>
0128 typename detail::extractor_result<AccumulatorSet, Feature>::type
0129 operator ()(AccumulatorSet const &acc, A1 const &a1) const
0130 {
0131 BOOST_MPL_ASSERT((detail::is_accumulator_set<AccumulatorSet>));
0132 typedef typename as_feature<Feature>::type feature_type;
0133 return extract_result<feature_type>(acc, a1);
0134 }
0135
0136
0137
0138
0139
0140 #define BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP(z, n, _) \
0141 template<BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
0142 struct result<this_type(BOOST_PP_ENUM_PARAMS_Z(z, n, A))> \
0143 : detail::extractor_result<A1, Feature> \
0144 {}; \
0145 template< \
0146 typename AccumulatorSet \
0147 BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
0148 > \
0149 typename detail::extractor_result<AccumulatorSet, Feature>::type \
0150 operator ()( \
0151 AccumulatorSet const &acc \
0152 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \
0153 ) const \
0154 { \
0155 BOOST_MPL_ASSERT((detail::is_accumulator_set<AccumulatorSet>)); \
0156 typedef typename as_feature<Feature>::type feature_type; \
0157 return extract_result<feature_type>(acc BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a));\
0158 }
0159
0160 BOOST_PP_REPEAT_FROM_TO(
0161 2
0162 , BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS)
0163 , BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP
0164 , _
0165 )
0166
0167 #undef BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP
0168
0169 #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
0170
0171
0172 template<typename AccumulatorSet, typename A1, typename A2, ...>
0173 typename detail::extractor_result<AccumulatorSet, Feature>::type
0174 operator ()(AccumulatorSet const &acc, A1 const &a1, A2 const &a2, ...);
0175 #endif
0176 };
0177
0178 }}
0179
0180
0181
0182 #define BOOST_ACCUMULATORS_ARRAY_REM(Array) \
0183 BOOST_PP_TUPLE_REM_CTOR(BOOST_PP_ARRAY_SIZE(Array), BOOST_PP_ARRAY_DATA(Array))
0184
0185
0186
0187 #define BOOST_ACCUMULATORS_SEQ_REM(Seq) \
0188 BOOST_ACCUMULATORS_ARRAY_REM(BOOST_PP_SEQ_TO_ARRAY(Seq))
0189
0190
0191
0192 #define BOOST_ACCUMULATORS_ARGS_OP(s, data, elem) \
0193 T ## s
0194
0195
0196
0197 #define BOOST_ACCUMULATORS_PARAMS_OP(s, data, elem) \
0198 elem T ## s
0199
0200
0201
0202 #define BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \
0203 Tag::Feature< \
0204 BOOST_ACCUMULATORS_SEQ_REM( \
0205 BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_ARGS_OP, ~, ParamsSeq) \
0206 ) \
0207 >
0208
0209
0210
0211 #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL(z, n, Tag, Feature, ParamsSeq) \
0212 template< \
0213 BOOST_ACCUMULATORS_SEQ_REM( \
0214 BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_PARAMS_OP, ~, ParamsSeq) \
0215 ) \
0216 , typename Arg1 \
0217 BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
0218 > \
0219 typename boost::accumulators::detail::extractor_result< \
0220 Arg1 \
0221 , BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \
0222 >::type \
0223 Feature(Arg1 const &arg1 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) ) \
0224 { \
0225 typedef BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) feature_type; \
0226 return boost::accumulators::extractor<feature_type>()( \
0227 arg1 BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a)); \
0228 }
0229
0230
0231
0232 #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN(z, n, _) \
0233 BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL( \
0234 z \
0235 , n \
0236 , BOOST_PP_ARRAY_ELEM(0, _) \
0237 , BOOST_PP_ARRAY_ELEM(1, _) \
0238 , BOOST_PP_ARRAY_ELEM(2, _) \
0239 )
0240
0241 #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(Tag, Feature, ParamSeq) \
0242 BOOST_PP_REPEAT( \
0243 BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS) \
0244 , BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN \
0245 , (3, (Tag, Feature, ParamSeq)) \
0246 )
0247
0248 #endif