template< typename SAMPLE, int QUEUE_SIZE, int QUEUE_SIZE_ = QUEUE_SIZE + 1 >

class CQUE

{

private:

    SAMPLE*                     samples;

    size_t                      front;

    size_t                      back;


public:

                                CQUE()

        : front( 0 )

        , back( 0 )

    {

        samples = new SAMPLE[ QUEUE_SIZE_ ];

    }


                               ~CQUE()

    {

        delete[] samples;

    }


    size_t                    size()

    {

        return  ( back - front + QUEUE_SIZE_ ) % QUEUE_SIZE_;

    }


    void                      push_back( const SAMPLE sample )

    {

        samples[ back++ ]   = sample;

        back    %=  QUEUE_SIZE_;

    }


    SAMPLE                      pop_front()

    {

        SAMPLE  sample = samples[ front++ ];

        front   %=  QUEUE_SIZE_;

        return  sample;

    }

};

//------------------------------------------------------------------------------


#include <math.h>


template< typename SAMPLE, int QUEUE_SIZE = 1024 >

class STREAM_ANALYZER

{

private:

    CQUE< SAMPLE, QUEUE_SIZE >  samples;

    double                      sum_samples;

    double                      sum_squares;

    size_t                      size;


public:

                                STREAM_ANALYZER()

        : sum_samples( 0. )

        , sum_squares( 0. )

        , size( 0 )

    {}


                               ~STREAM_ANALYZER()

    {}


    STREAM_ANALYZER&            operator<<( const SAMPLE sample )

    {

        if( size == QUEUE_SIZE )

        {

            double  old_sample = samples.pop_front();

            sum_samples -= old_sample;

            sum_squares -= old_sample * old_sample;

        }

        else    size++;

        sum_samples += sample;

        sum_squares += sample * sample;

        samples.push_back( sample );

        return *this;

    }


    double                      average()

    {

        if( size == 0 ) return 0.;

        return  sum_samples / size;

    }


    double                      variance()

    {

        if( size <= 1 ) return 0.;

        return ( sum_squares - sum_samples * sum_samples / size ) / ( size - 1 );

    }


    double                      stdev()

    {

        if( size <= 1 ) return 0.;

        return  sqrt( variance() );

    }

};

//------------------------------------------------------------------------------


#include <stdlib.h>

#include <iostream>


STREAM_ANALYZER< float, 5 > oscilloscope; // 1024 개를 쓰고 싶으면 수정해라


int main()

{

    for( int i = 0; i < 10; ++i )

    {

        float   sample = (float)rand() / rand();

        oscilloscope << sample;

        std::cout

            << "input  : " << sample

            << " --> avg " << oscilloscope.average()

            << " , stdev " << oscilloscope.stdev()

            << std::endl;

    }

    return 0;

}