Advertisement
sludwig

Untitled

Feb 18th, 2012
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 8.41 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement