Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Lazy Variable Template
#pragma once
/*!
* @brief template class for inertial variable
* @note class T must implement operator=(T), operator+(T), and operator/(float).
*
* @usage
* Lazy<float> value(SIZE);
* value = 0;
* cout << value << endl; // 0
* for(int i = 1; i <= SIZE; ++i) {
* value = 10;
* cout << value << endl; // 10*i/SIZE
* }
*/
#include <vector>
template<typename T>
class Lazy
{
public:
Lazy<T>(int size=1):length_(size){}
Lazy<T>(int size, const T& initial):length_(size){add(initial);}
void setSize(unsigned int size) {
while(buf_.size() > size) {
buf_.erase(buf_.begin());
}
length_ = size;
}
operator T&() {
return cache_;
}
const T& operator =(const T& t) {
return add(t);
}
void clear() { buf_.clear(); }
void reset(const T& t) { clear(); add(t); }
private:
const T& get() const { return cache_; }
const T& add(const T& t) {
if(buf_.size() == length_) {
buf_.erase(buf_.begin());
buf_.push_back(t);
}
else {
while(buf_.size() < length_) {
buf_.push_back(t);
}
}
switch(length_) {
case 1:
cache_ = t;
break;
case 2:
cache_ = (buf_[0]+t)/2.f;
break;
default: {
vector<T>::iterator it = buf_.begin();
cache_ = *it++;
while(it != buf_.end()) {
cache_ = cache_ + *it++;
}
cache_ = cache_ / (float)length_;
} break;
}
return cache_;
}
private:
unsigned int length_;
std::vector<T> buf_;
T cache_;
};
/* EOF */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment