#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

template<class T>
struct PredRetainMax;

template<class Time, class Val>
struct PredRetainMax<std::pair<Time, Val>>
{
	PredRetainMax(Time cutoff, Val& m) :_cutoff(cutoff), _max(m) {}
	bool operator()(const std::pair<Time, Val>& s)
	{
        //if older than cutoff, remove
        if (s.first < _cutoff) return true;
        //otherwise, keep and update max
        _max = std::max(_max, s.second);
        return false;
	}
	Val get() { return _max; }
private:
	Time _cutoff;
	Val& _max;
};

std::ostream& operator<<(std::ostream& ostr, const std::list<std::pair<unsigned, double>>& list)
{
	for (auto &i : list) {
		ostr << "<" << i.first << "," << i.second << "> ";
	}
	return ostr;
}

int main()
{
	using sample = std::pair<unsigned, double>;
	using pred = PredRetainMax<sample>;

	sample a{ 1,12.2 };
	sample b{ 2,11.778 };
	sample c{ 3,9.2 };
	sample d{ 4,-2.6 };
	sample e{ 5,10.1 };

	std::list<sample> samples{ d,c,b,a };
	cout << "original list is: " << samples << endl << endl;

	double maxval(-std::numeric_limits<double>::infinity());
	//eliminate samples older than 2
	samples.remove_if(pred(2, maxval));
	cout << "max is: " << maxval << ", list is: " << samples << endl << endl;

	//add new value
	samples.push_front(e);
	//reset max
	maxval = -std::numeric_limits<double>::infinity();
	//eliminate samples older than 2
	samples.remove_if(pred(2, maxval));
	cout << "max is: " << maxval << ", list is: " << samples << endl << endl;

	//reset max
	maxval = -std::numeric_limits<double>::infinity();
	//eliminate samples older than 3
	samples.remove_if(pred(3, maxval));
	cout << "max is: " << maxval << ", list is: " << samples << endl << endl;

	return 0;
}