#include <iostream>
#include <memory>
#include <map>
using namespace std;
#define Msg1(msg) {cout << (msg) << endl;}
#define Msg2(msg1,msg2) {cout << (msg1) << (msg2) << endl;}
#define Msg2s(msg1,msg2,sp) {cout << (msg1) << (sp) << (msg2) << endl;}
#define Msg3(msg1,msg2,msg3) {cout << (msg1) << (msg2) << (msg3) << endl;}
#define Msg3s(msg1,msg2,msg3,sp) {cout << (msg1) << (sp) << (msg2) << (sp) << (msg3) << endl;}
#define DebugMode
#ifdef DebugMode
# define DebugMsg1(msg) Msg1(msg)
# define DebugMsg2(msg1, msg2) Msg2(msg1, msg2)
# define DebugMsg2s(msg1, msg2, sp) Msg2s(msg1, msg2, sp)
# define DebugMsg3(msg1, msg2, msg3) Msg3(msg1, msg2, msg3)
# define DebugMsg3s(msg1, msg2, msg3, sp) Msg3s(msg1, msg2, msg3, sp)
#else
# define DebugMsg1(msg)
# define DebugMsg2(msg1, msg2)
# define DebugMsg2s(msg1, msg2, sp)
# define DebugMsg3(msg1, msg2, msg3)
# define DebugMsg3s(msg1, msg2, msg3, sp)
#endif
class NullPtr_t
{
public:
NullPtr_t() : zero(NULL) {}
template< class T >
operator T* () const { return NULL; }
template< class T, class C >
operator T C::* () const { return NULL; }
private:
void operator &() const;
void *zero;
};
inline NullPtr_t getNullPtr() { return NullPtr_t(); }
#define nullptr getNullPtr()
template< class T >
class BasePtr
{
typedef BasePtr< T > ThisPtr;
virtual T* get() = 0;
virtual T& ref() = 0;
friend bool operator == (ThisPtr& a, ThisPtr& b) {
return a.get() == b.get();
}
friend bool operator != (ThisPtr& a, ThisPtr& b) {
return a.get() != b.get();
}
};
template< class T, class A = allocator< T > >
class BarPtr : public BasePtr< T >
{
typedef int ID;
typedef T BAR, *LPBAR;
typedef A ALLO;
typedef BarPtr< BAR, ALLO > ThisPtr, *LPThisPtr;
typedef map< LPBAR, ID > REFMAP;
typedef map< ID, LPBAR > PTRMAP;
private:
ID id;
static REFMAP& refmap() {
static REFMAP refm;
return refm;
}
static PTRMAP& ptrmap() {
static PTRMAP ptrm;
return ptrm;
}
static void entry(ID id, const LPBAR bar) {
REFMAP& r = refmap();
PTRMAP& p = ptrmap();
if (bar != nullptr) {
ID other = r[bar];
if (other) {
if (p[other] != bar) {
p[id] = nullptr;
return;
}
p[other] = nullptr;
}
r[bar] = id;
}
p[id] = bar;
}
static void entry(ID id, const ThisPtr& other) {
PTRMAP& p = ptrmap();
entry(id, p[other.id]);
}
static LPBAR getptr(ID id) {
PTRMAP& p = ptrmap();
return p[id];
}
static void leave(ID id) {
REFMAP& r = refmap();
PTRMAP& p = ptrmap();
LPBAR ptr = p[id];
if (ptr != nullptr && r[ptr] == id) {
ALLO allo;
allo.destroy(ptr);
allo.deallocate(ptr, 1);
r.erase(ptr);
}
p[id] = nullptr;
}
static ID newID() {
static ID count = 0;
return ++count;
}
public:
BarPtr() : id(newID()) {
entry(id, nullptr);
}
BarPtr(const LPBAR bar) : id(newID()) {
DebugMsg2( "BarPTr(LPBAR): ", id );
entry(id, bar);
}
BarPtr(const ThisPtr& other) : id(newID()) {
DebugMsg2( "BarPTr(ThisPtr): ", id );
entry(id, other);
}
~BarPtr() {
leave(id);
}
BAR& operator * () {
return *(getptr(id));
}
LPBAR operator -> () {
return getptr(id);
}
operator LPBAR () {
return getptr(id);
}
LPBAR get() {
return getptr(id);
}
BAR& ref() {
return *(getptr(id));
}
ThisPtr& operator = (const ThisPtr& other) {
DebugMsg2( "ope = ThisPtr : ", id );
leave(id);
entry(id, other);
return *this;
}
ThisPtr& operator = (const LPBAR bar) {
DebugMsg2( "ope = LPBAR : ", id );
leave(id);
entry(id, bar);
return *this;
}
};
class Hoge
{
public:
Hoge() : id(counter()) {
Msg2( "Hoge() : ", id );
}
Hoge(const Hoge&) : id(counter()) {
Msg2( "Hoge(Hoge&) : ", id );
}
~Hoge() {
Msg2( "~Hoge() : ", id );
}
operator int () {
return id;
}
void print() {
Msg2( "Hoge method : ", id );
}
private:
const int id;
static int counter() {
static int c = 0;
return ++c;
}
};
BarPtr<Hoge> getHoge() {
BarPtr<Hoge> temp(new Hoge);
return temp;
}
int main() {
Msg1( "** begin of program **" );
BarPtr<Hoge> hoge1(new Hoge);
BarPtr<int> int1(new int(5));
{
Msg1( "-- test 1 --" );
BarPtr<Hoge> hoge2(hoge1);
}
{
Msg1( "-- test 2 --" );
hoge1 = new Hoge;
hoge1 = new Hoge;
}
{
Msg1( "-- test 3 --" );
hoge1 = getHoge();
}
{
Msg1( "-- test 4 --" );
BarPtr<Hoge> hoge2;
hoge2 = hoge1;
Hoge *h1 = hoge1;
Msg2( "h1: ", h1 );
}
Msg1( "** end of program **" );
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8bWFwPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiNkZWZpbmUgTXNnMShtc2cpIHtjb3V0IDw8IChtc2cpIDw8IGVuZGw7fQojZGVmaW5lIE1zZzIobXNnMSxtc2cyKSB7Y291dCA8PCAobXNnMSkgPDwgKG1zZzIpIDw8IGVuZGw7fQojZGVmaW5lIE1zZzJzKG1zZzEsbXNnMixzcCkge2NvdXQgPDwgKG1zZzEpIDw8IChzcCkgPDwgKG1zZzIpIDw8IGVuZGw7fQojZGVmaW5lIE1zZzMobXNnMSxtc2cyLG1zZzMpIHtjb3V0IDw8IChtc2cxKSA8PCAobXNnMikgPDwgKG1zZzMpIDw8IGVuZGw7fQojZGVmaW5lIE1zZzNzKG1zZzEsbXNnMixtc2czLHNwKSB7Y291dCA8PCAobXNnMSkgPDwgKHNwKSA8PCAobXNnMikgPDwgKHNwKSA8PCAobXNnMykgPDwgZW5kbDt9CgojZGVmaW5lIERlYnVnTW9kZQoKI2lmZGVmIERlYnVnTW9kZQojIGRlZmluZSBEZWJ1Z01zZzEobXNnKSBNc2cxKG1zZykKIyBkZWZpbmUgRGVidWdNc2cyKG1zZzEsIG1zZzIpIE1zZzIobXNnMSwgbXNnMikKIyBkZWZpbmUgRGVidWdNc2cycyhtc2cxLCBtc2cyLCBzcCkgTXNnMnMobXNnMSwgbXNnMiwgc3ApCiMgZGVmaW5lIERlYnVnTXNnMyhtc2cxLCBtc2cyLCBtc2czKSBNc2czKG1zZzEsIG1zZzIsIG1zZzMpCiMgZGVmaW5lIERlYnVnTXNnM3MobXNnMSwgbXNnMiwgbXNnMywgc3ApIE1zZzNzKG1zZzEsIG1zZzIsIG1zZzMsIHNwKQojZWxzZQojIGRlZmluZSBEZWJ1Z01zZzEobXNnKQojIGRlZmluZSBEZWJ1Z01zZzIobXNnMSwgbXNnMikKIyBkZWZpbmUgRGVidWdNc2cycyhtc2cxLCBtc2cyLCBzcCkKIyBkZWZpbmUgRGVidWdNc2czKG1zZzEsIG1zZzIsIG1zZzMpCiMgZGVmaW5lIERlYnVnTXNnM3MobXNnMSwgbXNnMiwgbXNnMywgc3ApCiNlbmRpZgoKCmNsYXNzIE51bGxQdHJfdAp7CnB1YmxpYzoKCU51bGxQdHJfdCgpIDogemVybyhOVUxMKSB7fQoJdGVtcGxhdGU8IGNsYXNzIFQgPgoJb3BlcmF0b3IgVCogKCkgY29uc3QgeyByZXR1cm4gTlVMTDsgfQoJdGVtcGxhdGU8IGNsYXNzIFQsIGNsYXNzIEMgPgoJb3BlcmF0b3IgVCBDOjoqICgpIGNvbnN0IHsgcmV0dXJuIE5VTEw7IH0KcHJpdmF0ZToKCXZvaWQgb3BlcmF0b3IgJigpIGNvbnN0OwoJdm9pZCAqemVybzsKfTsKCmlubGluZSBOdWxsUHRyX3QgZ2V0TnVsbFB0cigpIHsgcmV0dXJuIE51bGxQdHJfdCgpOyB9CiNkZWZpbmUgbnVsbHB0ciBnZXROdWxsUHRyKCkKCnRlbXBsYXRlPCBjbGFzcyBUID4KY2xhc3MgQmFzZVB0cgp7Cgl0eXBlZGVmIEJhc2VQdHI8IFQgPiBUaGlzUHRyOwoJCgl2aXJ0dWFsIFQqIGdldCgpID0gMDsKCXZpcnR1YWwgVCYgcmVmKCkgPSAwOwoJCglmcmllbmQgYm9vbCBvcGVyYXRvciA9PSAoVGhpc1B0ciYgYSwgVGhpc1B0ciYgYikgewoJCXJldHVybiBhLmdldCgpID09IGIuZ2V0KCk7Cgl9CgkKCWZyaWVuZCBib29sIG9wZXJhdG9yICE9IChUaGlzUHRyJiBhLCBUaGlzUHRyJiBiKSB7CgkJcmV0dXJuIGEuZ2V0KCkgIT0gYi5nZXQoKTsKCX0KfTsKCnRlbXBsYXRlPCBjbGFzcyBULCBjbGFzcyBBID0gYWxsb2NhdG9yPCBUID4gPgpjbGFzcyBCYXJQdHIgOiBwdWJsaWMgQmFzZVB0cjwgVCA+CnsKCXR5cGVkZWYgaW50IElEOwoJdHlwZWRlZiBUIEJBUiwgKkxQQkFSOwoJdHlwZWRlZiBBIEFMTE87Cgl0eXBlZGVmIEJhclB0cjwgQkFSLCBBTExPID4gVGhpc1B0ciwgKkxQVGhpc1B0cjsKCXR5cGVkZWYgbWFwPCBMUEJBUiwgSUQgPiBSRUZNQVA7Cgl0eXBlZGVmIG1hcDwgSUQsIExQQkFSID4gUFRSTUFQOwoJCnByaXZhdGU6CgoJSUQgaWQ7CgkKCXN0YXRpYyBSRUZNQVAmIHJlZm1hcCgpIHsKCQlzdGF0aWMgUkVGTUFQIHJlZm07CgkJcmV0dXJuIHJlZm07Cgl9CgkKCXN0YXRpYyBQVFJNQVAmIHB0cm1hcCgpIHsKCQlzdGF0aWMgUFRSTUFQIHB0cm07CgkJcmV0dXJuIHB0cm07Cgl9CgkKCXN0YXRpYyB2b2lkIGVudHJ5KElEIGlkLCBjb25zdCBMUEJBUiBiYXIpIHsKCQlSRUZNQVAmIHIgPSByZWZtYXAoKTsKCQlQVFJNQVAmIHAgPSBwdHJtYXAoKTsKCQlpZiAoYmFyICE9IG51bGxwdHIpIHsKCQkJSUQgb3RoZXIgPSByW2Jhcl07CgkJCWlmIChvdGhlcikgewoJCQkJaWYgKHBbb3RoZXJdICE9IGJhcikgewoJCQkJCXBbaWRdID0gbnVsbHB0cjsKCQkJCQlyZXR1cm47CgkJCQl9CgkJCQlwW290aGVyXSA9IG51bGxwdHI7CgkJCX0KCQkJcltiYXJdID0gaWQ7CgkJfQoJCXBbaWRdID0gYmFyOwoJfQoJCglzdGF0aWMgdm9pZCBlbnRyeShJRCBpZCwgY29uc3QgVGhpc1B0ciYgb3RoZXIpIHsKCQlQVFJNQVAmIHAgPSBwdHJtYXAoKTsKCQllbnRyeShpZCwgcFtvdGhlci5pZF0pOwoJfQoJCglzdGF0aWMgTFBCQVIgZ2V0cHRyKElEIGlkKSB7CgkJUFRSTUFQJiBwID0gcHRybWFwKCk7CgkJcmV0dXJuIHBbaWRdOwoJfQoJCglzdGF0aWMgdm9pZCBsZWF2ZShJRCBpZCkgewoJCVJFRk1BUCYgciA9IHJlZm1hcCgpOwoJCVBUUk1BUCYgcCA9IHB0cm1hcCgpOwoJCUxQQkFSIHB0ciA9IHBbaWRdOwoJCQoJCWlmIChwdHIgIT0gbnVsbHB0ciAmJiByW3B0cl0gPT0gaWQpIHsKCQkJQUxMTyBhbGxvOwoJCQlhbGxvLmRlc3Ryb3kocHRyKTsKCQkJYWxsby5kZWFsbG9jYXRlKHB0ciwgMSk7CgkJCXIuZXJhc2UocHRyKTsKCQl9CgoJCXBbaWRdID0gbnVsbHB0cjsKCX0KCQoJc3RhdGljIElEIG5ld0lEKCkgewoJCXN0YXRpYyBJRCBjb3VudCA9IDA7CgkJcmV0dXJuICsrY291bnQ7Cgl9CgpwdWJsaWM6CgoJQmFyUHRyKCkgOiBpZChuZXdJRCgpKSB7CgkJZW50cnkoaWQsIG51bGxwdHIpOwoJfQoJCglCYXJQdHIoY29uc3QgTFBCQVIgYmFyKSA6IGlkKG5ld0lEKCkpIHsKCQlEZWJ1Z01zZzIoICJCYXJQVHIoTFBCQVIpOiAiLCBpZCApOwoJCWVudHJ5KGlkLCBiYXIpOwoJfQoJCglCYXJQdHIoY29uc3QgVGhpc1B0ciYgb3RoZXIpIDogaWQobmV3SUQoKSkgewoJCURlYnVnTXNnMiggIkJhclBUcihUaGlzUHRyKTogIiwgaWQgKTsKCQllbnRyeShpZCwgb3RoZXIpOwoJfQoJCgl+QmFyUHRyKCkgewoJCWxlYXZlKGlkKTsKCX0KCQoJQkFSJiBvcGVyYXRvciAqICgpIHsKCQlyZXR1cm4gKihnZXRwdHIoaWQpKTsKCX0KCQoJTFBCQVIgb3BlcmF0b3IgLT4gKCkgewoJCXJldHVybiBnZXRwdHIoaWQpOwoJfQoJCglvcGVyYXRvciBMUEJBUiAoKSB7CgkJcmV0dXJuIGdldHB0cihpZCk7Cgl9CgkKCUxQQkFSIGdldCgpIHsKCQlyZXR1cm4gZ2V0cHRyKGlkKTsKCX0KCQoJQkFSJiByZWYoKSB7CgkJcmV0dXJuICooZ2V0cHRyKGlkKSk7Cgl9CgkKCVRoaXNQdHImIG9wZXJhdG9yID0gKGNvbnN0IFRoaXNQdHImIG90aGVyKSB7CgkJRGVidWdNc2cyKCAib3BlID0gVGhpc1B0ciA6ICIsIGlkICk7CgkJbGVhdmUoaWQpOwoJCWVudHJ5KGlkLCBvdGhlcik7CgkJcmV0dXJuICp0aGlzOwoJfQoJCglUaGlzUHRyJiBvcGVyYXRvciA9IChjb25zdCBMUEJBUiBiYXIpIHsKCQlEZWJ1Z01zZzIoICJvcGUgPSBMUEJBUiA6ICIsIGlkICk7CgkJbGVhdmUoaWQpOwoJCWVudHJ5KGlkLCBiYXIpOwoJCXJldHVybiAqdGhpczsKCX0KCn07CgoKCgpjbGFzcyBIb2dlCnsKcHVibGljOgoJSG9nZSgpIDogaWQoY291bnRlcigpKSB7CgkJTXNnMiggIkhvZ2UoKSA6ICIsIGlkICk7Cgl9CglIb2dlKGNvbnN0IEhvZ2UmKSA6IGlkKGNvdW50ZXIoKSkgewoJCU1zZzIoICJIb2dlKEhvZ2UmKSA6ICIsIGlkICk7Cgl9CgkKCX5Ib2dlKCkgewoJCU1zZzIoICJ+SG9nZSgpIDogIiwgaWQgKTsKCX0KCQoJb3BlcmF0b3IgaW50ICgpIHsKCQlyZXR1cm4gaWQ7Cgl9CgkKCXZvaWQgcHJpbnQoKSB7CgkJTXNnMiggIkhvZ2UgbWV0aG9kIDogIiwgaWQgKTsKCX0KCQpwcml2YXRlOgoJY29uc3QgaW50IGlkOwoJc3RhdGljIGludCBjb3VudGVyKCkgewoJCXN0YXRpYyBpbnQgYyA9IDA7CgkJcmV0dXJuICsrYzsKCX0KfTsKCgpCYXJQdHI8SG9nZT4gZ2V0SG9nZSgpIHsKCUJhclB0cjxIb2dlPiB0ZW1wKG5ldyBIb2dlKTsKCXJldHVybiB0ZW1wOwp9CgppbnQgbWFpbigpIHsKCU1zZzEoICIqKiBiZWdpbiBvZiBwcm9ncmFtICoqIiApOwoJCglCYXJQdHI8SG9nZT4gaG9nZTEobmV3IEhvZ2UpOwoJQmFyUHRyPGludD4gaW50MShuZXcgaW50KDUpKTsKCQoJewoJCU1zZzEoICItLSB0ZXN0IDEgLS0iICk7CgkJCgkJQmFyUHRyPEhvZ2U+IGhvZ2UyKGhvZ2UxKTsKCQkKCX0KCQoJewoJCU1zZzEoICItLSB0ZXN0IDIgLS0iICk7CgkJCgkJaG9nZTEgPSBuZXcgSG9nZTsKCQkKCQlob2dlMSA9IG5ldyBIb2dlOwoJfQoJCgl7CgkJTXNnMSggIi0tIHRlc3QgMyAtLSIgKTsKCQkKCQlob2dlMSA9IGdldEhvZ2UoKTsKCX0KCQoJewoJCU1zZzEoICItLSB0ZXN0IDQgLS0iICk7CgkJCgkJQmFyUHRyPEhvZ2U+IGhvZ2UyOwoJCQoJCWhvZ2UyID0gaG9nZTE7CgkJCgkJSG9nZSAqaDEgPSBob2dlMTsKCQkKCQlNc2cyKCAiaDE6ICIsIGgxICk7Cgl9CgkKCQoJCglNc2cxKCAiKiogZW5kIG9mIHByb2dyYW0gKioiICk7CglyZXR1cm4gMDsKfQ==