
* mln/accu/count_value.hh: new. --- milena/ChangeLog | 6 + milena/mln/accu/count_value.hh | 204 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+), 0 deletions(-) create mode 100644 milena/mln/accu/count_value.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index 289810b..787b8fc 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,11 @@ 2009-06-23 Guillaume Lazzara <guillaume.lazzara@lrde.epita.fr> + Add accu::count_value. + + * mln/accu/count_value.hh: new. + +2009-06-23 Guillaume Lazzara <guillaume.lazzara@lrde.epita.fr> + Fix compilation warnings. * mln/core/image/vmorph/fun_image.hh: move inline keyword before diff --git a/milena/mln/accu/count_value.hh b/milena/mln/accu/count_value.hh new file mode 100644 index 0000000..12562e1 --- /dev/null +++ b/milena/mln/accu/count_value.hh @@ -0,0 +1,204 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef MLN_ACCU_COUNT_VALUE_HH +# define MLN_ACCU_COUNT_VALUE_HH + +/// \file +/// +/// Define an accumulator that counts the number of different value. + +# include <mln/accu/internal/base.hh> +# include <mln/core/concept/meta_accumulator.hh> +# include <mln/metal/is_a.hh> + +namespace mln +{ + + namespace accu + { + + /// \brief Count a given value. + /// + /// \ingroup modaccuvalues + // + template <typename V> + struct count_value + : public mln::accu::internal::base< unsigned , count_value<V> > + { + typedef V argument; + + count_value(); + explicit count_value(const V& ref); + + /// Manipulators. + /// \{ + void init(); + void take(const argument&); + void take(const count_value<V>& other); + void untake(const argument&); + void untake(const count_value<V>& other); + + /// Force the value of the counter to \a c. + void set_value(unsigned c); + /// \} + + /// Get the value of the accumulator. + unsigned to_result() const; + + /// Check whether this accu is able to return a result. + /// Always true here. + bool is_valid() const; + + protected: + /// The value of the counter. + unsigned count_; + /// The value which must be counted. + V ref_; + + /// Set to false if the reference value is not set. + bool valid_; + }; + + + namespace meta + { + + /// FIXME: How to write a meta accumulator with a constructor taking + /// a generic argument? + /// Meta accumulator for count_value. + struct count_value : public Meta_Accumulator< count_value > + { + + template <typename V> + struct with + { + typedef accu::count_value<V> ret; + }; + + }; + + } // end of namespace mln::accu::meta + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename V> + inline + count_value<V>::count_value() + { + init(); + valid_ = false; + } + + template <typename V> + inline + count_value<V>::count_value(const V& ref) + { + ref_ = ref; + valid_ = true; + init(); + } + + template <typename V> + inline + void + count_value<V>::init() + { + count_ = 0; + } + + template <typename V> + inline + void + count_value<V>::take(const argument& l) + { + if (l == ref_) + ++count_; + } + + template <typename V> + inline + void + count_value<V>::take(const count_value<V>& other) + { + mln_precondition(other.is_valid()); + mln_precondition(other.ref_ == ref_); + count_ += other.count_; + } + + template <typename V> + inline + void + count_value<V>::untake(const argument& l) + { + if (l == ref_) + --count_; + } + + template <typename V> + inline + void + count_value<V>::untake(const count_value<V>& other) + { + mln_precondition(other.is_valid()); + mln_precondition(other.ref_ == ref_); + count_ -= other.count_; + } + + template <typename V> + inline + unsigned + count_value<V>::to_result() const + { + // The background label MUST not be counted. + return count_; + } + + template <typename V> + inline + void + count_value<V>::set_value(unsigned c) + { + count_ = c; + } + + template <typename V> + inline + bool + count_value<V>::is_valid() const + { + return valid_; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::accu + +} // end of namespace mln + + +#endif // ! MLN_ACCU_COUNT_VALUE_HH -- 1.5.6.5