Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import std.stdio;
- //version=ASSIGNMENT_OPERATOR1;
- version=ASSIGNMENT_OPERATOR2;
- extern(C) void memcpy(void* dst, const void* src, size_t cnt);
- // keep track of all living objects
- bool[int*] s_living;
- // canonical reference count dummy implementation
- struct Count {
- int* count;
- int magic = 0x2f7d9a65;
- this(bool){
- count = new int;
- *count = 1;
- assert(count !in s_living);
- s_living[count] = true;
- }
- this(this){
- assert(magic == 0x2f7d9a65);
- if( count ){
- assert(*count > 0);
- (*count)++;
- }
- }
- ~this(){
- assert(magic == 0x2f7d9a65);
- if( count ){
- assert(*count > 0);
- if( --(*count) == 0){
- assert(count in s_living);
- s_living.remove(count);
- count = null;
- }
- }
- // reset just to catch uninitialized-errors better
- count = null;
- magic = 0;
- }
- version(ASSIGNMENT_OPERATOR1)
- {
- void opAssign(Count c)
- {
- assert(&this != &c); // note: c is passed by value
- assert(magic == 0x2f7d9a65);
- assert(c.magic == 0x2f7d9a65);
- typeid(Count).destroy(&this);
- memcpy(&this, &c, Count.sizeof);
- typeid(Count).postblit(&this);
- }
- }
- version(ASSIGNMENT_OPERATOR2)
- {
- void opAssign(Count c)
- {
- auto tmp = count;
- count = c.count;
- c.count = tmp;
- }
- }
- }
- void test_con_ass()
- {
- Count c;
- { c = Count(true); }
- assert(c.count && *c.count == 1);
- { c = Count(); }
- assert(c.count == null);
- }
- void test_con_sae_ass()
- {
- Count c[1];
- { c[0] = Count(true); }
- assert(*c[0].count == 1);
- { c[0] = Count(); }
- assert(c[0].count == null);
- }
- void test_con_ae_ass1()
- {
- Count c[] = new Count[1];
- { c[0] = Count(true); }
- assert(c[0].count && *c[0].count == 1);
- { c[0] = Count(); }
- assert(c[0].count == null);
- }
- void test_con_ae_ass2()
- {
- Count c[];
- { c ~= Count(true); }
- assert(c[0].count && *c[0].count == 1);
- { c[0] = Count(); }
- assert(c[0].count == null);
- { c ~= Count(true); }
- assert(c[0].count && *c[0].count == 1);
- Count tmp = c[0];
- assert(c[0].count && *c[0].count == 2);
- //{ c.length = 0; }
- { c[0] = Count(); c.length = 0; }
- assert(c[0].count && *c[0].count == 1);
- tmp = Count();
- assert(c[0].count == null);
- }
- void test_con_aa_ass1() // DMD 6178?
- {
- Count[int] c;
- { auto cs = Count(true); c[0] = cs; }
- assert(c[0].count && *c[0].count == 1);
- { Count cs; c[0] = cs; }
- assert(c[0].count == null);
- }
- void test_con_aa_ass2() // DMD 6178?
- {
- Count[int] c;
- { c[0] = Count(true); }
- assert(c[0].count && *c[0].count == 1);
- { c[0] = Count(); }
- assert(c[0].count == null);
- }
- void test_con_sm_ass()
- {
- struct S { Count c; }
- S s;
- { s.c = Count(true); }
- assert(s.c.count && *s.c.count == 1);
- { s.c = Count(); }
- assert(s.c.count == null);
- }
- void test_con_cm_ass()
- {
- class S { Count c; }
- S s = new S;
- { s.c = Count(true); }
- assert(s.c.count && *s.c.count == 1);
- { s.c = Count(); }
- assert(s.c.count == null);
- }
- void test_con_delp()
- {
- Count c;
- void f(Count c_){ c = c_; }
- { f(Count(true)); }
- assert(c.count && *c.count == 1);
- { f(Count()); }
- assert(c.count == null);
- }
- void test_con_refp()
- {
- Count c;
- static void f(ref Count cd, Count cs){ cd = cs; }
- { f(c, Count(true)); }
- assert(c.count && *c.count == 1);
- { f(c, Count()); }
- assert(c.count == null);
- }
- void test_con_refp2()
- {
- Count c;
- static void f(ref Count cd, ref Count cs){ cd = cs; }
- { auto cs = Count(true); f(c, cs); }
- assert(c.count && *c.count == 1);
- { Count cs; f(c, cs); }
- assert(c.count == null);
- }
- void test_con_ptrp()
- {
- Count c;
- static void f(Count* cd, Count cs){ *cd = cs; }
- { f(&c, Count(true)); }
- assert(c.count && *c.count == 1);
- { f(&c, Count()); }
- assert(c.count == null);
- }
- void test_con_ptrp2()
- {
- Count c;
- static void f(Count* cd, Count* cs){ *cd = *cs; }
- { auto cs = Count(true); f(&c, &cs); }
- assert(c.count && *c.count == 1);
- { Count cs; f(&c, &cs); }
- assert(c.count == null);
- }
- void test_con_outp()
- {
- Count c;
- static void f(out Count cd, Count cs){ cd = cs; }
- { f(c, Count(true)); }
- assert(c.count && *c.count == 1);
- { f(c, Count()); }
- assert(c.count == null);
- }
- void test_con_ret()
- {
- Count c;
- static Count a(){ return Count(true); }
- static Count b(){ return Count(); }
- { c = a(); }
- assert(c.count && *c.count == 1);
- { c = b(); }
- assert(c.count == null);
- }
- void test_var_ret()
- {
- Count c;
- static Count a(bool x = true){
- static Count cs;
- if( x && cs.count == null ) cs = Count(true);
- else if( !x && cs.count != null ) cs = Count();
- return cs;
- }
- static Count b(){ return a(); }
- { c = a(); }
- assert(c.count && *c.count == 2);
- { c = Count(); }
- assert(c.count && *c.count == 1);
- { c = b(); }
- assert(c.count && *c.count == 2);
- { c = Count(); }
- assert(c.count && *c.count == 1);
- a(false); // frees the static reference
- }
- void test_sae_ret() // DMD
- {
- Count c;
- static Count a(bool x = true){
- static Count[1] cs;
- if( x && cs[0].count == null ) cs[0] = Count(true);
- else if( !x && cs[0].count != null ) cs[0] = Count();
- return cs[0];
- }
- { c = a(); }
- assert(c.count && *c.count == 2);
- { c = Count(); }
- assert(c.count && *c.count == 1);
- a(false); // frees the static reference
- }
- void test_ae_ret() // DMD 7530
- {
- Count c;
- static Count a(bool x = true){
- static Count[] cs;
- if( x && cs.length == 0 ) cs ~= Count(true);
- else if( !x && cs.length > 0 ){ cs[0] = Count(); cs.length = 0; }
- return cs[0];
- }
- { c = a(); }
- assert(c.count && *c.count == 2);
- { c = Count(); }
- assert(c.count && *c.count == 1);
- a(false); // frees the static reference
- }
- void test_aae_ret()
- {
- Count c;
- static Count a(bool x = true){
- static Count[int] cs;
- if( x && 0 !in cs ) cs[0] = Count(true);
- else if( !x && 0 in cs ) cs.remove(0);
- return cs[0];
- }
- { c = a(); }
- assert(c.count && *c.count == 2);
- { c = Count(); }
- assert(c.count && *c.count == 1);
- a(false); // frees the static reference
- }
- void test_sm_ret()
- {
- Count c;
- struct S { Count c; }
- static Count a(bool x = true){
- static S cs;
- if( x && cs.c.count == null ) cs.c = Count(true);
- else if( !x && cs.c.count != null ) cs.c = Count();
- return cs.c;
- }
- { c = a(); }
- assert(c.count && *c.count == 2);
- { c = Count(); }
- assert(c.count && *c.count == 1);
- a(false); // frees the static reference
- }
- void test_tern_ret() // DMD 7516
- {
- Count c;
- static Count a(bool x, bool y = true){
- static Count cs;
- if( y && cs.count == null ) cs = Count(true);
- else if( !y && cs.count != null ) cs = Count();
- return x ? cs : Count(0);
- }
- static Count b(bool x){ return x ? a(x) : Count(); }
- { c = a(true); }
- assert(c.count && *c.count == 2);
- { c = a(false); }
- assert(c.count && *c.count == 1);
- { c = b(true); }
- assert(c.count && *c.count == 2);
- { c = b(false); }
- assert(c.count && *c.count == 1);
- a(false, false); // frees the static reference
- }
- void test_str_ass()
- {
- struct S { Count c; }
- S s, t;
- { s.c = Count(true); }
- assert(s.c.count && *s.c.count == 1);
- { t = s; }
- assert(s.c.count && *s.c.count == 2);
- assert(t.c.count && *t.c.count == 2);
- { t.c = Count(); }
- assert(s.c.count && *s.c.count == 1);
- { s = t; }
- assert(s.c.count == null);
- assert(t.c.count == null);
- }
- void test_str_sa_ass()
- {
- struct S { Count[2] c; }
- S s, t;
- { s.c[0] = Count(true); }
- assert(s.c[0].count && *s.c[0].count == 1);
- { t = s; }
- assert(s.c[0].count && *s.c[0].count == 2);
- assert(t.c[0].count && *t.c[0].count == 2);
- { t.c[0] = Count(); }
- assert(s.c[0].count && *s.c[0].count == 1);
- { s = t; }
- assert(s.c[0].count == null);
- assert(t.c[0].count == null);
- }
- @property void test(alias F)()
- {
- import std.stdio;
- writef("Test %s: ", F.stringof);
- version(BAILOUT){
- F();
- assert(s_living.length == 0);
- } else {
- try {
- F();
- if( s_living.length > 0 ){
- writeln("FAIL (leak)");
- } else writeln("OK");
- s_living = null;
- } catch(Throwable th){
- writeln("FAIL");
- }
- }
- }
- int main()
- {
- test!test_con_ass;
- test!test_con_sae_ass;
- test!test_con_ae_ass1;
- test!test_con_ae_ass2;
- test!test_con_aa_ass1;
- test!test_con_aa_ass2;
- test!test_con_sm_ass;
- test!test_con_cm_ass;
- test!test_con_delp;
- test!test_con_refp;
- test!test_con_refp2;
- test!test_con_ptrp;
- test!test_con_ptrp2;
- test!test_con_outp;
- test!test_con_ret;
- test!test_var_ret;
- test!test_sae_ret;
- test!test_aae_ret;
- test!test_sm_ret;
- test!test_tern_ret;
- test!test_str_ass;
- test!test_str_sa_ass;
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement