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
00027 #ifndef MLN_ACCU_COUNT_VALUE_HH
00028 # define MLN_ACCU_COUNT_VALUE_HH
00029
00033
00034 # include <mln/accu/internal/base.hh>
00035 # include <mln/core/concept/meta_accumulator.hh>
00036 # include <mln/metal/is_a.hh>
00037
00038 namespace mln
00039 {
00040
00041
00042 namespace accu {
00043 template <typename V> struct count_value;
00044 }
00045
00046
00047
00048
00049 namespace trait
00050 {
00051
00052 template <typename V>
00053 struct accumulator_< accu::count_value<V> >
00054 {
00055 typedef accumulator::has_untake::yes has_untake;
00056 typedef accumulator::has_set_value::yes has_set_value;
00057 typedef accumulator::has_stop::no has_stop;
00058 typedef accumulator::when_pix::use_v when_pix;
00059 };
00060
00061 }
00062
00063
00064 namespace accu
00065 {
00066
00070
00071 template <typename V>
00072 struct count_value
00073 : public mln::accu::internal::base< unsigned , count_value<V> >
00074 {
00075 typedef V argument;
00076
00077 count_value();
00078 explicit count_value(const V& ref);
00079
00082 void init();
00083 void take(const argument&);
00084 void take(const count_value<V>& other);
00085 void untake(const argument&);
00086 void untake(const count_value<V>& other);
00087
00089 void set_value(unsigned c);
00091
00093 unsigned to_result() const;
00094
00097 bool is_valid() const;
00098
00099 protected:
00101 unsigned count_;
00103 V ref_;
00104
00106 bool valid_;
00107 };
00108
00109
00110 namespace meta
00111 {
00112
00116 struct count_value : public Meta_Accumulator< count_value >
00117 {
00118
00119 template <typename V>
00120 struct with
00121 {
00122 typedef accu::count_value<V> ret;
00123 };
00124
00125 };
00126
00127 }
00128
00129
00130
00131 # ifndef MLN_INCLUDE_ONLY
00132
00133 template <typename V>
00134 inline
00135 count_value<V>::count_value()
00136 {
00137 init();
00138 valid_ = false;
00139 }
00140
00141 template <typename V>
00142 inline
00143 count_value<V>::count_value(const V& ref)
00144 {
00145 ref_ = ref;
00146 valid_ = true;
00147 init();
00148 }
00149
00150 template <typename V>
00151 inline
00152 void
00153 count_value<V>::init()
00154 {
00155 count_ = 0;
00156 }
00157
00158 template <typename V>
00159 inline
00160 void
00161 count_value<V>::take(const argument& l)
00162 {
00163 if (l == ref_)
00164 ++count_;
00165 }
00166
00167 template <typename V>
00168 inline
00169 void
00170 count_value<V>::take(const count_value<V>& other)
00171 {
00172 mln_precondition(other.is_valid());
00173 mln_precondition(other.ref_ == ref_);
00174 count_ += other.count_;
00175 }
00176
00177 template <typename V>
00178 inline
00179 void
00180 count_value<V>::untake(const argument& l)
00181 {
00182 if (l == ref_)
00183 --count_;
00184 }
00185
00186 template <typename V>
00187 inline
00188 void
00189 count_value<V>::untake(const count_value<V>& other)
00190 {
00191 mln_precondition(other.is_valid());
00192 mln_precondition(other.ref_ == ref_);
00193 count_ -= other.count_;
00194 }
00195
00196 template <typename V>
00197 inline
00198 unsigned
00199 count_value<V>::to_result() const
00200 {
00201
00202 return count_;
00203 }
00204
00205 template <typename V>
00206 inline
00207 void
00208 count_value<V>::set_value(unsigned c)
00209 {
00210 count_ = c;
00211 }
00212
00213 template <typename V>
00214 inline
00215 bool
00216 count_value<V>::is_valid() const
00217 {
00218 return valid_;
00219 }
00220
00221 # endif // ! MLN_INCLUDE_ONLY
00222
00223 }
00224
00225 }
00226
00227
00228 #endif // ! MLN_ACCU_COUNT_VALUE_HH