count.hpp 2.3 KB
Newer Older
1
2
3
#ifndef MLN_ACCU_ACCUMULATOTS_COUNT_HPP
# define MLN_ACCU_ACCUMULATOTS_COUNT_HPP

4
5
6
/// \file
/// \brief Header file for counting accumulator.

7
# include <mln/accu/accumulator_base.hpp>
8
9
10
11
12
13
14
15
16
17
# include <mln/accu/dontcare.hpp>
# include <utility>

namespace mln
{

  namespace accu
  {
    namespace accumulators
    {
18
19
20
      /// \brief The counting accumulator.
      /// \tparam CountType is underlying the counter type (it must be incrementable,
      ///         and decrementable.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
      template <typename CountType = std::size_t>
      struct count;
    }

    namespace features
    {
      template <typename CountType = std::size_t>
      struct count;
    }

    namespace extractor
    {

      template <typename A>
      inline
36
      auto
37
      count(const Accumulator<A>& acc)
38
        -> decltype(extract(exact(acc), features::count<> ()))
39
      {
40
        return extract(exact(acc), features::count<> ());
41
42
43
44
45
46
47
48
      }

    }


    namespace features
    {
      template <typename CountType>
49
      struct count : simple_feature< count<CountType> >
50
      {
51
52
53
54
55
56
57
58
59
60
61
62
        template <typename T>
        struct apply
        {
          typedef accumulators::count<CountType> type;
        };

        template <typename T>
        accumulators::count<CountType>
        make()
        {
          return accumulators::count<CountType> ();
        }
63
64
65
66
67
68
69
      };
    }

    namespace accumulators
    {

      template <typename CountType>
70
      struct count : accumulator_base< count<CountType>, dontcare, CountType, features::count<> >
71
      {
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
        typedef dontcare		argument_type;
        typedef CountType		result_type;
        typedef boost::mpl::set< features::count<> >	provides;

        count()
          : m_count (0)
        {
        }

        void init()
        {
          m_count = 0;
        }

        void take(const dontcare&)
        {
          ++m_count;
        }

        void untake(const dontcare&)
        {
          --m_count;
        }

        template <typename Other>
        void take(const Accumulator<Other>& other)
        {
          m_count += extractor::count(other);
        }

        friend
        result_type extract(const count& accu, features::count<> )
        {
          return accu.m_count;
        }
107
108

      private:
109
        CountType m_count;
110
111
112
113
114
115
116
117
118
      };

    }

  }

}

#endif // !MLN_ACCU_ACCUMULATOTS_COUNT_HPP