#include <functional>
#include <iostream>
#include <string>
template<typename T>
class lazy {
//TYPES
typedef typename std::aligned_storage<
sizeof(T),
std::alignment_of<T>::value
>::type uninit_t;
//MEMBERS
std::function<T()> f;
uninit_t value;
bool cached;
public:
lazy(std::function<T()> f_)
: f { std::move(f_) }
, cached { false }
{ }
T& get() {
if(!cached) {
new(&value) T(f());
cached=true;
}
return reinterpret_cast<T&>(value);
}
~lazy() {
get().~T();
}
};
std::string make_big_string() {
std::cerr << "making string\n";
return "hello, world";
}
int main() {
lazy<std::string> l_str(make_big_string);
std::cerr << "get1\n";
std::cout << l_str.get() << '\n';
std::cerr << "get1\n";
std::cout << l_str.get() << '\n';
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIGxhenkgewovL1RZUEVTCiAgICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6YWxpZ25lZF9zdG9yYWdlPAogICAgICAgICAgICBzaXplb2YoVCksIAogICAgICAgICAgICBzdGQ6OmFsaWdubWVudF9vZjxUPjo6dmFsdWUKICAgICAgICA+Ojp0eXBlIHVuaW5pdF90OwovL01FTUJFUlMKICAgIHN0ZDo6ZnVuY3Rpb248VCgpPiBmOwogICAgdW5pbml0X3QgdmFsdWU7CiAgICBib29sIGNhY2hlZDsKcHVibGljOgogICAgbGF6eShzdGQ6OmZ1bmN0aW9uPFQoKT4gZl8pIAogICAgOiAgICAgZiAgICAgIHsgc3RkOjptb3ZlKGZfKSB9CiAgICAsICAgICBjYWNoZWQgeyBmYWxzZSAgICAgICAgIH0KICAgIHsgICAgIH0KCiAgICBUJiBnZXQoKSB7CiAgICAgICAgaWYoIWNhY2hlZCkgeyAKICAgICAgICAgICAgbmV3KCZ2YWx1ZSkgVChmKCkpOwogICAgICAgICAgICBjYWNoZWQ9dHJ1ZTsKICAgICAgICB9ICAgCiAgICAgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VCY+KHZhbHVlKTsgCiAgICB9ICAgCiAgICB+bGF6eSgpIHsKICAgICAgICBnZXQoKS5+VCgpOwogICAgfSAgIAp9OwoKCgpzdGQ6OnN0cmluZyBtYWtlX2JpZ19zdHJpbmcoKSB7CiAgICBzdGQ6OmNlcnIgPDwgIm1ha2luZyBzdHJpbmdcbiI7CiAgICByZXR1cm4gImhlbGxvLCB3b3JsZCI7Cn0KCgppbnQgbWFpbigpIHsKICAgIGxhenk8c3RkOjpzdHJpbmc+IGxfc3RyKG1ha2VfYmlnX3N0cmluZyk7IAogICAgc3RkOjpjZXJyIDw8ICJnZXQxXG4iOwogICAgc3RkOjpjb3V0IDw8IGxfc3RyLmdldCgpIDw8ICdcbic7CiAgICBzdGQ6OmNlcnIgPDwgImdldDFcbiI7CiAgICBzdGQ6OmNvdXQgPDwgbF9zdHIuZ2V0KCkgPDwgJ1xuJzsKfQ==