#include <iostream>
#include <vector>
template<typename T>
class Proxy
{
public:
enum class State
{
NEVER_SET = 0,
SET,
UNSET
};
operator const T& () const
{
if ( _state != State::SET )
{
std::cout << "EXCEPTION" << std::endl;
// TODO throw exception
}
return _data;
}
Proxy<T>& operator=(const T& val)
{
_data = val;
_state = State::SET;
return (*this);
}
Proxy<T>& operator+=(const T& val)
{
_data = (*this) + val;
_state = State::SET;
return (*this);
}
private:
T _data;
State _state = State::NEVER_SET;
};
class Tape
{
};
template<typename T>
class tape : public Tape
{
public:
const Proxy<T>& operator[](int idx) const
{
return operator[](idx);
}
Proxy<T>& operator[](int idx)
{
if ( idx >= data.size() )
{
data.resize(idx + 1);
}
return data[idx];
}
private:
std::vector< Proxy<T> > data;
};
class CRIXUS
{
public:
virtual void Go() final {};
protected:
virtual void Pre() {};
virtual void Post() {};
virtual void Step() = 0;
};
class CRIXUS_MA : public CRIXUS
{
public:
int window = 30;
tape<double> input;
tape<double> output;
protected:
virtual void Step()
{
double sum = 0;
for ( int j = 0; j < window; j++ )
{
sum += input[-j];
}
output[0] = sum / window;
}
};
int main()
{
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgUHJveHkKewpwdWJsaWM6CiAgICBlbnVtIGNsYXNzIFN0YXRlCiAgICB7CiAgICAgICAgTkVWRVJfU0VUID0gMCwKICAgICAgICBTRVQsCiAgICAgICAgVU5TRVQKICAgIH07CiAgICBvcGVyYXRvciBjb25zdCBUJiAoKSBjb25zdAogICAgewogICAgICAgIGlmICggX3N0YXRlICE9IFN0YXRlOjpTRVQgKQogICAgICAgIHsKICAgICAgICAgICAgc3RkOjpjb3V0IDw8ICJFWENFUFRJT04iIDw8IHN0ZDo6ZW5kbDsKICAgICAgICAgICAgLy8gVE9ETyB0aHJvdyBleGNlcHRpb24KICAgICAgICB9CiAgICAgICAgcmV0dXJuIF9kYXRhOwogICAgfQogICAgUHJveHk8VD4mIG9wZXJhdG9yPShjb25zdCBUJiB2YWwpCiAgICB7CiAgICAgICAgX2RhdGEgPSB2YWw7CiAgICAgICAgX3N0YXRlID0gU3RhdGU6OlNFVDsKICAgICAgICByZXR1cm4gKCp0aGlzKTsKICAgIH0KICAgIFByb3h5PFQ+JiBvcGVyYXRvcis9KGNvbnN0IFQmIHZhbCkKICAgIHsKICAgICAgICBfZGF0YSA9ICgqdGhpcykgKyB2YWw7CiAgICAgICAgX3N0YXRlID0gU3RhdGU6OlNFVDsKICAgICAgICByZXR1cm4gKCp0aGlzKTsKICAgIH0KcHJpdmF0ZToKICAgIFQgX2RhdGE7CiAgICBTdGF0ZSBfc3RhdGUgPSBTdGF0ZTo6TkVWRVJfU0VUOwp9OwoKY2xhc3MgVGFwZQp7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjbGFzcyB0YXBlIDogcHVibGljIFRhcGUKewpwdWJsaWM6CiAgICBjb25zdCBQcm94eTxUPiYgb3BlcmF0b3JbXShpbnQgaWR4KSBjb25zdAogICAgewogICAgICAgIHJldHVybiBvcGVyYXRvcltdKGlkeCk7CiAgICB9CiAgICBQcm94eTxUPiYgb3BlcmF0b3JbXShpbnQgaWR4KQogICAgewogICAgICAgIGlmICggaWR4ID49IGRhdGEuc2l6ZSgpICkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEucmVzaXplKGlkeCArIDEpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZGF0YVtpZHhdOwogICAgfQpwcml2YXRlOgogICAgc3RkOjp2ZWN0b3I8IFByb3h5PFQ+ID4gZGF0YTsKfTsKCmNsYXNzIENSSVhVUwp7CnB1YmxpYzoKICAgIHZpcnR1YWwgdm9pZCBHbygpIGZpbmFsIHt9Owpwcm90ZWN0ZWQ6CiAgICB2aXJ0dWFsIHZvaWQgUHJlKCkge307CiAgICB2aXJ0dWFsIHZvaWQgUG9zdCgpIHt9OwogICAgdmlydHVhbCB2b2lkIFN0ZXAoKSA9IDA7Cn07CgpjbGFzcyBDUklYVVNfTUEgOiBwdWJsaWMgQ1JJWFVTCnsKcHVibGljOgogICAgaW50IHdpbmRvdyA9IDMwOwogICAgdGFwZTxkb3VibGU+IGlucHV0OwogICAgdGFwZTxkb3VibGU+IG91dHB1dDsKcHJvdGVjdGVkOgogICAgdmlydHVhbCB2b2lkIFN0ZXAoKQogICAgewogICAgICAgIGRvdWJsZSBzdW0gPSAwOwogICAgICAgIGZvciAoIGludCBqID0gMDsgaiA8IHdpbmRvdzsgaisrICkKICAgICAgICB7CiAgICAgICAgICAgIHN1bSArPSBpbnB1dFstal07CiAgICAgICAgfQogICAgICAgIG91dHB1dFswXSA9IHN1bSAvIHdpbmRvdzsKICAgIH0KfTsKCmludCBtYWluKCkKewp9