#include <functional>
#include <iostream>
#include <string>
#include <type_traits>
template < typename T, typename F= typename std:: function < T( ) >>
class lazy {
//TYPES
using uninit_t= typename std:: aligned_storage <
sizeof ( T) ,
std:: alignment_of < T> :: value
> :: type ;
//MEMBERS
F f;
uninit_t value;
bool cached { false } ;
public :
lazy( F f_) : f { f_ } { }
T& get( ) {
if ( ! cached) {
new ( & value) T( f( ) ) ;
cached= true ;
}
return reinterpret_cast < T& > ( value) ;
}
~lazy( ) {
if ( cached)
get( ) .~T( ) ;
}
} ;
std:: string make_big_string( ) {
std:: cerr << "making string\n " ;
return "hello, world" ;
}
template < typename F>
lazy<
typename std:: remove_reference <
typename std:: result_of < F( ) > :: type
> :: type ,
F
> make_lazy( F f) { return { f } ; }
int main( ) {
auto l_str= make_lazy( make_big_string) ;
std:: cout << "get2\t " << l_str.get ( ) << '\n ' ;
std:: cout << "get2\t " << l_str.get ( ) << '\n ' ;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRj10eXBlbmFtZSBzdGQ6OmZ1bmN0aW9uPFQoKT4+CmNsYXNzIGxhenkgewovL1RZUEVTCiAgICB1c2luZyB1bmluaXRfdD10eXBlbmFtZSBzdGQ6OmFsaWduZWRfc3RvcmFnZTwKICAgICAgICAgICAgc2l6ZW9mKFQpLCAKICAgICAgICAgICAgc3RkOjphbGlnbm1lbnRfb2Y8VD46OnZhbHVlCiAgICAgICAgPjo6dHlwZTsKLy9NRU1CRVJTCiAgICBGIGY7CiAgICB1bmluaXRfdCB2YWx1ZTsKICAgIGJvb2wgY2FjaGVkIHsgZmFsc2UgfTsKcHVibGljOgogICAgbGF6eShGIGZfKSA6IGYgeyBmXyB9eyAgfQoKICAgIFQmIGdldCgpIHsKICAgICAgICBpZighY2FjaGVkKSB7IAogICAgICAgICAgICBuZXcoJnZhbHVlKSBUKGYoKSk7CiAgICAgICAgICAgIGNhY2hlZD10cnVlOwogICAgICAgIH0gICAKICAgICAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxUJj4odmFsdWUpOyAKICAgIH0gICAKICAgIH5sYXp5KCkgewogICAgICAgIGlmKGNhY2hlZCkKICAgICAgICAgICAgZ2V0KCkuflQoKTsKICAgIH0gICAKfTsKCgpzdGQ6OnN0cmluZyBtYWtlX2JpZ19zdHJpbmcoKSB7CiAgICBzdGQ6OmNlcnIgPDwgIm1ha2luZyBzdHJpbmdcbiI7CiAgICByZXR1cm4gImhlbGxvLCB3b3JsZCI7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIEY+Cmxhenk8CiAgICB0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8CiAgICAgICAgdHlwZW5hbWUgc3RkOjpyZXN1bHRfb2Y8RigpPjo6dHlwZQogICAgPjo6dHlwZSwKICAgIEYgICAKPiBtYWtlX2xhenkoRiBmKSB7IHJldHVybiB7IGYgfTsgfQoKaW50IG1haW4oKSB7CiAgICBhdXRvIGxfc3RyPW1ha2VfbGF6eShtYWtlX2JpZ19zdHJpbmcpOwoKCiAgICBzdGQ6OmNvdXQgPDwgImdldDJcdCIgPDwgbF9zdHIuZ2V0KCkgPDwgJ1xuJzsKICAgIHN0ZDo6Y291dCA8PCAiZ2V0Mlx0IiA8PCBsX3N0ci5nZXQoKSA8PCAnXG4nOwp9
compilation info
prog.cpp:9:11: error: expected nested-name-specifier before 'uninit_t'
prog.cpp:9:11: error: using-declaration for non-member at class scope
prog.cpp:9:19: error: expected ';' before '=' token
prog.cpp:9:19: error: expected unqualified-id before '=' token
prog.cpp:15:5: error: 'uninit_t' does not name a type
prog.cpp:16:10: error: function definition does not declare parameters
prog.cpp: In member function 'T& lazy<T, F>::get()':
prog.cpp:21:13: error: 'cached' was not declared in this scope
prog.cpp:22:18: error: 'value' was not declared in this scope
prog.cpp:25:37: error: 'value' was not declared in this scope
prog.cpp: In destructor 'lazy<T, F>::~lazy()':
prog.cpp:28:12: error: 'cached' was not declared in this scope
stdout