00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_CORE_CONCEPT_ACCUMULATOR_HH
00027 # define MLN_CORE_CONCEPT_ACCUMULATOR_HH
00028
00032
00033 # include <mln/core/concept/proxy.hh>
00034 # include <mln/metal/fix_return.hh>
00035 # include <mln/metal/const.hh>
00036 # include <mln/trait/accumulators.hh>
00037
00038
00039 namespace mln
00040 {
00041
00042
00043 template <typename E> struct Accumulator;
00044
00045
00046 namespace convert
00047 {
00048
00049 namespace over_load
00050 {
00051
00052 template <typename A>
00053 void
00054 from_to_(const Accumulator<A>& from, mln_result(A)& to);
00055
00056 }
00057
00058 }
00059
00060
00061
00062 template <>
00063 struct Accumulator<void>
00064 {
00065 typedef Proxy<void> super;
00066 };
00067
00068
00069
00077 template <typename E>
00078 struct Accumulator : public Proxy<E>
00079 {
00080 typedef Accumulator<void> category;
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00101 template <typename T>
00102 void take_as_init(const T& t);
00103
00105 template <typename T>
00106 void take_as_init_(const T& t);
00107
00108
00113 template <typename T>
00114 void take_n_times(unsigned n, const T& t);
00115
00117 template <typename T>
00118 void take_n_times_(unsigned n, const T& t);
00119
00120
00121 protected:
00122 Accumulator();
00123 };
00124
00125
00126 # ifndef MLN_INCLUDE_ONLY
00127
00128
00129
00130
00131 namespace convert
00132 {
00133
00134 namespace over_load
00135 {
00136
00137 template <typename A>
00138 void
00139 from_to_(const Accumulator<A>& from_, mln_result(A)& to)
00140 {
00141 const A& from = exact(from_);
00142 if (from.is_valid())
00143 to = from.to_result();
00144 else
00145 to = mln_result(A)();
00146 }
00147
00148 }
00149
00150 }
00151
00152
00153
00154
00155
00156 template <typename E>
00157 inline
00158 Accumulator<E>::Accumulator()
00159 {
00160 typedef mln_argument(E) argument;
00161 typedef mln_result(E) result;
00162 typedef mln_q_result(E) q_result;
00163
00164 void (E::*m1)() = & E::init;
00165 m1 = 0;
00166 void (E::*m2)(const argument&) = & E::take;
00167 m2 = 0;
00168 void (E::*m3)(const E&) = & E::take;
00169 m3 = 0;
00170
00171 q_result (E::*m4)() const = & E::to_result;
00172 m4 = 0;
00173 q_result (E::*m5)() const = & E::operator q_result;
00174 m5 = 0;
00175
00176 bool (E::*m6)() const = & E::is_valid;
00177 m6 = 0;
00178 }
00179
00180
00181
00182
00183 template <typename E>
00184 template <typename T>
00185 void
00186 Accumulator<E>::take_as_init(const T& t)
00187 {
00188 typedef mln_exact(T) T_;
00189 typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
00190 typedef mlc_converts_to(T_, E) t_is_accumulator;
00191 mlc_or(t_is_argument, t_is_accumulator)::check();
00192
00193
00194 exact(this)->take_as_init_(t);
00195 }
00196
00197 template <typename E>
00198 template <typename T>
00199 void
00200 Accumulator<E>::take_as_init_(const T& t)
00201 {
00202
00203 exact(this)->init();
00204 exact(this)->take(t);
00205 }
00206
00207
00208
00209
00210 template <typename E>
00211 template <typename T>
00212 void
00213 Accumulator<E>::take_n_times(unsigned n, const T& t)
00214 {
00215 typedef mln_exact(T) T_;
00216 typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
00217 typedef mlc_converts_to(T_, E) t_is_accumulator;
00218 mlc_or(t_is_argument, t_is_accumulator)::check();
00219
00220 if (n == 0u)
00221 return;
00222
00223
00224 exact(this)->take_n_times_(n, t);
00225 }
00226
00227 template <typename E>
00228 template <typename T>
00229 void
00230 Accumulator<E>::take_n_times_(unsigned n, const T& t)
00231 {
00232
00233 for (unsigned i = 0; i < n; ++i)
00234 exact(this)->take(t);
00235 }
00236
00237 # endif // ! MLN_INCLUDE_ONLY
00238
00239 }
00240
00241
00242 #endif // ! MLN_CORE_CONCEPT_ACCUMULATOR_HH