X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fstlplus%2Fcontainers%2Fsimple_ptr.tpp;h=ead6744035fe76fe087ceb32928789fe94802840;hp=13f55967c7ec00ea4c9150524e0589b4c95dd445;hb=5846afb00833cc72fe72422ca896d2387c712cb4;hpb=6b0a0d0efafe34d48ab344fca3b479553bd4e62c diff --git a/src/stlplus/containers/simple_ptr.tpp b/src/stlplus/containers/simple_ptr.tpp index 13f5596..ead6744 100644 --- a/src/stlplus/containers/simple_ptr.tpp +++ b/src/stlplus/containers/simple_ptr.tpp @@ -1,338 +1,338 @@ -//////////////////////////////////////////////////////////////////////////////// - -// Author: Daniel Milton -// Copyright: (c) Daniel Milton 2002-2009 - -//////////////////////////////////////////////////////////////////////////////// - -namespace stlplus -{ - - //////////////////////////////////////////////////////////////////////////////// - // simple_ptr_base class - //////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////// - // constructors, assignments and destructors - - // create a null pointer - template - simple_ptr_base::simple_ptr_base(void) : - m_pointer(0), - m_count(new unsigned(1)) - { - } - - // create a pointer containing a *copy* of the object pointer - template - simple_ptr_base::simple_ptr_base(const T& data) throw(illegal_copy) : - m_pointer(C()(data)), - m_count(new unsigned(1)) - { - } - - // create a pointer containing a dynamically created object - // Note: the object must be allocated *by the user* with new - // constructor form - must be called in the form simple_ptr x(new type(args)) - template - simple_ptr_base::simple_ptr_base(T* data) : - m_pointer(data), - m_count(new unsigned(1)) - { - } - - // copy constructor implements counted referencing - no copy is made - template - simple_ptr_base::simple_ptr_base(const simple_ptr_base& r) : - m_pointer(r.m_pointer), - m_count(r.m_count) - { - increment(); - } - - // assignment operator - required, else the output of GCC suffers segmentation faults - template - simple_ptr_base& simple_ptr_base::operator=(const simple_ptr_base& r) - { - alias(r); - return *this; - } - - // destructor decrements the reference count and delete only when the last reference is destroyed - template - simple_ptr_base::~simple_ptr_base(void) - { - if(decrement()) - { - delete m_pointer; - delete m_count; - } - } - - ////////////////////////////////////////////////////////////////////////////// - // logical tests to see if there is anything contained in the pointer since it can be null - - template - bool simple_ptr_base::null(void) const - { - return m_pointer==0; - } - - template - bool simple_ptr_base::present(void) const - { - return m_pointer!=0; - } - - template - bool simple_ptr_base::operator!(void) const - { - return m_pointer==0; - } - - template - simple_ptr_base::operator bool(void) const - { - return m_pointer!=0; - } - - ////////////////////////////////////////////////////////////////////////////// - // dereference operators and functions - - template - T& simple_ptr_base::operator*(void) throw(null_dereference) - { - if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*"); - return *m_pointer; - } - - template - const T& simple_ptr_base::operator*(void) const throw(null_dereference) - { - if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*"); - return *m_pointer; - } - - template - T* simple_ptr_base::operator->(void) throw(null_dereference) - { - if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->"); - return m_pointer; - } - - template - const T* simple_ptr_base::operator->(void) const throw(null_dereference) - { - if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->"); - return m_pointer; - } - - ////////////////////////////////////////////////////////////////////////////// - // explicit function forms of the above assignment dereference operators - - template - void simple_ptr_base::set_value(const T& data) throw(illegal_copy) - { - set(C()(data)); - } - - template - T& simple_ptr_base::value(void) throw(null_dereference) - { - if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value"); - return *m_pointer; - } - - template - const T& simple_ptr_base::value(void) const throw(null_dereference) - { - if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value"); - return *m_pointer; - } - - template - void simple_ptr_base::set(T* data) - { - unsigned& count = *m_count; - if (count<=1) - delete m_pointer; - else - { - --count; - m_count = new unsigned(1); - } - m_pointer = data; - } - - template - T* simple_ptr_base::pointer(void) - { - return m_pointer; - } - - template - const T* simple_ptr_base::pointer(void) const - { - return m_pointer; - } - - //////////////////////////////////////////////////////////////////////////////// - // functions to manage counted referencing - - template - void simple_ptr_base::increment(void) - { - ++(*m_count); - } - - template - bool simple_ptr_base::decrement(void) - { - unsigned& count = *m_count; - --count; - return count == 0; - } - - // make this an alias of the passed object - template - void simple_ptr_base::alias(const simple_ptr_base& r) - { - // make it alias-copy safe - this means that I don't try to do the - // assignment if r is either the same object or an alias of it - if (m_pointer==r.m_pointer) return; - if(decrement()) { - delete m_pointer; - delete m_count; - } - m_pointer = r.m_pointer; - m_count = r.m_count; - increment(); - } - - template - bool simple_ptr_base::aliases(const simple_ptr_base& r) const - { - return m_count == r.m_count; - } - - template - unsigned simple_ptr_base::alias_count(void) const - { - return *m_count; - } - - template - void simple_ptr_base::clear(void) - { - set(0); - } - - template - void simple_ptr_base::clear_unique(void) - { - set(0); // no difference between clear and clear_unique with the simple_ptr - } - - template - void simple_ptr_base::make_unique(void) throw(illegal_copy) - { - unsigned& count = *m_count; - if (count <= 1) return; - --count; - if (m_pointer) m_pointer = C()(*m_pointer); - m_count = new unsigned(1); - } - - template - void simple_ptr_base::copy(const simple_ptr_base& data) throw(illegal_copy) - { - alias(data); - make_unique(); - } - -#ifdef STLPLUS_MEMBER_TEMPLATES - - // dynamic cast of underlying pointer to a derived/parent - template - template - simple_ptr_base simple_ptr_base::dyn_cast(void) const - { - simple_ptr_base rtn; - rtn.m_pointer = dynamic_cast(m_pointer); - if (rtn.m_pointer) { - delete rtn.m_count; - rtn.m_count = m_count; - rtn.increment(); - } - return rtn; - } - - // static cast of underlying pointer to a derived/parent - template - template - simple_ptr_base simple_ptr_base::stat_cast(void) const - { - simple_ptr_base rtn; - rtn.m_pointer = static_cast(m_pointer); - if (rtn.m_pointer) { - delete rtn.m_count; - rtn.m_count = m_count; - rtn.increment(); - } - return rtn; - } - - // cast of underlying pointer to a base - while keeping the same ref-counted object - template - template - simple_ptr_base simple_ptr_base::cast(void) const - { - simple_ptr_base rtn; - rtn.m_pointer = (T2*)m_pointer; - if (rtn.m_pointer) { - delete rtn.m_count; - rtn.m_count = m_count; - rtn.increment(); - } - return rtn; - } - -#endif - - // internal function for distinguishing unique simple_ptr objects - // used for example in persistence routines - - template - unsigned* simple_ptr_base::_count(void) const - { - return m_count; - } - - template - T* simple_ptr_base::_pointer(void) const - { - return m_pointer; - } - - template - void simple_ptr_base::_make_alias(T* pointer, unsigned* count) - { - // make it alias-copy safe - this means that I don't try to do the - // assignment if r is either the same object or an alias of it - if (m_count != count) - { - if(decrement()) - { - delete m_pointer; - delete m_count; - } - m_pointer = pointer; - m_count = count; - increment(); - } - } - - //////////////////////////////////////////////////////////////////////////////// - -} // end namespace stlplus - +//////////////////////////////////////////////////////////////////////////////// + +// Author: Daniel Milton +// Copyright: (c) Daniel Milton 2002-2009 + +//////////////////////////////////////////////////////////////////////////////// + +namespace stlplus +{ + + //////////////////////////////////////////////////////////////////////////////// + // simple_ptr_base class + //////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////// + // constructors, assignments and destructors + + // create a null pointer + template + simple_ptr_base::simple_ptr_base(void) : + m_pointer(0), + m_count(new unsigned(1)) + { + } + + // create a pointer containing a *copy* of the object pointer + template + simple_ptr_base::simple_ptr_base(const T& data) throw(illegal_copy) : + m_pointer(C()(data)), + m_count(new unsigned(1)) + { + } + + // create a pointer containing a dynamically created object + // Note: the object must be allocated *by the user* with new + // constructor form - must be called in the form simple_ptr x(new type(args)) + template + simple_ptr_base::simple_ptr_base(T* data) : + m_pointer(data), + m_count(new unsigned(1)) + { + } + + // copy constructor implements counted referencing - no copy is made + template + simple_ptr_base::simple_ptr_base(const simple_ptr_base& r) : + m_pointer(r.m_pointer), + m_count(r.m_count) + { + increment(); + } + + // assignment operator - required, else the output of GCC suffers segmentation faults + template + simple_ptr_base& simple_ptr_base::operator=(const simple_ptr_base& r) + { + alias(r); + return *this; + } + + // destructor decrements the reference count and delete only when the last reference is destroyed + template + simple_ptr_base::~simple_ptr_base(void) + { + if(decrement()) + { + delete m_pointer; + delete m_count; + } + } + + ////////////////////////////////////////////////////////////////////////////// + // logical tests to see if there is anything contained in the pointer since it can be null + + template + bool simple_ptr_base::null(void) const + { + return m_pointer==0; + } + + template + bool simple_ptr_base::present(void) const + { + return m_pointer!=0; + } + + template + bool simple_ptr_base::operator!(void) const + { + return m_pointer==0; + } + + template + simple_ptr_base::operator bool(void) const + { + return m_pointer!=0; + } + + ////////////////////////////////////////////////////////////////////////////// + // dereference operators and functions + + template + T& simple_ptr_base::operator*(void) throw(null_dereference) + { + if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*"); + return *m_pointer; + } + + template + const T& simple_ptr_base::operator*(void) const throw(null_dereference) + { + if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator*"); + return *m_pointer; + } + + template + T* simple_ptr_base::operator->(void) throw(null_dereference) + { + if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->"); + return m_pointer; + } + + template + const T* simple_ptr_base::operator->(void) const throw(null_dereference) + { + if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::operator->"); + return m_pointer; + } + + ////////////////////////////////////////////////////////////////////////////// + // explicit function forms of the above assignment dereference operators + + template + void simple_ptr_base::set_value(const T& data) throw(illegal_copy) + { + set(C()(data)); + } + + template + T& simple_ptr_base::value(void) throw(null_dereference) + { + if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value"); + return *m_pointer; + } + + template + const T& simple_ptr_base::value(void) const throw(null_dereference) + { + if (!m_pointer) throw null_dereference("null pointer dereferenced in simple_ptr::value"); + return *m_pointer; + } + + template + void simple_ptr_base::set(T* data) + { + unsigned& count = *m_count; + if (count<=1) + delete m_pointer; + else + { + --count; + m_count = new unsigned(1); + } + m_pointer = data; + } + + template + T* simple_ptr_base::pointer(void) + { + return m_pointer; + } + + template + const T* simple_ptr_base::pointer(void) const + { + return m_pointer; + } + + //////////////////////////////////////////////////////////////////////////////// + // functions to manage counted referencing + + template + void simple_ptr_base::increment(void) + { + ++(*m_count); + } + + template + bool simple_ptr_base::decrement(void) + { + unsigned& count = *m_count; + --count; + return count == 0; + } + + // make this an alias of the passed object + template + void simple_ptr_base::alias(const simple_ptr_base& r) + { + // make it alias-copy safe - this means that I don't try to do the + // assignment if r is either the same object or an alias of it + if (m_pointer==r.m_pointer) return; + if(decrement()) { + delete m_pointer; + delete m_count; + } + m_pointer = r.m_pointer; + m_count = r.m_count; + increment(); + } + + template + bool simple_ptr_base::aliases(const simple_ptr_base& r) const + { + return m_count == r.m_count; + } + + template + unsigned simple_ptr_base::alias_count(void) const + { + return *m_count; + } + + template + void simple_ptr_base::clear(void) + { + set(0); + } + + template + void simple_ptr_base::clear_unique(void) + { + set(0); // no difference between clear and clear_unique with the simple_ptr + } + + template + void simple_ptr_base::make_unique(void) throw(illegal_copy) + { + unsigned& count = *m_count; + if (count <= 1) return; + --count; + if (m_pointer) m_pointer = C()(*m_pointer); + m_count = new unsigned(1); + } + + template + void simple_ptr_base::copy(const simple_ptr_base& data) throw(illegal_copy) + { + alias(data); + make_unique(); + } + +#ifdef STLPLUS_MEMBER_TEMPLATES + + // dynamic cast of underlying pointer to a derived/parent + template + template + simple_ptr_base simple_ptr_base::dyn_cast(void) const + { + simple_ptr_base rtn; + rtn.m_pointer = dynamic_cast(m_pointer); + if (rtn.m_pointer) { + delete rtn.m_count; + rtn.m_count = m_count; + rtn.increment(); + } + return rtn; + } + + // static cast of underlying pointer to a derived/parent + template + template + simple_ptr_base simple_ptr_base::stat_cast(void) const + { + simple_ptr_base rtn; + rtn.m_pointer = static_cast(m_pointer); + if (rtn.m_pointer) { + delete rtn.m_count; + rtn.m_count = m_count; + rtn.increment(); + } + return rtn; + } + + // cast of underlying pointer to a base - while keeping the same ref-counted object + template + template + simple_ptr_base simple_ptr_base::cast(void) const + { + simple_ptr_base rtn; + rtn.m_pointer = (T2*)m_pointer; + if (rtn.m_pointer) { + delete rtn.m_count; + rtn.m_count = m_count; + rtn.increment(); + } + return rtn; + } + +#endif + + // internal function for distinguishing unique simple_ptr objects + // used for example in persistence routines + + template + unsigned* simple_ptr_base::_count(void) const + { + return m_count; + } + + template + T* simple_ptr_base::_pointer(void) const + { + return m_pointer; + } + + template + void simple_ptr_base::_make_alias(T* pointer, unsigned* count) + { + // make it alias-copy safe - this means that I don't try to do the + // assignment if r is either the same object or an alias of it + if (m_count != count) + { + if(decrement()) + { + delete m_pointer; + delete m_count; + } + m_pointer = pointer; + m_count = count; + increment(); + } + } + + //////////////////////////////////////////////////////////////////////////////// + +} // end namespace stlplus +