#include <iostream>
#include <memory>
using namespace std;
struct inner {
inner ( ) { cout << "constructing inner object at " << this << '\n ' ; }
~inner ( ) { cout << "destructing inner object at " << this << '\n ' ; }
inner operator + ( const inner & ) { return * this ; }
} ;
template < class T>
class storage {
public :
size_t _size;
unique_ptr< T[ ] > _Array;
storage ( size_t size = 2 ) : _size( size) , _Array( new T[ size] ) {
cout << "constructing storage object at " << this << '\n ' ;
}
~storage ( ) { cout << "destructing storage object at " << this << '\n ' ; }
storage ( const storage & other) : _size( other._size) , _Array( new T[ other._size] ) {
for ( size_t i = 0 ; i < _size; ++ i)
_Array[ i] = other._Array[ i] ;
cout << "constructing storage object via copy (l-ref) constructor at " << this << '\n ' ;
}
storage ( storage && other) {
swap( * this , other) ;
cout << "constructing storage object via move (r-ref) constructor at " << this << '\n ' ;
other._Array = nullptr, other._size = 0 ;
}
storage & operator= ( storage other) {
swap( * this , other) ;
}
friend void swap ( storage & first, storage & second) {
std:: swap ( first._Array, second._Array) ;
std:: swap ( first._size, second._size) ;
}
storage operator + ( const storage & other) {
storage tmp( _size + other._size) ;
return tmp;
// return storage(_size + other._size);
}
} ;
int main ( ) {
storage< inner> T;
storage< inner> T2 ( T + T) ;
cout << "end of init.\n " ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBpbm5lciB7CiAgICBpbm5lciAoKSB7IGNvdXQgPDwgImNvbnN0cnVjdGluZyBpbm5lciBvYmplY3QgYXQgIiA8PCB0aGlzIDw8ICdcbic7IH0KCiAgICB+aW5uZXIgKCkgeyBjb3V0IDw8ICJkZXN0cnVjdGluZyBpbm5lciBvYmplY3QgYXQgIiA8PCB0aGlzIDw8ICdcbic7IH0KCiAgICBpbm5lciBvcGVyYXRvciArIChjb25zdCBpbm5lciAmKSB7IHJldHVybiAqdGhpczsgfQp9OwoKdGVtcGxhdGUgPGNsYXNzIFQ+CmNsYXNzIHN0b3JhZ2UgewpwdWJsaWM6CiAgICBzaXplX3QgX3NpemU7CiAgICB1bmlxdWVfcHRyPFRbXT4gX0FycmF5OwogICAgc3RvcmFnZSAoc2l6ZV90IHNpemUgPSAyKSA6IF9zaXplKHNpemUpLCBfQXJyYXkobmV3IFRbc2l6ZV0pIHsKICAgICAgICBjb3V0IDw8ICJjb25zdHJ1Y3Rpbmcgc3RvcmFnZSBvYmplY3QgYXQgIiA8PCB0aGlzIDw8ICdcbic7CiAgICB9CgogICAgfnN0b3JhZ2UgKCkgeyBjb3V0IDw8ICJkZXN0cnVjdGluZyBzdG9yYWdlIG9iamVjdCBhdCAiIDw8IHRoaXMgPDwgJ1xuJzsgfQoKICAgIHN0b3JhZ2UgKGNvbnN0IHN0b3JhZ2UgJm90aGVyKSA6IF9zaXplKG90aGVyLl9zaXplKSwgX0FycmF5KG5ldyBUW290aGVyLl9zaXplXSkgewogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgX3NpemU7ICsraSkKICAgICAgICAgICAgX0FycmF5W2ldID0gb3RoZXIuX0FycmF5W2ldOwoKICAgICAgICBjb3V0IDw8ICJjb25zdHJ1Y3Rpbmcgc3RvcmFnZSBvYmplY3QgdmlhIGNvcHkgKGwtcmVmKSBjb25zdHJ1Y3RvciBhdCAiIDw8IHRoaXMgPDwgJ1xuJzsKICAgIH0KCiAgICBzdG9yYWdlIChzdG9yYWdlICYmb3RoZXIpIHsKICAgICAgICBzd2FwKCp0aGlzLCBvdGhlcik7CiAgICAgICAgY291dCA8PCAiY29uc3RydWN0aW5nIHN0b3JhZ2Ugb2JqZWN0IHZpYSBtb3ZlIChyLXJlZikgY29uc3RydWN0b3IgYXQgIiA8PCB0aGlzIDw8ICdcbic7CiAgICAgICAgb3RoZXIuX0FycmF5ID0gbnVsbHB0ciwgb3RoZXIuX3NpemUgPSAwOwogICAgfQoKICAgIHN0b3JhZ2UgJm9wZXJhdG9yPSAoc3RvcmFnZSBvdGhlcikgewogICAgICAgIHN3YXAoKnRoaXMsIG90aGVyKTsKICAgIH0KCiAgICBmcmllbmQgdm9pZCBzd2FwIChzdG9yYWdlICZmaXJzdCwgc3RvcmFnZSAmc2Vjb25kKSB7CiAgICAgICAgc3RkOjpzd2FwKGZpcnN0Ll9BcnJheSwgc2Vjb25kLl9BcnJheSk7CiAgICAgICAgc3RkOjpzd2FwKGZpcnN0Ll9zaXplLCBzZWNvbmQuX3NpemUpOwogICAgfQoKICAgIHN0b3JhZ2Ugb3BlcmF0b3IgKyAoY29uc3Qgc3RvcmFnZSAmb3RoZXIpIHsKICAgICAgICBzdG9yYWdlIHRtcChfc2l6ZSArIG90aGVyLl9zaXplKTsKICAgICAgICByZXR1cm4gdG1wOwovLyAgICAgICAgcmV0dXJuIHN0b3JhZ2UoX3NpemUgKyBvdGhlci5fc2l6ZSk7CiAgICB9Cn07CgppbnQgbWFpbiAoKSB7CiAgICBzdG9yYWdlPGlubmVyPiBUOwogICAgc3RvcmFnZTxpbm5lcj4gVDIgKFQgKyBUKTsKICAgIGNvdXQgPDwgImVuZCBvZiBpbml0LlxuIjsKICAgIHJldHVybiAwOwp9