module stats;

interface Stat
{
    void accumulate(double x);
    void postprocess();
    double result();
}

class IncrementalStat : Stat
{
    protected double _result;
    abstract void accumulate(double x);
    void postprocess() {}

    double result()
    {
        return _result;
    }
}

class Min : IncrementalStat
{
    this()
    {
        _result = double.max;
    }

    override void accumulate(double x)
    {
        if (x < _result)
        {
            _result = x;
        }
    }
}

class Max : IncrementalStat
{
    this()
    {
        _result = double.min_normal;
    }

    override void accumulate(double x)
    {
        if (x > _result)
        {
            _result = x;
        }
    }
}

class Average : IncrementalStat
{
    private uint items = 0;

    this()
    {
        _result = 0;
    }

    override void accumulate(double x)
    {
        _result += x;
        ++items;
    }

    override void postprocess()
    {
        if (items)
        {
            _result /= items;
        }
    }
}
