accumulator.hpp 3.97 KB
Newer Older
1
#pragma once
Edwin Carlinet's avatar
Edwin Carlinet committed
2

Michaël Roynard's avatar
Michaël Roynard committed
3
4
5
#include <mln/accu/composite_accumulator.hpp>
#include <mln/accu/concept/accumulator.hpp>
#include <mln/accu/feature.hpp>
6

7
8
9
10
11
12
/// \defgroup accu Accumulator framework
/// \{

/// \file
/// \brief Header file for the accumulator framework

Edwin Carlinet's avatar
Edwin Carlinet committed
13
14
15
16
17
18
namespace mln
{

  namespace accu
  {

19
    /// \brief The namespace for accumulator features.
20
    namespace features
Edwin Carlinet's avatar
Edwin Carlinet committed
21
    {
22
    }
Edwin Carlinet's avatar
Edwin Carlinet committed
23

24
    /// \brief The namespace for accumulator object themselves.
25
26
27
    namespace accumulators
    {
    }
Edwin Carlinet's avatar
Edwin Carlinet committed
28

29
    /// \brief The namespace for feature extractor.
30
31
32
    namespace extractor
    {
    }
Edwin Carlinet's avatar
Edwin Carlinet committed
33

Michaël Roynard's avatar
Michaël Roynard committed
34
#ifdef MLN_DOXYGEN
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    /// \brief Make a concrete accumulator from an accumulator-like object \p accu.
    /// If \p accu is a feature-set, it is bound to the argument type of \p arg, otherwise
    /// \tparam A the accumulator-like type.
    /// \tparam T the value type to accumulate
    /// \param accu the accumulator-like object
    /// \param arg a value prototype to accumulate
    ///
    /// \code
    /// accu::features::max<> myfeat;
    /// auto myaccu = accu::make_accumulator(myfeat, int());
    /// myaccu.init();
    /// myaccu.take(15); myaccu.take(5);
    /// int m = myaccu.to_result() // 15
    /// \endcode
    ///
    template <typename A, typename T>
51
    unspecified make_accumulator(const AccumulatorLike<A>& accu, const T& arg);
52
53
54
55
56
57
58
59
60
61

    /// \brief Helper structure to get the return type of an accumulator-like object.
    /// It defines an internal member type named \p type which is the result type
    /// of the accumulator
    /// \tparam AccuLike The type of the accumulator-like object.
    /// \tparam T The argument type (the type of values to accumulate)
    /// \tparam Extractor The function used to extract the result from the accumulator
    template <typename AccuLike, typename T, typename Extractor = default_extractor>
    struct result_of
    {
62
63
      typedef unspecified type;
    };
64
65
66
67

    /// \brief The defaut extractor
    /// It calls the `to_result` method of the accumulator.
    struct default_extractor;
Michaël Roynard's avatar
Michaël Roynard committed
68
#endif
69

Michaël Roynard's avatar
Michaël Roynard committed
70
#ifndef MLN_DOXYGEN
71
    template <typename A, typename...>
Edwin Carlinet's avatar
Edwin Carlinet committed
72
73
    A& make_accumulator(Accumulator<A>& accu);

74
75
    template <typename A, typename T>
    const A& make_accumulator(const Accumulator<A>& accu, const T&);
Edwin Carlinet's avatar
Edwin Carlinet committed
76

77
    template <typename F, typename T>
Michaël Roynard's avatar
Michaël Roynard committed
78
    typename F::template apply<T>::type make_accumulator(const FeatureSet<F>& feat, const T& = T());
79
80
81

    struct default_extractor
    {
Michaël Roynard's avatar
Michaël Roynard committed
82
83
84
85
86
87
      template <typename A>
      typename A::result_type operator()(const Accumulator<A>& accu) const
      {
        return exact(accu).to_result();
      }
    };
88

Michaël Roynard's avatar
Michaël Roynard committed
89
#endif
90

91
92
    template <typename AccuLike, typename T, typename Enable = void>
    struct accu_of
93
    {
Michaël Roynard's avatar
Michaël Roynard committed
94
      static_assert(is_a<AccuLike, Accumulator>::value, "First template parameter is not an Accumulator");
95

96
97
      typedef AccuLike type;
    };
98

99
100
    template <typename AccuLike, typename T>
    struct accu_of<AccuLike, T, typename std::enable_if<is_a<AccuLike, FeatureSet>::value>::type>
101
    {
102
103
      typedef typename AccuLike::template apply<T>::type type;
    };
104

105
106
107
108
    template <typename AccuLike, typename T, typename Extractor = default_extractor>
    struct result_of
    {
    private:
Michaël Roynard's avatar
Michaël Roynard committed
109
110
      typedef typename accu_of<AccuLike, T>::type accu_type;

111
    public:
112
      typedef typename std::invoke_result<Extractor, accu_type>::type type;
113
    };
114
115
116
117

    template <class A, class T, class E = default_extractor>
    using result_of_t = typename result_of<A, T, E>::type;

Edwin Carlinet's avatar
Edwin Carlinet committed
118
119
120
121
122
123
    /// \}

    /*********************/
    /*** Implementation  */
    /*********************/

Michaël Roynard's avatar
Michaël Roynard committed
124
    template <typename A, typename...>
Edwin Carlinet's avatar
Edwin Carlinet committed
125
126
    A& make_accumulator(Accumulator<A>& accu)
    {
127
128
      return exact(accu);
    }
Edwin Carlinet's avatar
Edwin Carlinet committed
129

130
131
    template <typename A, typename T>
    const A& make_accumulator(const Accumulator<A>& accu, const T&)
Edwin Carlinet's avatar
Edwin Carlinet committed
132
133
134
135
    {
      return exact(accu);
    }

136
    template <typename F, typename T>
Michaël Roynard's avatar
Michaël Roynard committed
137
    typename F::template apply<T>::type make_accumulator(const FeatureSet<F>& fs, const T&)
Edwin Carlinet's avatar
Edwin Carlinet committed
138
    {
139
140
      return exact(fs).template make<T>();
    }
141
142
  } // namespace accu
} // namespace mln
Edwin Carlinet's avatar
Edwin Carlinet committed
143

144
/// \}