#pragma once #include #include #include namespace cgv { /// namespace for data management components namespace data { template class ref_arr { private: /// struct to store the array pointer with a count struct counter_type { counter_type(T* a, int c) : arr(a), count(c) {} T* arr; int count; }; /// store pointer to counter struct counter_type* counter; /// store pointer to array T* arr; /// decrement the count, delete if it is 0 void release() { if (counter) { if (--counter->count == 0) { delete [] counter->arr; delete counter; } counter = 0; } arr = 0; } public: /// construct reference counted pointer explicit ref_arr(T* a = 0, counter_type* c = 0) : counter(c), arr(a) { if (!c && a) counter = new counter_type(a, 1); } /// copy construct from same pointer type and increment count ref_arr(const ref_arr& ra) : counter(ra.counter), arr(ra.arr) { if (counter) ++counter->count; } /// destruct reference counted pointer ~ref_arr() { release(); } /// assignment to pointer of same type ref_arr& operator = (const ref_arr& ra) { if (this == &ra) return *this; release(); new (this) ref_arr(ra); return *this; } /// return array pointer T* ptr() const { return arr; } /// access to element T& operator*() const { return *arr; } /// access to element pointer T* operator->() const { return arr; } /// access to i-th element T& operator [] (int i) { return arr[i]; } /// return an array pointer pointing to the i-th element ref_arr operator () (int i) const { return ref_arr(arr+i,counter); } /// compare by pointer bool operator == (const ref_arr& ra) const { return arr == ra.arr; } /// return current count int get_count() const { return counter ? counter->count : 0; } /// check if this is the only reference bool unique() const { return get_count() <= 1; } /// check if pointer is not yet set bool empty() const { return get_count() == 0; } /// conversion to bool results in false if the stored pointer is a null pointer operator bool () const { return !empty(); } /// clear the array pointer void clear() { release(); } }; } }