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