--- deliantra/server/include/util.h 2007/07/13 15:54:40 1.53 +++ deliantra/server/include/util.h 2007/08/16 06:36:56 1.55 @@ -335,33 +335,66 @@ extern rand_gen rndm; +INTERFACE_CLASS (attachable) +struct refcnt_base +{ + typedef int refcnt_t; + mutable refcnt_t ACC (RW, refcnt); + + MTH void refcnt_inc () const { ++refcnt; } + MTH void refcnt_dec () const { --refcnt; } + + refcnt_base () : refcnt (0) { } +}; + +extern refcnt_base::refcnt_t refcnt_dummy; + template struct refptr { + // p if not null + refcnt_base::refcnt_t *refcnt_ref () { return p ? &p->refcnt : &refcnt_dummy; } + + void refcnt_dec () + { + if (!is_constant (p)) + --*refcnt_ref (); + else if (p) + --p->refcnt; + } + + void refcnt_inc () + { + if (!is_constant (p)) + ++*refcnt_ref (); + else if (p) + ++p->refcnt; + } + T *p; refptr () : p(0) { } - refptr (const refptr &p) : p(p.p) { if (p) p->refcnt_inc (); } - refptr (T *p) : p(p) { if (p) p->refcnt_inc (); } - ~refptr () { if (p) p->refcnt_dec (); } + refptr (const refptr &p) : p(p.p) { refcnt_inc (); } + refptr (T *p) : p(p) { refcnt_inc (); } + ~refptr () { refcnt_dec (); } const refptr &operator =(T *o) { - if (p) p->refcnt_dec (); + // if decrementing ever destroys we need to reverse the order here + refcnt_dec (); p = o; - if (p) p->refcnt_inc (); - + refcnt_inc (); return *this; } - const refptr &operator =(const refptr o) + const refptr &operator =(const refptr &o) { *this = o.p; return *this; } T &operator * () const { return *p; } - T *operator ->() const { return p; } + T *operator ->() const { return p; } operator T *() const { return p; } }; @@ -513,8 +546,8 @@ int similar_direction (int a, int b); -// like printf, but returns a std::string -const std::string format (const char *format, ...); +// like sprintf, but returns a "static" buffer +const char *format (const char *format, ...); #endif