#include <iostream>
#include <cstdlib>
using namespace std;
typedef int HANDLE;
void DeleteHandle(HANDLE h)
{
cout << "deleting handle " << h << endl;
}
template <class H>
class UniqueHandle {
H h;
public:
UniqueHandle(H _h = 0)
:h(_h) {}
UniqueHandle(const UniqueHandle &other)
:h(const_cast<UniqueHandle&>(other).YieldOwnership()) {}
~UniqueHandle() { ::DeleteHandle(h); }
UniqueHandle &operator =(const UniqueHandle &other)
{
this->~UniqueHandle(); // release the old handle
h = const_cast<UniqueHandle&>(other).YieldOwnership();
return *this;
}
UniqueHandle &operator =(H _h)
{
this->~UniqueHandle(); // release the old handle
h = _h;
return *this;
}
H YieldOwnership() { H result = h; h = 0; return result; }
operator H() const { return h; }
};
int main()
{
UniqueHandle<HANDLE> h(123);
UniqueHandle<HANDLE> h2 = 456;
HANDLE unmanaged = 789;
HANDLE mixed_case = (rand() & 1)? (HANDLE)h : unmanaged;
DeleteHandle(unmanaged);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGxpYj4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiAgICB0eXBlZGVmIGludCBIQU5ETEU7CgogICAgdm9pZCBEZWxldGVIYW5kbGUoSEFORExFIGgpCiAgICB7CiAgICAgICAgY291dCA8PCAiZGVsZXRpbmcgaGFuZGxlICIgPDwgaCA8PCBlbmRsOwogICAgfQoKICAgIHRlbXBsYXRlIDxjbGFzcyBIPgogICAgY2xhc3MgVW5pcXVlSGFuZGxlIHsKICAgICAgICBIIGg7CgogICAgcHVibGljOgogICAgICAgIFVuaXF1ZUhhbmRsZShIIF9oID0gMCkKICAgICAgICAgICAgOmgoX2gpIHt9CgogICAgICAgIFVuaXF1ZUhhbmRsZShjb25zdCBVbmlxdWVIYW5kbGUgJm90aGVyKQogICAgICAgICAgICA6aChjb25zdF9jYXN0PFVuaXF1ZUhhbmRsZSY+KG90aGVyKS5ZaWVsZE93bmVyc2hpcCgpKSB7fQoKICAgICAgICB+VW5pcXVlSGFuZGxlKCkgeyA6OkRlbGV0ZUhhbmRsZShoKTsgfQoKICAgICAgICBVbmlxdWVIYW5kbGUgJm9wZXJhdG9yID0oY29uc3QgVW5pcXVlSGFuZGxlICZvdGhlcikKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMtPn5VbmlxdWVIYW5kbGUoKTsgLy8gcmVsZWFzZSB0aGUgb2xkIGhhbmRsZQogICAgICAgICAgICBoID0gY29uc3RfY2FzdDxVbmlxdWVIYW5kbGUmPihvdGhlcikuWWllbGRPd25lcnNoaXAoKTsKICAgICAgICAgICAgcmV0dXJuICp0aGlzOwogICAgICAgIH0KCiAgICAgICAgVW5pcXVlSGFuZGxlICZvcGVyYXRvciA9KEggX2gpCiAgICAgICAgewogICAgICAgICAgICB0aGlzLT5+VW5pcXVlSGFuZGxlKCk7IC8vIHJlbGVhc2UgdGhlIG9sZCBoYW5kbGUKICAgICAgICAgICAgaCA9IF9oOwogICAgICAgICAgICByZXR1cm4gKnRoaXM7CiAgICAgICAgfQoKICAgICAgICBIIFlpZWxkT3duZXJzaGlwKCkgeyBIIHJlc3VsdCA9IGg7IGggPSAwOyByZXR1cm4gcmVzdWx0OyB9CgogICAgICAgIG9wZXJhdG9yIEgoKSBjb25zdCB7IHJldHVybiBoOyB9CiAgICB9OwoKaW50IG1haW4oKQp7CglVbmlxdWVIYW5kbGU8SEFORExFPiBoKDEyMyk7CglVbmlxdWVIYW5kbGU8SEFORExFPiBoMiA9IDQ1NjsKCUhBTkRMRSB1bm1hbmFnZWQgPSA3ODk7CglIQU5ETEUgbWl4ZWRfY2FzZSA9IChyYW5kKCkgJiAxKT8gKEhBTkRMRSloIDogdW5tYW5hZ2VkOwoJRGVsZXRlSGFuZGxlKHVubWFuYWdlZCk7CglyZXR1cm4gMDsKfQ==