--- deliantra/server/include/util.h 2007/07/01 05:00:18 1.51 +++ deliantra/server/include/util.h 2007/08/06 10:54:12 1.54 @@ -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; } }; @@ -407,9 +440,9 @@ }; // Mostly the same as std::vector, but insert/erase can reorder -// the elements, making insret/remove O(1) instead of O(n). +// the elements, making append(=insert)/remove O(1) instead of O(n). // -// NOTE: only some forms of erase/insert are available +// NOTE: only some forms of erase are available template struct unordered_vector : std::vector > { @@ -460,10 +493,15 @@ : this->end (); } + void push_back (T *obj) + { + std::vector >::push_back (obj); + obj->*indexmember = this->size (); + } + void insert (T *obj) { push_back (obj); - obj->*indexmember = this->size (); } void insert (T &obj)