count.hh 4.37 KB
Newer Older
Guillaume Lazzara's avatar
Guillaume Lazzara committed
1
2
// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
// Laboratory (LRDE)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//
// This file is part of the Olena Library.  This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
// This library 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 this library; see the file COPYING.  If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free
// software library 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.

Thierry Geraud's avatar
Thierry Geraud committed
29
30
#ifndef MLN_ACCU_COUNT_HH
# define MLN_ACCU_COUNT_HH
31

32
/// \file mln/accu/count.hh
33
///
Guillaume Lazzara's avatar
Guillaume Lazzara committed
34
/// Define an accumulator that counts.
35

36
# include <mln/accu/internal/base.hh>
37
# include <mln/core/concept/meta_accumulator.hh>
38

39

40
41
42
namespace mln
{

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  // Forward declaration.
  namespace accu { template <typename T> struct count; }


  // Traits.

  namespace trait
  {

    template <typename T>
    struct accumulator_< accu::count<T> >
    {
      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


64
  namespace accu
65
66
  {

Guillaume Lazzara's avatar
Guillaume Lazzara committed
67
    /// \brief Generic counter accumulator.
68
    /// The parameter \a T is the type to be count.
Guillaume Lazzara's avatar
Guillaume Lazzara committed
69
70
71
    ///
    /// \ingroup modaccusiteset
    //
72
    template <typename T>
Ugo Jardonnet's avatar
Ugo Jardonnet committed
73
    struct count : public mln::accu::internal::base< unsigned , count<T> >
74
    {
75
      typedef T argument;
76

77
      count();
78

79
80
      /// Manipulators.
      /// \{
81
      void init();
82
      void take(const argument&);
83
      void take(const count<T>& other);
84

85
86
87
      void untake(const argument&);
      void untake(const count<T>& other);

88
      /// Force the value of the counter to \a c.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
89
      void set_value(unsigned c);
90
      /// \}
Thierry Geraud's avatar
Thierry Geraud committed
91

92
      /// Get the value of the accumulator.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
93
      unsigned to_result() const;
94

95
96
97
98
      /// Check whether this accu is able to return a result.
      /// Always true here.
      bool is_valid() const;

99
100
    protected:
      /// The value of the counter.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
101
      unsigned count_;
102
    };
103

104

105
    namespace meta
106
    {
107

Guillaume Lazzara's avatar
Guillaume Lazzara committed
108
      /// Meta accumulator for count.
109
      struct count : public Meta_Accumulator< count >
110
      {
111
112
113
	template <typename T>
	struct with
	{
114
	  typedef accu::count<T> ret;
115
	};
116
      };
117
118

    } // end of namespace mln::accu::meta
119

120

121

122
123
# ifndef MLN_INCLUDE_ONLY

124
    template <typename T>
125
    inline
126
    count<T>::count()
127
128
129
130
    {
      init();
    }

131
    template <typename T>
132
    inline
133
    void
134
    count<T>::init()
135
    {
136
      count_ = 0;
137
138
    }

139
    template <typename T>
140
    inline
141
    void
142
    count<T>::take(const argument&)
143
    {
144
      ++count_;
145
146
    }

147
148
149
150
151
152
153
154
155
    template <typename T>
    inline
    void
    count<T>::untake(const argument&)
    {
      mln_precondition(count_ > 0);
      --count_;
    }

156
    template <typename T>
157
    inline
158
    void
159
    count<T>::take(const count<T>& other)
160
    {
161
      count_ += other.count_;
162
163
    }

164
165
166
167
168
169
170
171
172
    template <typename T>
    inline
    void
    count<T>::untake(const count<T>& other)
    {
      mln_precondition(other.count_ <= count_);
      count_ -= other.count_;
    }

173
    template <typename T>
174
    inline
Ugo Jardonnet's avatar
Ugo Jardonnet committed
175
    unsigned
176
    count<T>::to_result() const
177
    {
178
      return count_;
179
180
    }

181
    template <typename T>
182
    inline
183
    void
Ugo Jardonnet's avatar
Ugo Jardonnet committed
184
    count<T>::set_value(unsigned c)
185
    {
186
      count_ = c;
187
188
    }

189
190
191
    template <typename T>
    inline
    bool
192
    count<T>::is_valid() const
193
194
195
196
    {
      return true;
    }

197
198
# endif // ! MLN_INCLUDE_ONLY

199
  } // end of namespace mln::accu
200
201
202
203

} // end of namespace mln


Thierry Geraud's avatar
Thierry Geraud committed
204
#endif // ! MLN_ACCU_COUNT_HH