fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <map>
  4.  
  5. using namespace std;
  6.  
  7. #define Msg1(msg) {cout << (msg) << endl;}
  8. #define Msg2(msg1,msg2) {cout << (msg1) << (msg2) << endl;}
  9. #define Msg2s(msg1,msg2,sp) {cout << (msg1) << (sp) << (msg2) << endl;}
  10. #define Msg3(msg1,msg2,msg3) {cout << (msg1) << (msg2) << (msg3) << endl;}
  11. #define Msg3s(msg1,msg2,msg3,sp) {cout << (msg1) << (sp) << (msg2) << (sp) << (msg3) << endl;}
  12.  
  13. #define DebugMode
  14.  
  15. #ifdef DebugMode
  16. # define DebugMsg1(msg) Msg1(msg)
  17. # define DebugMsg2(msg1, msg2) Msg2(msg1, msg2)
  18. # define DebugMsg2s(msg1, msg2, sp) Msg2s(msg1, msg2, sp)
  19. # define DebugMsg3(msg1, msg2, msg3) Msg3(msg1, msg2, msg3)
  20. # define DebugMsg3s(msg1, msg2, msg3, sp) Msg3s(msg1, msg2, msg3, sp)
  21. #else
  22. # define DebugMsg1(msg)
  23. # define DebugMsg2(msg1, msg2)
  24. # define DebugMsg2s(msg1, msg2, sp)
  25. # define DebugMsg3(msg1, msg2, msg3)
  26. # define DebugMsg3s(msg1, msg2, msg3, sp)
  27. #endif
  28.  
  29.  
  30. class NullPtr_t
  31. {
  32. public:
  33. NullPtr_t() : zero(NULL) {}
  34. template< class T >
  35. operator T* () const { return NULL; }
  36. template< class T, class C >
  37. operator T C::* () const { return NULL; }
  38. private:
  39. void operator &() const;
  40. void *zero;
  41. };
  42.  
  43. inline NullPtr_t getNullPtr() { return NullPtr_t(); }
  44. #define nullptr getNullPtr()
  45.  
  46. template< class T >
  47. class BasePtr
  48. {
  49. typedef BasePtr< T > ThisPtr;
  50.  
  51. virtual T* get() = 0;
  52. virtual T& ref() = 0;
  53.  
  54. friend bool operator == (ThisPtr& a, ThisPtr& b) {
  55. return a.get() == b.get();
  56. }
  57.  
  58. friend bool operator != (ThisPtr& a, ThisPtr& b) {
  59. return a.get() != b.get();
  60. }
  61. };
  62.  
  63. template< class T, class A = allocator< T > >
  64. class BarPtr : public BasePtr< T >
  65. {
  66. typedef int ID;
  67. typedef T BAR, *LPBAR;
  68. typedef A ALLO;
  69. typedef BarPtr< BAR, ALLO > ThisPtr, *LPThisPtr;
  70. typedef map< LPBAR, ID > REFMAP;
  71. typedef map< ID, LPBAR > PTRMAP;
  72.  
  73. private:
  74.  
  75. ID id;
  76.  
  77. static REFMAP& refmap() {
  78. static REFMAP refm;
  79. return refm;
  80. }
  81.  
  82. static PTRMAP& ptrmap() {
  83. static PTRMAP ptrm;
  84. return ptrm;
  85. }
  86.  
  87. static void entry(ID id, const LPBAR bar) {
  88. REFMAP& r = refmap();
  89. PTRMAP& p = ptrmap();
  90. if (bar != nullptr) {
  91. ID other = r[bar];
  92. if (other) {
  93. if (p[other] != bar) {
  94. p[id] = nullptr;
  95. return;
  96. }
  97. p[other] = nullptr;
  98. }
  99. r[bar] = id;
  100. }
  101. p[id] = bar;
  102. }
  103.  
  104. static void entry(ID id, const ThisPtr& other) {
  105. PTRMAP& p = ptrmap();
  106. entry(id, p[other.id]);
  107. }
  108.  
  109. static LPBAR getptr(ID id) {
  110. PTRMAP& p = ptrmap();
  111. return p[id];
  112. }
  113.  
  114. static void leave(ID id) {
  115. REFMAP& r = refmap();
  116. PTRMAP& p = ptrmap();
  117. LPBAR ptr = p[id];
  118.  
  119. if (ptr != nullptr && r[ptr] == id) {
  120. ALLO allo;
  121. allo.destroy(ptr);
  122. allo.deallocate(ptr, 1);
  123. r.erase(ptr);
  124. }
  125.  
  126. p[id] = nullptr;
  127. }
  128.  
  129. static ID newID() {
  130. static ID count = 0;
  131. return ++count;
  132. }
  133.  
  134. public:
  135.  
  136. BarPtr() : id(newID()) {
  137. entry(id, nullptr);
  138. }
  139.  
  140. BarPtr(const LPBAR bar) : id(newID()) {
  141. DebugMsg2( "BarPTr(LPBAR): ", id );
  142. entry(id, bar);
  143. }
  144.  
  145. BarPtr(const ThisPtr& other) : id(newID()) {
  146. DebugMsg2( "BarPTr(ThisPtr): ", id );
  147. entry(id, other);
  148. }
  149.  
  150. ~BarPtr() {
  151. leave(id);
  152. }
  153.  
  154. BAR& operator * () {
  155. return *(getptr(id));
  156. }
  157.  
  158. LPBAR operator -> () {
  159. return getptr(id);
  160. }
  161.  
  162. operator LPBAR () {
  163. return getptr(id);
  164. }
  165.  
  166. LPBAR get() {
  167. return getptr(id);
  168. }
  169.  
  170. BAR& ref() {
  171. return *(getptr(id));
  172. }
  173.  
  174. ThisPtr& operator = (const ThisPtr& other) {
  175. DebugMsg2( "ope = ThisPtr : ", id );
  176. leave(id);
  177. entry(id, other);
  178. return *this;
  179. }
  180.  
  181. ThisPtr& operator = (const LPBAR bar) {
  182. DebugMsg2( "ope = LPBAR : ", id );
  183. leave(id);
  184. entry(id, bar);
  185. return *this;
  186. }
  187.  
  188. };
  189.  
  190.  
  191.  
  192.  
  193. class Hoge
  194. {
  195. public:
  196. Hoge() : id(counter()) {
  197. Msg2( "Hoge() : ", id );
  198. }
  199. Hoge(const Hoge&) : id(counter()) {
  200. Msg2( "Hoge(Hoge&) : ", id );
  201. }
  202.  
  203. ~Hoge() {
  204. Msg2( "~Hoge() : ", id );
  205. }
  206.  
  207. operator int () {
  208. return id;
  209. }
  210.  
  211. void print() {
  212. Msg2( "Hoge method : ", id );
  213. }
  214.  
  215. private:
  216. const int id;
  217. static int counter() {
  218. static int c = 0;
  219. return ++c;
  220. }
  221. };
  222.  
  223.  
  224. BarPtr<Hoge> getHoge() {
  225. BarPtr<Hoge> temp(new Hoge);
  226. return temp;
  227. }
  228.  
  229. int main() {
  230. Msg1( "** begin of program **" );
  231.  
  232. BarPtr<Hoge> hoge1(new Hoge);
  233. BarPtr<int> int1(new int(5));
  234.  
  235. {
  236. Msg1( "-- test 1 --" );
  237.  
  238. BarPtr<Hoge> hoge2(hoge1);
  239.  
  240. }
  241.  
  242. {
  243. Msg1( "-- test 2 --" );
  244.  
  245. hoge1 = new Hoge;
  246.  
  247. hoge1 = new Hoge;
  248. }
  249.  
  250. {
  251. Msg1( "-- test 3 --" );
  252.  
  253. hoge1 = getHoge();
  254. }
  255.  
  256. {
  257. Msg1( "-- test 4 --" );
  258.  
  259. BarPtr<Hoge> hoge2;
  260.  
  261. hoge2 = hoge1;
  262.  
  263. Hoge *h1 = hoge1;
  264.  
  265. Msg2( "h1: ", h1 );
  266. }
  267.  
  268.  
  269.  
  270. Msg1( "** end of program **" );
  271. return 0;
  272. }
Success #stdin #stdout 0s 3448KB
stdin
Standard input is empty
stdout
** begin of program **
Hoge() : 1
BarPTr(LPBAR): 1
BarPTr(LPBAR): 1
-- test 1 --
BarPTr(ThisPtr): 2
~Hoge() : 1
-- test 2 --
Hoge() : 2
ope = LPBAR : 1
Hoge() : 3
ope = LPBAR : 1
~Hoge() : 2
-- test 3 --
Hoge() : 4
BarPTr(LPBAR): 3
ope = ThisPtr : 1
~Hoge() : 3
-- test 4 --
ope = ThisPtr : 4
h1: 0
~Hoge() : 4
** end of program **