Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // extractor.hpp Chris@16: // Chris@16: // Copyright 2005 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005 Chris@16: #define BOOST_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace accumulators Chris@16: { Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct accumulator_set_result Chris@16: { Chris@16: typedef typename as_feature::type feature_type; Chris@16: typedef typename mpl::apply::type::result_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct argument_pack_result Chris@16: : accumulator_set_result< Chris@16: typename remove_reference< Chris@16: typename parameter::binding::type Chris@16: >::type Chris@16: , Feature Chris@16: > Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct extractor_result Chris@16: : mpl::eval_if< Chris@16: detail::is_accumulator_set Chris@16: , accumulator_set_result Chris@16: , argument_pack_result Chris@16: > Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: typename extractor_result::type Chris@16: do_extract(AccumulatorSet const &acc, mpl::true_) Chris@16: { Chris@16: typedef typename as_feature::type feature_type; Chris@16: return extract_result(acc); Chris@16: } Chris@16: Chris@16: template Chris@16: typename extractor_result::type Chris@16: do_extract(Args const &args, mpl::false_) Chris@16: { Chris@16: typedef typename as_feature::type feature_type; Chris@16: return find_accumulator(args[accumulator]).result(args); Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// Extracts the result associated with Feature from the specified accumulator_set. Chris@16: template Chris@16: struct extractor Chris@16: { Chris@16: typedef extractor this_type; Chris@16: Chris@16: /// The result meta-function for determining the return type of the extractor Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: : detail::extractor_result Chris@16: { Chris@16: }; Chris@16: Chris@16: /// Extract the result associated with Feature from the accumulator set Chris@16: /// \param acc The accumulator set object from which to extract the result Chris@16: template Chris@16: typename detail::extractor_result::type Chris@16: operator ()(Arg1 const &arg1) const Chris@16: { Chris@16: // Arg1 could be an accumulator_set or an argument pack containing Chris@16: // an accumulator_set. Dispatch accordingly. Chris@16: return detail::do_extract(arg1, detail::is_accumulator_set()); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: /// \param a1 Optional named parameter to be passed to the accumulator's result() function. Chris@16: template Chris@16: typename detail::extractor_result::type Chris@16: operator ()(AccumulatorSet const &acc, A1 const &a1) const Chris@16: { Chris@16: BOOST_MPL_ASSERT((detail::is_accumulator_set)); Chris@16: typedef typename as_feature::type feature_type; Chris@16: return extract_result(acc, a1); Chris@16: } Chris@16: Chris@16: // ... other overloads generated by Boost.Preprocessor: Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP(z, n, _) \ Chris@16: template \ Chris@16: struct result \ Chris@16: : detail::extractor_result \ Chris@16: {}; \ Chris@16: template< \ Chris@16: typename AccumulatorSet \ Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \ Chris@16: > \ Chris@16: typename detail::extractor_result::type \ Chris@16: operator ()( \ Chris@16: AccumulatorSet const &acc \ Chris@16: BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \ Chris@16: ) const \ Chris@16: { \ Chris@16: BOOST_MPL_ASSERT((detail::is_accumulator_set)); \ Chris@16: typedef typename as_feature::type feature_type; \ Chris@16: return extract_result(acc BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a));\ Chris@16: } Chris@16: Chris@16: BOOST_PP_REPEAT_FROM_TO( Chris@16: 2 Chris@16: , BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS) Chris@16: , BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP Chris@16: , _ Chris@16: ) Chris@16: Chris@16: #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED Chris@16: /// \overload Chris@16: /// Chris@16: template Chris@16: typename detail::extractor_result::type Chris@16: operator ()(AccumulatorSet const &acc, A1 const &a1, A2 const &a2, ...); Chris@16: #endif Chris@16: }; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_ARRAY_REM(Array) \ Chris@16: BOOST_PP_TUPLE_REM_CTOR(BOOST_PP_ARRAY_SIZE(Array), BOOST_PP_ARRAY_DATA(Array)) Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_SEQ_REM(Seq) \ Chris@16: BOOST_ACCUMULATORS_ARRAY_REM(BOOST_PP_SEQ_TO_ARRAY(Seq)) Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_ARGS_OP(s, data, elem) \ Chris@16: T ## s Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_PARAMS_OP(s, data, elem) \ Chris@16: elem T ## s Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \ Chris@16: Tag::Feature< \ Chris@16: BOOST_ACCUMULATORS_SEQ_REM( \ Chris@16: BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_ARGS_OP, ~, ParamsSeq) \ Chris@16: ) \ Chris@16: > Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL(z, n, Tag, Feature, ParamsSeq) \ Chris@16: template< \ Chris@16: BOOST_ACCUMULATORS_SEQ_REM( \ Chris@16: BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_PARAMS_OP, ~, ParamsSeq) \ Chris@16: ) \ Chris@16: , typename Arg1 \ Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \ Chris@16: > \ Chris@16: typename boost::accumulators::detail::extractor_result< \ Chris@16: Arg1 \ Chris@16: , BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \ Chris@16: >::type \ Chris@16: Feature(Arg1 const &arg1 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) ) \ Chris@16: { \ Chris@16: typedef BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) feature_type; \ Chris@16: return boost::accumulators::extractor()( \ Chris@16: arg1 BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a)); \ Chris@16: } Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN(z, n, _) \ Chris@16: BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL( \ Chris@16: z \ Chris@16: , n \ Chris@16: , BOOST_PP_ARRAY_ELEM(0, _) \ Chris@16: , BOOST_PP_ARRAY_ELEM(1, _) \ Chris@16: , BOOST_PP_ARRAY_ELEM(2, _) \ Chris@16: ) Chris@16: Chris@16: #define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(Tag, Feature, ParamSeq) \ Chris@16: BOOST_PP_REPEAT( \ Chris@16: BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS) \ Chris@16: , BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN \ Chris@16: , (3, (Tag, Feature, ParamSeq)) \ Chris@16: ) Chris@16: Chris@16: }} // namespace boost::accumulators Chris@16: Chris@16: #endif