count.hh 3.88 KB
Newer Older
1
2
// Copyright (C) 2007, 2008 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
///
34
/// \brief 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
  namespace accu
44
45
  {

46
47
    /// \brief Generic counter accumulator class.
    /// The parameter \a T is the type to be count.
48
    template <typename T>
Ugo Jardonnet's avatar
Ugo Jardonnet committed
49
    struct count : public mln::accu::internal::base< unsigned , count<T> >
50
    {
51
      typedef T argument;
52

53
      count();
54

55
56
      /// Manipulators.
      /// \{
57
      void init();
58
      void take(const argument&);
59
      void take(const count<T>& other);
60

61
62
63
      void untake(const argument&);
      void untake(const count<T>& other);

64
      /// Force the value of the counter to \a c.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
65
      void set_value(unsigned c);
66
      /// \}
Thierry Geraud's avatar
Thierry Geraud committed
67

68
      /// Get the value of the accumulator.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
69
      unsigned to_result() const;
70

71
72
73
74
      /// Check whether this accu is able to return a result.
      /// Always true here.
      bool is_valid() const;

75
76
    protected:
      /// The value of the counter.
Ugo Jardonnet's avatar
Ugo Jardonnet committed
77
      unsigned count_;
78
    };
79

80

81
    namespace meta
82
    {
83
84
85

      /// \brief Meta accumulator for count.
      struct count : public Meta_Accumulator< count >
86
      {
87
88
89
	template <typename T>
	struct with
	{
90
	  typedef accu::count<T> ret;
91
	};
92
      };
93
94

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

96

97

98
99
# ifndef MLN_INCLUDE_ONLY

100
    template <typename T>
101
    inline
102
    count<T>::count()
103
104
105
106
    {
      init();
    }

107
    template <typename T>
108
    inline
109
    void
110
    count<T>::init()
111
    {
112
      count_ = 0;
113
114
    }

115
    template <typename T>
116
    inline
117
    void
118
    count<T>::take(const argument&)
119
    {
120
      ++count_;
121
122
    }

123
124
125
126
127
128
129
130
131
    template <typename T>
    inline
    void
    count<T>::untake(const argument&)
    {
      mln_precondition(count_ > 0);
      --count_;
    }

132
    template <typename T>
133
    inline
134
    void
135
    count<T>::take(const count<T>& other)
136
    {
137
      count_ += other.count_;
138
139
    }

140
141
142
143
144
145
146
147
148
    template <typename T>
    inline
    void
    count<T>::untake(const count<T>& other)
    {
      mln_precondition(other.count_ <= count_);
      count_ -= other.count_;
    }

149
    template <typename T>
150
    inline
Ugo Jardonnet's avatar
Ugo Jardonnet committed
151
    unsigned
152
    count<T>::to_result() const
153
    {
154
      return count_;
155
156
    }

157
    template <typename T>
158
    inline
159
    void
Ugo Jardonnet's avatar
Ugo Jardonnet committed
160
    count<T>::set_value(unsigned c)
161
    {
162
      count_ = c;
163
164
    }

165
166
167
    template <typename T>
    inline
    bool
168
    count<T>::is_valid() const
169
170
171
172
    {
      return true;
    }

173
174
# endif // ! MLN_INCLUDE_ONLY

175
  } // end of namespace mln::accu
176
177
178
179

} // end of namespace mln


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