Commit d75e6fa4 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Fix accumulator issue with dynamic parameter in meta accumulators.

Fix affects also the Kernel Library that uses aggregators.
parent b35b7008
......@@ -5,26 +5,71 @@
# include <mln/accu/feature.hpp>
# include <mln/accu/composite_accumulator.hpp>
/// \defgroup accu Accumulator framework
/// \{
/// \file
/// \brief Header file for the accumulator framework
namespace mln
{
namespace accu
{
/// \brief The namespace for accumulator features.
namespace features
{
}
/// \brief The namespace for accumulator object themselves.
namespace accumulators
{
}
/// \brief The namespace for feature extractor.
namespace extractor
{
}
/// \defgroup freefun Free functions
/// \{
# ifdef MLN_DOXYGEN
/// \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>
unspecified make_accumulator(const AccumulatorLike<A>& accu, T arg);
/// \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
{
typedef unspecified type;
};
/// \brief The defaut extractor
/// It calls the `to_result` method of the accumulator.
struct default_extractor;
# endif
# ifndef MLN_DOXYGEN
template <typename A, typename ...>
A& make_accumulator(Accumulator<A>& accu);
......@@ -34,11 +79,9 @@ namespace mln
template <typename F, typename T>
typename F::template apply<T>::type
make_accumulator(const FeatureSet<F>& feat, T = T());
/// \}
struct default_extractor
{
template <typename A>
typename A::result_type
operator() (const Accumulator<A>& accu) const
......@@ -47,6 +90,8 @@ namespace mln
}
};
# endif
template <typename AccuLike, typename T, typename Extractor = default_extractor,
typename Enabler = void>
......@@ -99,13 +144,15 @@ namespace mln
template <typename F, typename T>
typename F::template apply<T>::type
make_accumulator(const FeatureSet<F>&, T)
make_accumulator(const FeatureSet<F>& fs, T)
{
return typename F::template apply<T>::type ();
return exact(fs).template make<T>();
}
}
}
}
/// \}
#endif // ! ACCUMULATOR_HPP
#ifndef MLN_ACCU_ACCUMULATOTS_COUNT_HPP
# define MLN_ACCU_ACCUMULATOTS_COUNT_HPP
/// \file
/// \brief Header file for counting accumulator.
# include <mln/accu/accumulator_base.hpp>
# include <mln/accu/dontcare.hpp>
# include <utility>
......@@ -12,6 +15,9 @@ namespace mln
{
namespace accumulators
{
/// \brief The counting accumulator.
/// \tparam CountType is underlying the counter type (it must be incrementable,
/// and decrementable.
template <typename CountType = std::size_t>
struct count;
}
......@@ -39,7 +45,6 @@ namespace mln
namespace features
{
template <typename CountType>
struct count : simple_feature< count<CountType> >
{
......@@ -48,8 +53,14 @@ namespace mln
{
typedef accumulators::count<CountType> type;
};
};
template <typename T>
accumulators::count<CountType>
make()
{
return accumulators::count<CountType> ();
}
};
}
namespace accumulators
......@@ -59,7 +70,7 @@ namespace mln
struct count : accumulator_base< count<CountType>, dontcare, CountType, features::count<> >
{
typedef dontcare argument_type;
typedef CountType return_type;
typedef CountType result_type;
typedef boost::mpl::set< features::count<> > provides;
count()
......@@ -89,7 +100,7 @@ namespace mln
}
friend
return_type extract(const count& accu, features::count<> )
result_type extract(const count& accu, features::count<> )
{
return accu.m_count;
}
......
......@@ -11,11 +11,18 @@ namespace mln
namespace accu
{
namespace accumulators
{
template <typename T, typename Compare = productorder_less<T> >
struct infsup;
template <typename T, typename Compare = std::less<T> >
struct sup;
template <typename T, typename Compare = std::less<T> >
struct inf;
}
namespace features
......@@ -55,43 +62,93 @@ namespace mln
template <typename Compare>
struct inf : simple_feature< inf<Compare> >
{
inf(const Compare& cmp)
: m_cmp(cmp)
{
}
template <typename T>
struct apply
{
typedef accumulators::infsup<T, Compare> type;
typedef accumulators::sup<T, Compare> type;
};
template <typename T>
accumulators::sup<T, Compare>
make() const
{
return accumulators::sup<T, Compare>(m_cmp);
}
private:
Compare m_cmp;
};
template <>
struct inf<void> : simple_feature< inf<void> >
{
inf() = default;
template <typename T>
struct apply
{
typedef accumulators::infsup<T, std::less<T> > type;
typedef accumulators::sup<T> type;
};
template <typename T>
accumulators::sup<T>
make() const
{
return accumulators::sup<T>();
}
};
template <typename Compare>
struct sup : simple_feature< sup<Compare> >
{
sup(const Compare& cmp)
: m_cmp(cmp)
{
}
template <typename T>
struct apply
{
typedef accumulators::infsup<T, Compare> type;
typedef accumulators::sup<T, Compare> type;
};
template <typename T>
accumulators::sup<T, Compare>
make() const
{
return accumulators::sup<T, Compare>(m_cmp);
}
private:
Compare m_cmp;
};
template <>
struct sup<void> : simple_feature< sup<void> >
{
sup() = default;
template <typename T>
struct apply
{
typedef accumulators::infsup<T, std::less<T> > type;
typedef accumulators::sup<T> type;
};
template <typename T>
accumulators::sup<T>
make() const
{
return accumulators::sup<T>();
}
};
}
namespace accumulators
......@@ -121,6 +178,8 @@ namespace mln
void take(const T& v)
{
using mln::inf;
using mln::sup;
m_inf = inf(m_inf, v, m_cmp);
m_sup = sup(m_sup, v, m_cmp);
}
......@@ -128,6 +187,8 @@ namespace mln
template <typename Other>
void take(const Accumulator<Other>& other)
{
using mln::inf;
using mln::sup;
T vinf = extractor::inf(other);
T vsup = extractor::sup(other);
m_inf = inf(m_inf, vinf, m_cmp);
......@@ -158,6 +219,102 @@ namespace mln
Compare m_cmp;
};
template <typename T, typename Compare>
struct inf : Accumulator< inf<T, Compare> >
{
typedef T argument_type;
typedef T result_type;
inf(const Compare& cmp = Compare())
: m_cmp( cmp ),
m_inf( value_traits<T, Compare>::sup() )
{
}
void init()
{
m_inf = value_traits<T, Compare>::sup();
}
void take(const T& v)
{
using mln::inf;
m_inf = inf(m_inf, v, m_cmp);
}
template <typename Other>
void take(const Accumulator<Other>& other)
{
using mln::inf;
T vinf = extractor::inf(other);
m_inf = inf(m_inf, vinf, m_cmp);
}
T to_result() const
{
return m_inf;
}
friend
T extract(const inf& accu, features::inf<> )
{
return accu.m_inf;
}
private:
Compare m_cmp;
T m_inf;
};
template <typename T, typename Compare>
struct sup : Accumulator< sup<T, Compare> >
{
typedef T argument_type;
typedef T result_type;
sup(const Compare& cmp = Compare())
: m_cmp( cmp ),
m_sup( value_traits<T, Compare>::inf() )
{
}
void init()
{
m_sup = value_traits<T, Compare>::inf();
}
void take(const T& v)
{
using mln::sup;
m_sup = sup(m_sup, v, m_cmp);
}
template <typename Other>
void take(const Accumulator<Other>& other)
{
using mln::sup;
T vsup = extractor::sup(other);
m_sup = sup(m_sup, vsup, m_cmp);
}
T to_result() const
{
return m_sup;
}
friend
T extract(const sup& accu, features::sup<> )
{
return accu.m_sup;
}
private:
Compare m_cmp;
T m_sup;
};
}
}
......
......@@ -2,6 +2,7 @@
# define MLN_ACCU_ACCUMULATORS_MAX_HPP
/// \file
/// \brief Header file for the maximum accumulator
# include <mln/accu/accumulator.hpp>
# include <mln/accu/accumulator_base.hpp>
......@@ -16,12 +17,18 @@ namespace mln
namespace accumulators
{
/// \brief Maximum accumlator.
/// \tparam T The argument and result type.
/// \tparam Compare The comparison function.
template <typename T, typename Compare = std::less<T> >
struct max;
}
namespace features
{
/// \brief Maximum accumlator.
/// \tparam T The argument and result type.
/// \tparam Compare The comparison function (`void` results in std::less by default).
template <typename Compare = void>
struct max;
}
......@@ -42,25 +49,41 @@ namespace mln
namespace features
{
template <typename Compare>
struct max : simple_feature< max<Compare> >
{
max(const Compare& cmp = Compare())
: m_cmp(cmp)
{
}
template <typename T>
struct apply
{
typedef accumulators::max<T, Compare> type;
};
template <typename T>
accumulators::max<T, Compare>
make() const
{
return accumulators::max<T, Compare> (m_cmp);
}
private: // dynamic parameter.
Compare m_cmp;
};
template <>
struct max<void> : simple_feature< max<void> >
namespace internal
{
template <typename T>
struct apply
using meta_max = accumulators::max<T>;
}
template <>
struct max<void>
: simple_feature_facade< max<void>, internal::meta_max>
{
typedef accumulators::max<T, std::less<T> > type;
};
};
}
......@@ -72,7 +95,7 @@ namespace mln
{
typedef T argument_type;
typedef T return_type;
typedef features::max<> feature;
//typedef features::max<> feature;
max(const Compare& cmp = Compare())
: m_val( value_traits<T, Compare>::min() ),
......
......@@ -48,6 +48,13 @@ namespace mln
{
typedef accumulators::mean<T, SumType> type;
};
template <typename T>
accumulators::mean<T, SumType>
make() const
{
return accumulators::mean<T, SumType>();
}
};
template <>
......@@ -58,6 +65,13 @@ namespace mln
{
typedef accumulators::mean<T> type;
};
template <typename T>
accumulators::mean<T>
make() const
{
return accumulators::mean<T>();
}
};
template <typename SumType>
......@@ -75,20 +89,14 @@ namespace mln
struct mean : composite_accumulator_facade< mean<T, SumType>, T, SumType, features::mean<SumType> >
{
typedef T argument_type;
typedef SumType return_type;
typedef SumType result_type;
typedef boost::mpl::set< features::mean<>, features::mean<SumType> > provides;
//typedef boost::mpl::set< features::mean<>, features::mean<SumType> > provides;
friend
SumType extract(const mean& accu, features::mean<SumType> )
{
//std::string x = extract(exact(accu), features::count<> ());
//std::string y = extractor::count(accu);
auto v = extractor::count(accu);
if (v == 0)
return extractor::sum(accu);
else
return extractor::sum(accu) / extractor::count(accu);
return extract(accu, features::mean<>() );
}
friend
......@@ -100,10 +108,6 @@ namespace mln
else
return extractor::sum(accu) / extractor::count(accu);
}
//private:
//SumType m_sum;
};
}
......
......@@ -46,21 +46,38 @@ namespace mln
template <typename Compare>
struct min : simple_feature< min<Compare> >
{
min(const Compare& cmp)
: m_cmp(cmp)
{
}
template <typename T>
struct apply
{
typedef accumulators::min<T, Compare> type;
};
template <typename T>
accumulators::min<T, Compare>
make() const
{
return accumulators::min<T, Compare>(m_cmp);
}
private:
Compare m_cmp;
};
template <>
struct min<void> : simple_feature< min<void> >
namespace internal
{
template <typename T>
struct apply
using meta_min = accumulators::min<T>;
}
template <>
struct min<void>
: simple_feature_facade< min<void>, internal::meta_min>
{
typedef accumulators::min<T, std::less<T> > type;
};
};
}
......@@ -72,7 +89,7 @@ namespace mln
{
typedef T argument_type;
typedef T return_type;
typedef features::min<> feature;
//typedef features::min<> feature;
min(const Compare& cmp = Compare())
: m_val( value_traits<T, Compare>::max() ),
......
......@@ -12,15 +12,21 @@ namespace mln
namespace accu
{
namespace accumulators
{
/// \brief Summation accumulator.
/// \tparam T The type of the arguments to sum up.
/// \tparam SumType The accumulation type (by default, the type of `T + T` w.r.t C++ type promotions)
template <typename T, typename SumType = decltype( std::declval<T>() + std::declval<T>() )>
struct sum;
}
namespace features
{
/// \brief Summation accumulator.
/// \tparam SumType The accumulation type (`void` will use the default type).
template <typename SumType = void>