#include <iostream>
#include <vector>
/**
* Class, which accumulates values only if increment is above a certain
* threshold.
*/
template <class X>
class SelectiveAccumulator
{
public:
typedef X value_type;
/**
* Constructor -- sets the lower threshold and initializes accumulated value.
* @param t threshold
* @param init initial value (usually 0)
*/
SelectiveAccumulator(const X& t, const X& init) :
threshold(t),
accumulated_value(init)
{}
/**
* Increases accumulated value by 'increment' if it is larger than
* threshold. Otherwise does nothing.
* @param increment increase the accumulated value by.
*/
void Inc(const value_type& increment)
{
if (increment > threshold)
accumulated_value += increment;
}
///Returns accumulated value.
X Value() const { return accumulated_value; }
private:
const X threshold;
X accumulated_value; //accumulated value
};
template <class T>
class Storage
{
public:
/**
* Constructor, allocated memory for storage vector.
* @param n size of vector
* @param initial values to put into storage.
*/
Storage(const std::size_t n, const T& init_value) :
storage(n, init_value)
{}
/**
* Increases value of element with the given index for classes, supporting
* += operator. For simplicity do not check for range.
* @param index index of the element in storage to increase.
* @param v value to increase the element by.
*/
void IncreaseValue(std::size_t index, const T& v)
{
storage[index] += v;
}
const T& Get(std::size_t index)
{
return storage[index];
}
/**
* Miraculously overloaded / specialized method, so I can increase value of
* element with the given index for SelectiveAccumulator type.
* @param index index of the element in storage to increase.
* @param v value to increase the element by.
*/
template <class SelectiveAccumulator >
void IncreaseValue(std::size_t index,
const typename SelectiveAccumulator::value_type & v)
{
storage[index].Inc(v);
}
private:
std::vector<T> storage;
};
template <class S, class T>
void Increase3rdElement(S& storage, const T& increment)
{
storage.IncreaseValue(3, increment);
}
int main()
{
Storage<double> s1(10, 0.0);
Increase3rdElement(s1, 0.9);
std::cout << "s1[3] = " << s1.Get(3) << std::endl;
Storage<SelectiveAccumulator<double> > s2(10, {1.0, 0.0});
//How to make this to work?
//Increase3rdElement(s2, 0.9);
//std::cout << "s2[3] = " << s2.Get(3).Value << std::endl;
//std::cout
return 0;
}