#include <iostream>
#include <string>
#include <vector>
using namespace std;
namespace {
// address to number
unsigned a2n(void *addr)
{
static std::vector<void*> addr_list;
unsigned i = 0;
for(; i < addr_list.size(); ++i) {
if(addr_list[i] == addr) {
return i;
}
}
addr_list.push_back(addr);
return i;
}
// number to string
std::string n2s(unsigned n)
{
switch(n) {
case 0:
return "x";
case 1:
return "tmp";
case 2:
return "y";
default:
return "none";
}
}
struct Hoge
{
Hoge()
{
cout << "Hoge : default constructor. (" << n2s(a2n(this)) << ")" << endl;
}
~Hoge()
{
cout << "Hoge : destructor. (" << n2s(a2n(this)) << ")" << endl;
}
Hoge(const Hoge& o)
{
cout << "Hoge : copy constructor. (" << n2s(a2n((void*)&o)) << ") -> (" << n2s(a2n(this)) << ")" << endl;
}
Hoge(Hoge&& o)
{
cout << "Hoge : move constructor. (" << n2s(a2n((void*)&o)) << ") -> (" << n2s(a2n(this)) << ")" << endl;
}
Hoge&& foo()
{
Hoge tmp(*this);
return std::move(tmp);
}
};
} // namespace
int main()
{
Hoge x;
Hoge y = x.foo();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCm5hbWVzcGFjZSB7CgovLyBhZGRyZXNzIHRvIG51bWJlcgp1bnNpZ25lZCBhMm4odm9pZCAqYWRkcikKewogIHN0YXRpYyBzdGQ6OnZlY3Rvcjx2b2lkKj4gYWRkcl9saXN0OwoKICB1bnNpZ25lZCBpID0gMDsKICBmb3IoOyBpIDwgYWRkcl9saXN0LnNpemUoKTsgKytpKSB7CiAgICBpZihhZGRyX2xpc3RbaV0gPT0gYWRkcikgewogICAgICByZXR1cm4gaTsKICAgIH0KICB9CiAgYWRkcl9saXN0LnB1c2hfYmFjayhhZGRyKTsKICByZXR1cm4gaTsKfQoKLy8gbnVtYmVyIHRvIHN0cmluZwpzdGQ6OnN0cmluZyBuMnModW5zaWduZWQgbikKewogIHN3aXRjaChuKSB7CiAgY2FzZSAwOgogICAgcmV0dXJuICJ4IjsKICBjYXNlIDE6CiAgICByZXR1cm4gInRtcCI7CiAgY2FzZSAyOgogICAgcmV0dXJuICJ5IjsKICBkZWZhdWx0OgogICAgcmV0dXJuICJub25lIjsKICB9Cn0KCnN0cnVjdCBIb2dlCnsKICBIb2dlKCkKICB7CiAgICBjb3V0IDw8ICJIb2dlIDogZGVmYXVsdCBjb25zdHJ1Y3Rvci4gKCIgPDwgbjJzKGEybih0aGlzKSkgPDwgIikiIDw8IGVuZGw7CiAgfQoKICB+SG9nZSgpCiAgewogICAgY291dCA8PCAiSG9nZSA6IGRlc3RydWN0b3IuICgiIDw8IG4ycyhhMm4odGhpcykpIDw8ICIpIiA8PCBlbmRsOwogIH0KCiAgSG9nZShjb25zdCBIb2dlJiBvKQogIHsKICAgIGNvdXQgPDwgIkhvZ2UgOiBjb3B5IGNvbnN0cnVjdG9yLiAoIiA8PCBuMnMoYTJuKCh2b2lkKikmbykpIDw8ICIpIC0+ICgiIDw8IG4ycyhhMm4odGhpcykpIDw8ICIpIiA8PCBlbmRsOwogIH0KCiAgSG9nZShIb2dlJiYgbykKICB7CiAgICBjb3V0IDw8ICJIb2dlIDogbW92ZSBjb25zdHJ1Y3Rvci4gKCIgPDwgbjJzKGEybigodm9pZCopJm8pKSA8PCAiKSAtPiAoIiA8PCBuMnMoYTJuKHRoaXMpKSA8PCAiKSIgPDwgZW5kbDsKICB9CgogIEhvZ2UmJiBmb28oKQogIHsKICAgIEhvZ2UgdG1wKCp0aGlzKTsKICAgIHJldHVybiBzdGQ6Om1vdmUodG1wKTsKICB9Cn07Cgp9IC8vIG5hbWVzcGFjZQoKaW50IG1haW4oKQp7CiAgSG9nZSB4OwogIEhvZ2UgeSA9IHguZm9vKCk7Cn0K