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_ACCU_COUNT_LABELS_HH
00027 # define MLN_ACCU_COUNT_LABELS_HH
00028
00032
00033 # include <mln/accu/internal/base.hh>
00034 # include <mln/core/concept/meta_accumulator.hh>
00035 # include <mln/metal/is_a.hh>
00036
00037 namespace mln
00038 {
00039
00040
00041 namespace value { template <typename E> struct Symbolic; }
00042
00043 namespace accu
00044 {
00045
00050
00051 template <typename L>
00052 struct count_labels
00053 : public mln::accu::internal::base< unsigned , count_labels<L> >,
00054 mlc_is_a(L, mln::value::Symbolic)::check_t
00055 {
00056 typedef L argument;
00057
00058 count_labels();
00059
00062 void init();
00063 void take(const argument&);
00064 void take(const count_labels<L>& other);
00065
00067 void set_value(unsigned c);
00069
00071 unsigned to_result() const;
00072
00075 bool is_valid() const;
00076
00077 protected:
00079 unsigned count_labels_;
00080 std::vector<bool> deja_vu_;
00081 };
00082
00083
00084 namespace meta
00085 {
00086
00088 struct count_labels : public Meta_Accumulator< count_labels >
00089 {
00090 template <typename L>
00091 struct with
00092 {
00093 typedef accu::count_labels<L> ret;
00094 };
00095 };
00096
00097 }
00098
00099
00100
00101 # ifndef MLN_INCLUDE_ONLY
00102
00103 template <typename L>
00104 inline
00105 count_labels<L>::count_labels()
00106 {
00107 init();
00108 }
00109
00110 template <typename L>
00111 inline
00112 void
00113 count_labels<L>::init()
00114 {
00115 count_labels_ = 0;
00116 deja_vu_.resize(mln_max(L), false);
00117 }
00118
00119 template <typename L>
00120 inline
00121 void
00122 count_labels<L>::take(const argument& l)
00123 {
00124 if (!deja_vu_[l])
00125 {
00126 ++count_labels_;
00127 deja_vu_[l] = true;
00128 }
00129
00130
00131 }
00132
00133 template <typename L>
00134 inline
00135 void
00136 count_labels<L>::take(const count_labels<L>& other)
00137 {
00138 count_labels_ += other.count_labels_;
00139 for (unsigned i = 0; i < deja_vu_.size(); ++i)
00140 deja_vu_[i] = deja_vu_[i] || other.deja_vu_[i];
00141 }
00142
00143 template <typename L>
00144 inline
00145 unsigned
00146 count_labels<L>::to_result() const
00147 {
00148
00149 return count_labels_ - 1;
00150 }
00151
00152 template <typename L>
00153 inline
00154 void
00155 count_labels<L>::set_value(unsigned c)
00156 {
00157 count_labels_ = c;
00158 }
00159
00160 template <typename L>
00161 inline
00162 bool
00163 count_labels<L>::is_valid() const
00164 {
00165 return true;
00166 }
00167
00168 # endif // ! MLN_INCLUDE_ONLY
00169
00170 }
00171
00172 }
00173
00174
00175 #endif // ! MLN_ACCU_COUNT_LABELS_HH