Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:42:43

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // extractor.hpp
0003 //
0004 //  Copyright 2005 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 } // namespace detail
0094 
0095 
0096 ///////////////////////////////////////////////////////////////////////////////
0097 /// Extracts the result associated with Feature from the specified accumulator_set.
0098 template<typename Feature>
0099 struct extractor
0100 {
0101     typedef extractor<Feature> this_type;
0102 
0103     /// The result meta-function for determining the return type of the extractor
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     /// Extract the result associated with Feature from the accumulator set
0114     /// \param acc The accumulator set object from which to extract the result
0115     template<typename Arg1>
0116     typename detail::extractor_result<Arg1, Feature>::type
0117     operator ()(Arg1 const &arg1) const
0118     {
0119         // Arg1 could be an accumulator_set or an argument pack containing
0120         // an accumulator_set. Dispatch accordingly.
0121         return detail::do_extract<Feature>(arg1, detail::is_accumulator_set<Arg1>());
0122     }
0123 
0124     /// \overload
0125     ///
0126     /// \param a1 Optional named parameter to be passed to the accumulator's result() function.
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     // ... other overloads generated by Boost.Preprocessor:
0137 
0138     /// INTERNAL ONLY
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     /// \overload
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 }} // namespace boost::accumulators
0179 
0180 /// INTERNAL ONLY
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 /// INTERNAL ONLY
0186 ///
0187 #define BOOST_ACCUMULATORS_SEQ_REM(Seq)                                                             \
0188     BOOST_ACCUMULATORS_ARRAY_REM(BOOST_PP_SEQ_TO_ARRAY(Seq))
0189 
0190 /// INTERNAL ONLY
0191 ///
0192 #define BOOST_ACCUMULATORS_ARGS_OP(s, data, elem)                                                   \
0193     T ## s
0194 
0195 /// INTERNAL ONLY
0196 ///
0197 #define BOOST_ACCUMULATORS_PARAMS_OP(s, data, elem)                                                 \
0198     elem T ## s
0199 
0200 /// INTERNAL ONLY
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 /// INTERNAL ONLY
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 /// INTERNAL ONLY
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