count.hh 4.24 KB
Newer Older
1
// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2
//
3
// This file is part of Olena.
4
//
5
6
7
8
9
// 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,
10
11
12
13
14
// 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
15
// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
16
17
//
// As a special exception, you may use this file as part of a free
18
// software project without restriction.  Specifically, if other files
19
// instantiate templates or use macros or inline functions from this
20
21
22
23
24
// 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.
25

Thierry Geraud's avatar
Thierry Geraud committed
26
27
#ifndef MLN_ACCU_COUNT_HH
# define MLN_ACCU_COUNT_HH
28

29
/// \file
30
///
Guillaume Lazzara's avatar
Guillaume Lazzara committed
31
/// Define an accumulator that counts.
32

33
# include <mln/accu/internal/base.hh>
34
# include <mln/core/concept/meta_accumulator.hh>
35

36

37
38
39
namespace mln
{

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  // 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


61
  namespace accu
62
63
  {

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

74
      count();
75

76
77
      /// Manipulators.
      /// \{
78
      void init();
79
      void take(const argument&);
80
      void take(const count<T>& other);
81

82
83
84
      void untake(const argument&);
      void untake(const count<T>& other);

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

89
      /// Get the value of the accumulator.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
90
      unsigned to_result() const;
91

92
93
94
95
      /// Check whether this accu is able to return a result.
      /// Always true here.
      bool is_valid() const;

96
97
    protected:
      /// The value of the counter.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
98
      unsigned count_;
99
    };
100

101

102
    namespace meta
103
    {
104

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

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

117

118

119
120
# ifndef MLN_INCLUDE_ONLY

121
    template <typename T>
122
    inline
123
    count<T>::count()
124
125
126
127
    {
      init();
    }

128
    template <typename T>
129
    inline
130
    void
131
    count<T>::init()
132
    {
133
      count_ = 0;
134
135
    }

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

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

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

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

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

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

186
187
188
    template <typename T>
    inline
    bool
189
    count<T>::is_valid() const
190
191
192
193
    {
      return true;
    }

194
195
# endif // ! MLN_INCLUDE_ONLY

196
  } // end of namespace mln::accu
197
198
199
200

} // end of namespace mln


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