//#define BUG_CASE
#include <iostream>
#include <deque>
#include <algorithm>
#include <utility>
#include <memory>
using namespace std;
deque<bool> pool;
class ExpressionTemp;
class Scalar
{
bool *alive;
friend class ExpressionTemp;
Scalar(const Scalar&);
Scalar &operator=(const Scalar&);
Scalar &operator=(Scalar&&);
public:
Scalar()
{
pool.push_back(true);
alive=&pool.back();
}
Scalar(Scalar &&rhs)
: alive(0)
{
swap(alive,rhs.alive);
}
~Scalar()
{
if(alive)
(*alive)=false;
}
};
class ExpressionTemp
{
#ifndef BUG_CASE
unique_ptr<Scalar> resource; // can be in separate type
#endif
bool *operand_alive;
public:
ExpressionTemp(const Scalar &s)
: operand_alive(s.alive)
{
}
#ifndef BUG_CASE
ExpressionTemp(Scalar &&s)
: resource(new Scalar(move(s))), operand_alive(resource->alive)
{
}
#endif
void do_job()
{
if(*operand_alive)
cout << "captured operand is alive" << endl;
else
cout << "captured operand is DEAD!" << endl;
}
};
template<typename T>
ExpressionTemp expression(T &&s)
{
return {forward<T>(s)};
}
int main()
{
{
expression(Scalar()).do_job(); // OK, Scalar is moved to temporary
}
{
Scalar lv;
auto &&rvref=expression(lv);
rvref.do_job(); // OK, lv is still alive
}
{
auto &&rvref=expression(Scalar());
rvref.do_job(); // OK, Scalar is moved into rvref
}
return 0;
}
Ly8jZGVmaW5lIEJVR19DQVNFCgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxkZXF1ZT4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxtZW1vcnk+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpkZXF1ZTxib29sPiBwb29sOwoKY2xhc3MgRXhwcmVzc2lvblRlbXA7CmNsYXNzIFNjYWxhcgp7CiAgICBib29sICphbGl2ZTsKICAgICAgICAKICAgIGZyaWVuZCBjbGFzcyBFeHByZXNzaW9uVGVtcDsKCiAgICBTY2FsYXIoY29uc3QgU2NhbGFyJik7CiAgICBTY2FsYXIgJm9wZXJhdG9yPShjb25zdCBTY2FsYXImKTsKICAgIFNjYWxhciAmb3BlcmF0b3I9KFNjYWxhciYmKTsKcHVibGljOgogICAgU2NhbGFyKCkKICAgIHsKICAgICAgICBwb29sLnB1c2hfYmFjayh0cnVlKTsKICAgICAgICBhbGl2ZT0mcG9vbC5iYWNrKCk7CiAgICB9CiAgICBTY2FsYXIoU2NhbGFyICYmcmhzKQogICAgICAgIDogYWxpdmUoMCkKICAgIHsKICAgICAgICBzd2FwKGFsaXZlLHJocy5hbGl2ZSk7CiAgICB9CiAgICB+U2NhbGFyKCkKICAgIHsKICAgICAgICBpZihhbGl2ZSkKICAgICAgICAgICAgKCphbGl2ZSk9ZmFsc2U7CiAgICB9Cn07CmNsYXNzIEV4cHJlc3Npb25UZW1wCnsKI2lmbmRlZiBCVUdfQ0FTRQogICAgdW5pcXVlX3B0cjxTY2FsYXI+IHJlc291cmNlOyAvLyBjYW4gYmUgaW4gc2VwYXJhdGUgdHlwZQojZW5kaWYKICAgIGJvb2wgKm9wZXJhbmRfYWxpdmU7CnB1YmxpYzoKICAgIEV4cHJlc3Npb25UZW1wKGNvbnN0IFNjYWxhciAmcykKICAgICAgICA6IG9wZXJhbmRfYWxpdmUocy5hbGl2ZSkKICAgIHsKICAgIH0KI2lmbmRlZiBCVUdfQ0FTRQogICAgRXhwcmVzc2lvblRlbXAoU2NhbGFyICYmcykKICAgICAgICA6IHJlc291cmNlKG5ldyBTY2FsYXIobW92ZShzKSkpLCBvcGVyYW5kX2FsaXZlKHJlc291cmNlLT5hbGl2ZSkKICAgIHsKICAgIH0KI2VuZGlmCiAgICB2b2lkIGRvX2pvYigpCiAgICB7CiAgICAgIGlmKCpvcGVyYW5kX2FsaXZlKQogICAgICAgICAgY291dCA8PCAiY2FwdHVyZWQgb3BlcmFuZCBpcyBhbGl2ZSIgPDwgZW5kbDsKICAgICAgZWxzZQogICAgICAgICAgY291dCA8PCAiY2FwdHVyZWQgb3BlcmFuZCBpcyBERUFEISIgPDwgZW5kbDsKICAgIH0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CkV4cHJlc3Npb25UZW1wIGV4cHJlc3Npb24oVCAmJnMpCnsKICAgIHJldHVybiB7Zm9yd2FyZDxUPihzKX07Cn0KaW50IG1haW4oKQp7CiAgICB7CiAgICAgICAgZXhwcmVzc2lvbihTY2FsYXIoKSkuZG9fam9iKCk7IC8vIE9LLCBTY2FsYXIgaXMgbW92ZWQgdG8gdGVtcG9yYXJ5CiAgICB9CiAgICB7CiAgICAgICAgU2NhbGFyIGx2OwogICAgICAgIGF1dG8gJiZydnJlZj1leHByZXNzaW9uKGx2KTsKICAgICAgICBydnJlZi5kb19qb2IoKTsgLy8gT0ssIGx2IGlzIHN0aWxsIGFsaXZlCiAgICB9CiAgICB7CiAgICAgICAgYXV0byAmJnJ2cmVmPWV4cHJlc3Npb24oU2NhbGFyKCkpOwogICAgICAgIHJ2cmVmLmRvX2pvYigpOyAvLyBPSywgU2NhbGFyIGlzIG1vdmVkIGludG8gcnZyZWYKICAgIH0KICAgIHJldHVybiAwOwp9Cg==