// Copyright (C) 2007, 2008, 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 .
//
// 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_HH
# define MLN_ACCU_COUNT_HH
/// \file
///
/// Define an accumulator that counts.
# include
# include
namespace mln
{
// Forward declaration.
namespace accu { template struct count; }
// Traits.
namespace trait
{
template
struct accumulator_< accu::count >
{
typedef accumulator::has_untake::yes has_untake;
typedef accumulator::has_set_value::yes has_set_value;
typedef accumulator::has_stop::no has_stop;
typedef accumulator::when_pix::use_pix when_pix;
};
} // end of namespace mln::trait
namespace accu
{
/// \brief Generic counter accumulator.
/// The parameter \a T is the type to be count.
///
/// \ingroup modaccusiteset
//
template
struct count : public mln::accu::internal::base< unsigned , count >
{
typedef T argument;
count();
/// Manipulators.
/// \{
void init();
void take(const argument&);
void take(const count& other);
void untake(const argument&);
void untake(const count& 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_;
};
namespace meta
{
/// Meta accumulator for count.
struct count : public Meta_Accumulator< count >
{
template
struct with
{
typedef accu::count ret;
};
};
} // end of namespace mln::accu::meta
# ifndef MLN_INCLUDE_ONLY
template
inline
count::count()
{
init();
}
template
inline
void
count::init()
{
count_ = 0;
}
template
inline
void
count::take(const argument&)
{
++count_;
}
template
inline
void
count::untake(const argument&)
{
mln_precondition(count_ > 0);
--count_;
}
template
inline
void
count::take(const count& other)
{
count_ += other.count_;
}
template
inline
void
count::untake(const count& other)
{
mln_precondition(other.count_ <= count_);
count_ -= other.count_;
}
template
inline
unsigned
count::to_result() const
{
return count_;
}
template
inline
void
count::set_value(unsigned c)
{
count_ = c;
}
template
inline
bool
count::is_valid() const
{
return true;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::accu
} // end of namespace mln
#endif // ! MLN_ACCU_COUNT_HH