/*++ Copyright (c) 2006 Microsoft Corporation Module Name: ref_buffer.h Abstract: Buffer of smart pointers. Author: Leonardo de Moura (leonardo) 2008-01-04. Revision History: --*/ #ifndef _REF_BUFFER_H_ #define _REF_BUFFER_H_ #include"buffer.h" #include"obj_ref.h" #include"ref_vector.h" /** \brief Buffer of smart pointers. Ref must provide the methods - void dec_ref(T * obj) - void inc_ref(T * obj) */ template class ref_buffer_core : public Ref { protected: ptr_buffer m_buffer; void inc_ref(T * o) { Ref::inc_ref(o); } void dec_ref(T * o) { Ref::dec_ref(o); } void dec_range_ref(T * const * begin, T * const * end) { for (T * const * it = begin; it < end; ++it) dec_ref(*it); } public: typedef T * data; ref_buffer_core(Ref const & r = Ref()): Ref(r) { } ~ref_buffer_core() { dec_range_ref(m_buffer.begin(), m_buffer.end()); } void push_back(T * n) { inc_ref(n); m_buffer.push_back(n); } void pop_back() { SASSERT(!m_buffer.empty()); T * n = m_buffer.back(); m_buffer.pop_back(); dec_ref(n); } T * back() const { return m_buffer.back(); } T * & back() { return m_buffer.back(); } T ** c_ptr() const { return m_buffer.c_ptr(); } T const * operator[](unsigned idx) const { return m_buffer[idx]; } T * operator[](unsigned idx) { return m_buffer[idx]; } void set(unsigned idx, T * n) { inc_ref(n); dec_ref(m_buffer[idx]); m_buffer[idx] = n; } unsigned size() const { return m_buffer.size(); } bool empty() const { return m_buffer.empty(); } void reset() { dec_range_ref(m_buffer.begin(), m_buffer.end()); m_buffer.reset(); } void finalize() { dec_range_ref(m_buffer.begin(), m_buffer.end()); m_buffer.finalize(); } void append(unsigned n, T * const * elems) { for (unsigned i = 0; i < n; i++) { push_back(elems[i]); } } void append(ref_buffer_core const & other) { append(other.size(), other.c_ptr()); } void resize(unsigned sz) { if (sz < m_buffer.size()) dec_range_ref(m_buffer.begin() + sz, m_buffer.end()); m_buffer.resize(sz, 0); } // set pos idx with elem. If idx >= size, then expand. void setx(unsigned idx, T * elem) { if (idx >= size()) { resize(idx+1); } set(idx, elem); } private: // prevent abuse: ref_buffer_core& operator=(ref_buffer_core const & other); }; /** \brief Buffer of managed references */ template class ref_buffer : public ref_buffer_core > { typedef ref_buffer_core > super; public: ref_buffer(TManager & m): super(ref_manager_wrapper(m)) { } ref_buffer(ref_buffer const & other): super(ref_manager_wrapper(other.m_manager)) { SASSERT(this->m_buffer.size() == 0); append(other); } }; /** \brief Buffer of unmanaged references */ template class sref_buffer : public ref_buffer_core > { public: }; #endif /* _REF_BUFFER_H_ */