Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: sludwig on Feb 18th, 2012  |  syntax: D  |  size: 8.41 KB  |  views: 84  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. import std.stdio;
  2.  
  3. //version=ASSIGNMENT_OPERATOR1;
  4. version=ASSIGNMENT_OPERATOR2;
  5.  
  6. extern(C) void memcpy(void* dst, const void* src, size_t cnt);
  7.  
  8. // keep track of all living objects
  9. bool[int*] s_living;
  10.  
  11. // canonical reference count dummy implementation
  12. struct Count {
  13.         int* count;
  14.         int magic = 0x2f7d9a65;
  15.        
  16.         this(bool){
  17.                 count = new int;
  18.                 *count = 1;
  19.                 assert(count !in s_living);
  20.                 s_living[count] = true;
  21.         }
  22.         this(this){
  23.                 assert(magic == 0x2f7d9a65);
  24.                 if( count ){
  25.                         assert(*count > 0);
  26.                         (*count)++;
  27.                 }
  28.         }
  29.         ~this(){
  30.                 assert(magic == 0x2f7d9a65);
  31.                 if( count ){
  32.                         assert(*count > 0);
  33.                         if( --(*count) == 0){
  34.                                 assert(count in s_living);
  35.                                 s_living.remove(count);
  36.                                 count = null;
  37.                         }
  38.                 }
  39.                 // reset just to catch uninitialized-errors better
  40.                 count = null;
  41.                 magic = 0;
  42.         }
  43.  
  44.         version(ASSIGNMENT_OPERATOR1)
  45.         {
  46.                 void opAssign(Count c)
  47.                 {
  48.                         assert(&this != &c); // note: c is passed by value
  49.                         assert(magic == 0x2f7d9a65);
  50.                         assert(c.magic == 0x2f7d9a65);
  51.                         typeid(Count).destroy(&this);
  52.                         memcpy(&this, &c, Count.sizeof);
  53.                         typeid(Count).postblit(&this);
  54.                 }
  55.         }
  56.         version(ASSIGNMENT_OPERATOR2)
  57.         {
  58.                 void opAssign(Count c)
  59.                 {
  60.                         auto tmp = count;
  61.                         count = c.count;
  62.                         c.count = tmp;
  63.                 }              
  64.         }
  65. }
  66.  
  67. void test_con_ass()
  68. {
  69.         Count c;
  70.         { c = Count(true); }
  71.         assert(c.count && *c.count == 1);
  72.         { c = Count(); }
  73.         assert(c.count == null);
  74. }
  75.  
  76. void test_con_sae_ass()
  77. {
  78.         Count c[1];
  79.         { c[0] = Count(true); }
  80.         assert(*c[0].count == 1);
  81.         { c[0] = Count(); }
  82.         assert(c[0].count == null);
  83. }
  84.  
  85. void test_con_ae_ass1()
  86. {
  87.         Count c[] = new Count[1];
  88.         { c[0] = Count(true); }
  89.         assert(c[0].count && *c[0].count == 1);
  90.         { c[0] = Count(); }
  91.         assert(c[0].count == null);
  92. }
  93.  
  94. void test_con_ae_ass2()
  95. {
  96.         Count c[];
  97.         { c ~= Count(true); }
  98.         assert(c[0].count && *c[0].count == 1);
  99.         { c[0] = Count(); }
  100.         assert(c[0].count == null);
  101.         { c ~= Count(true); }
  102.         assert(c[0].count && *c[0].count == 1);
  103.         Count tmp = c[0];
  104.         assert(c[0].count && *c[0].count == 2);
  105.         //{ c.length = 0; }
  106.         { c[0] = Count(); c.length = 0; }
  107.         assert(c[0].count && *c[0].count == 1);
  108.         tmp = Count();
  109.         assert(c[0].count == null);
  110. }
  111.  
  112. void test_con_aa_ass1() // DMD 6178?
  113. {
  114.         Count[int] c;
  115.         { auto cs = Count(true); c[0] = cs; }
  116.         assert(c[0].count && *c[0].count == 1);
  117.         { Count cs; c[0] = cs; }
  118.         assert(c[0].count == null);
  119. }
  120.  
  121. void test_con_aa_ass2() // DMD 6178?
  122. {
  123.         Count[int] c;
  124.         { c[0] = Count(true); }
  125.         assert(c[0].count && *c[0].count == 1);
  126.         { c[0] = Count(); }
  127.         assert(c[0].count == null);
  128. }
  129.  
  130. void test_con_sm_ass()
  131. {
  132.         struct S { Count c; }
  133.         S s;
  134.         { s.c = Count(true); }
  135.         assert(s.c.count && *s.c.count == 1);
  136.         { s.c = Count(); }
  137.         assert(s.c.count == null);
  138. }
  139.  
  140. void test_con_cm_ass()
  141. {
  142.         class S { Count c; }
  143.         S s = new S;
  144.         { s.c = Count(true); }
  145.         assert(s.c.count && *s.c.count == 1);
  146.         { s.c = Count(); }
  147.         assert(s.c.count == null);
  148. }
  149.  
  150. void test_con_delp()
  151. {
  152.         Count c;
  153.         void f(Count c_){ c = c_; }
  154.         { f(Count(true)); }
  155.         assert(c.count && *c.count == 1);
  156.         { f(Count()); }
  157.         assert(c.count == null);
  158. }
  159.  
  160. void test_con_refp()
  161. {
  162.         Count c;
  163.         static void f(ref Count cd, Count cs){ cd = cs; }
  164.         { f(c, Count(true)); }
  165.         assert(c.count && *c.count == 1);
  166.         { f(c, Count()); }
  167.         assert(c.count == null);
  168. }
  169.  
  170. void test_con_refp2()
  171. {
  172.         Count c;
  173.         static void f(ref Count cd, ref Count cs){ cd = cs; }
  174.         { auto cs = Count(true); f(c, cs); }
  175.         assert(c.count && *c.count == 1);
  176.         { Count cs; f(c, cs); }
  177.         assert(c.count == null);
  178. }
  179.  
  180. void test_con_ptrp()
  181. {
  182.         Count c;
  183.         static void f(Count* cd, Count cs){ *cd = cs; }
  184.         { f(&c, Count(true)); }
  185.         assert(c.count && *c.count == 1);
  186.         { f(&c, Count()); }
  187.         assert(c.count == null);
  188. }
  189.  
  190. void test_con_ptrp2()
  191. {
  192.         Count c;
  193.         static void f(Count* cd, Count* cs){ *cd = *cs; }
  194.         { auto cs = Count(true); f(&c, &cs); }
  195.         assert(c.count && *c.count == 1);
  196.         { Count cs; f(&c, &cs); }
  197.         assert(c.count == null);
  198. }
  199.  
  200. void test_con_outp()
  201. {
  202.         Count c;
  203.         static void f(out Count cd, Count cs){ cd = cs; }
  204.         { f(c, Count(true)); }
  205.         assert(c.count && *c.count == 1);
  206.         { f(c, Count()); }
  207.         assert(c.count == null);
  208. }
  209.  
  210. void test_con_ret()
  211. {
  212.         Count c;
  213.         static Count a(){ return Count(true); }
  214.         static Count b(){ return Count(); }
  215.         { c = a(); }
  216.         assert(c.count && *c.count == 1);
  217.         { c = b(); }
  218.         assert(c.count == null);
  219. }
  220.  
  221. void test_var_ret()
  222. {
  223.         Count c;
  224.         static Count a(bool x = true){
  225.                 static Count cs;
  226.                 if( x && cs.count == null ) cs = Count(true);
  227.                 else if( !x && cs.count != null ) cs = Count();
  228.                 return cs;
  229.         }
  230.         static Count b(){ return a(); }
  231.         { c = a(); }
  232.         assert(c.count && *c.count == 2);
  233.         { c = Count(); }
  234.         assert(c.count && *c.count == 1);
  235.         { c = b(); }
  236.         assert(c.count && *c.count == 2);
  237.         { c = Count(); }
  238.         assert(c.count && *c.count == 1);
  239.         a(false); // frees the static reference
  240. }
  241.  
  242. void test_sae_ret() // DMD
  243. {
  244.         Count c;
  245.         static Count a(bool x = true){
  246.                 static Count[1] cs;
  247.                 if( x && cs[0].count == null ) cs[0] = Count(true);
  248.                 else if( !x && cs[0].count != null ) cs[0] = Count();
  249.                 return cs[0];
  250.         }
  251.         { c = a(); }
  252.         assert(c.count && *c.count == 2);
  253.         { c = Count(); }
  254.         assert(c.count && *c.count == 1);
  255.         a(false); // frees the static reference
  256. }
  257.  
  258. void test_ae_ret() // DMD 7530
  259. {
  260.         Count c;
  261.         static Count a(bool x = true){
  262.                 static Count[] cs;
  263.                 if( x && cs.length == 0 ) cs ~= Count(true);
  264.                 else if( !x && cs.length > 0 ){ cs[0] = Count(); cs.length = 0; }
  265.                 return cs[0];
  266.         }
  267.         { c = a(); }
  268.         assert(c.count && *c.count == 2);
  269.         { c = Count(); }
  270.         assert(c.count && *c.count == 1);
  271.         a(false); // frees the static reference
  272. }
  273.  
  274. void test_aae_ret()
  275. {
  276.         Count c;
  277.         static Count a(bool x = true){
  278.                 static Count[int] cs;
  279.                 if( x && 0 !in cs ) cs[0] = Count(true);
  280.                 else if( !x && 0 in cs ) cs.remove(0);
  281.                 return cs[0];
  282.         }
  283.         { c = a(); }
  284.         assert(c.count && *c.count == 2);
  285.         { c = Count(); }
  286.         assert(c.count && *c.count == 1);
  287.         a(false); // frees the static reference
  288. }
  289.  
  290. void test_sm_ret()
  291. {
  292.         Count c;
  293.         struct S { Count c; }
  294.         static Count a(bool x = true){
  295.                 static S cs;
  296.                 if( x && cs.c.count == null ) cs.c = Count(true);
  297.                 else if( !x && cs.c.count != null ) cs.c = Count();
  298.                 return cs.c;
  299.         }
  300.         { c = a(); }
  301.         assert(c.count && *c.count == 2);
  302.         { c = Count(); }
  303.         assert(c.count && *c.count == 1);
  304.         a(false); // frees the static reference
  305. }
  306.  
  307. void test_tern_ret() // DMD 7516
  308. {
  309.         Count c;
  310.         static Count a(bool x, bool y = true){
  311.                 static Count cs;
  312.                 if( y && cs.count == null ) cs = Count(true);
  313.                 else if( !y && cs.count != null ) cs = Count();
  314.                 return x ? cs : Count(0);
  315.         }
  316.         static Count b(bool x){ return x ? a(x) : Count(); }
  317.         { c = a(true); }
  318.         assert(c.count && *c.count == 2);
  319.         { c = a(false); }
  320.         assert(c.count && *c.count == 1);
  321.         { c = b(true); }
  322.         assert(c.count && *c.count == 2);
  323.         { c = b(false); }
  324.         assert(c.count && *c.count == 1);
  325.         a(false, false); // frees the static reference
  326. }
  327.  
  328. void test_str_ass()
  329. {
  330.         struct S { Count c; }
  331.         S s, t;
  332.         { s.c = Count(true); }
  333.         assert(s.c.count && *s.c.count == 1);
  334.         { t = s; }
  335.         assert(s.c.count && *s.c.count == 2);
  336.         assert(t.c.count && *t.c.count == 2);
  337.         { t.c = Count(); }
  338.         assert(s.c.count && *s.c.count == 1);
  339.         { s = t; }
  340.         assert(s.c.count == null);
  341.         assert(t.c.count == null);
  342. }
  343.  
  344. void test_str_sa_ass()
  345. {
  346.         struct S { Count[2] c; }
  347.         S s, t;
  348.         { s.c[0] = Count(true); }
  349.         assert(s.c[0].count && *s.c[0].count == 1);
  350.         { t = s; }
  351.         assert(s.c[0].count && *s.c[0].count == 2);
  352.         assert(t.c[0].count && *t.c[0].count == 2);
  353.         { t.c[0] = Count(); }
  354.         assert(s.c[0].count && *s.c[0].count == 1);
  355.         { s = t; }
  356.         assert(s.c[0].count == null);
  357.         assert(t.c[0].count == null);
  358. }
  359.  
  360. @property void test(alias F)()
  361. {
  362.         import std.stdio;
  363.         writef("Test %s: ", F.stringof);
  364.         version(BAILOUT){
  365.                 F();
  366.                 assert(s_living.length == 0);
  367.         } else {
  368.                 try {
  369.                         F();
  370.                         if( s_living.length > 0 ){
  371.                                 writeln("FAIL (leak)");
  372.                         } else writeln("OK");
  373.                         s_living = null;
  374.                 } catch(Throwable th){
  375.                         writeln("FAIL");
  376.                 }
  377.         }
  378. }
  379.  
  380. int main()
  381. {
  382.         test!test_con_ass;
  383.         test!test_con_sae_ass;
  384.         test!test_con_ae_ass1;
  385.         test!test_con_ae_ass2;
  386.         test!test_con_aa_ass1;
  387.         test!test_con_aa_ass2;
  388.         test!test_con_sm_ass;
  389.         test!test_con_cm_ass;
  390.         test!test_con_delp;
  391.         test!test_con_refp;
  392.         test!test_con_refp2;
  393.         test!test_con_ptrp;
  394.         test!test_con_ptrp2;
  395.         test!test_con_outp;
  396.         test!test_con_ret;
  397.         test!test_var_ret;
  398.         test!test_sae_ret;
  399.         test!test_aae_ret;
  400.         test!test_sm_ret;
  401.         test!test_tern_ret;
  402.         test!test_str_ass;
  403.         test!test_str_sa_ass;
  404.         return 1;
  405. }
clone this paste RAW Paste Data