// Filename: pointerToArray.I // Created by: drose (07Jan00) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license // along with this source code; you will also find a current copy of // the license at http://etc.cmu.edu/panda3d/docs/license/ . // // To contact the maintainers of this program write to // panda3d-general@lists.sourceforge.net . // //////////////////////////////////////////////////////////////////// template pvector PointerToArray::_empty_array; template pvector ConstPointerToArray::_empty_array; //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Constructor // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray:: PointerToArray() : PointerToBase > >((RefCountObj > *)NULL) { } // return an empty array of size n template INLINE PointerToArray PointerToArray::empty_array(size_type n) { PointerToArray temp; temp.reserve(n); ((To *)temp._void_ptr)->insert(((To *)temp._void_ptr)->begin(), n, Element()); return temp; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Constructor // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray:: PointerToArray(size_type n, const Element &value) : PointerToBase > >(new RefCountObj >) { ((To *)(this->_void_ptr))->reserve(n); insert(begin(), n, value); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Copy Constructor // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray:: PointerToArray(const PointerToArray ©) : PointerToBase > >(copy) { } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::begin // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::iterator PointerToArray:: begin() const { if ((this->_void_ptr) == NULL) { return _empty_array.begin(); } return ((To *)(this->_void_ptr))->begin(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::end // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::iterator PointerToArray:: end() const { if ((this->_void_ptr) == NULL) { return _empty_array.begin(); } return ((To *)(this->_void_ptr))->end(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::rbegin // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reverse_iterator PointerToArray:: rbegin() const { if ((this->_void_ptr) == NULL) { return _empty_array.rbegin(); } return ((To *)(this->_void_ptr))->rbegin(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::rend // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reverse_iterator PointerToArray:: rend() const { if ((this->_void_ptr) == NULL) { return _empty_array.rbegin(); } return ((To *)(this->_void_ptr))->rend(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::size // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::size_type PointerToArray:: size() const { return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->size(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::max_size // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::size_type PointerToArray:: max_size() const { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new RefCountObj >); } return ((To *)(this->_void_ptr))->max_size(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::empty // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE bool PointerToArray:: empty() const { return ((this->_void_ptr) == NULL) ? true : ((To *)(this->_void_ptr))->empty(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::reserve // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: reserve(TYPENAME PointerToArray::size_type n) { if ((this->_void_ptr) == NULL) { reassign(new RefCountObj >); } ((To *)(this->_void_ptr))->reserve(n); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::capacity // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::size_type PointerToArray:: capacity() const { nassertr((this->_void_ptr) != NULL, 0); return ((To *)(this->_void_ptr))->capacity(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::front // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reference PointerToArray:: front() const { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new RefCountObj >); } nassertd(!((To *)(this->_void_ptr))->empty()) { ((To *)(this->_void_ptr))->push_back(Element()); } return ((To *)(this->_void_ptr))->front(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::back // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reference PointerToArray:: back() const { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new RefCountObj >); } nassertd(!((To *)(this->_void_ptr))->empty()) { ((To *)(this->_void_ptr))->push_back(Element()); } return ((To *)(this->_void_ptr))->back(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::insert // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::iterator PointerToArray:: insert(iterator position, const Element &x) { if ((this->_void_ptr) == NULL) { reassign(new RefCountObj >); position = end(); } nassertr(position >= ((To *)(this->_void_ptr))->begin() && position <= ((To *)(this->_void_ptr))->end(), position); return ((To *)(this->_void_ptr))->insert(position, x); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::insert // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: insert(iterator position, size_type n, const Element &x) { if ((this->_void_ptr) == NULL) { reassign(new RefCountObj >); position = end(); } nassertv(position >= ((To *)(this->_void_ptr))->begin() && position <= ((To *)(this->_void_ptr))->end()); ((To *)(this->_void_ptr))->insert(position, n, x); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::erase // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: erase(iterator position) { nassertv((this->_void_ptr) != NULL); nassertv(position >= ((To *)(this->_void_ptr))->begin() && position <= ((To *)(this->_void_ptr))->end()); ((To *)(this->_void_ptr))->erase(position); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::erase // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: erase(iterator first, iterator last) { nassertv((this->_void_ptr) != NULL); nassertv(first >= ((To *)(this->_void_ptr))->begin() && first <= ((To *)(this->_void_ptr))->end()); nassertv(last >= ((To *)(this->_void_ptr))->begin() && last <= ((To *)(this->_void_ptr))->end()); ((To *)(this->_void_ptr))->erase(first, last); } #if !defined(WIN32_VC) //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Indexing operator // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reference PointerToArray:: operator [](size_type n) const { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new RefCountObj >); } nassertd(!((To *)(this->_void_ptr))->empty()) { ((To *)(this->_void_ptr))->push_back(Element()); } nassertr(n < ((To *)(this->_void_ptr))->size(), ((To *)(this->_void_ptr))->operator[](0)); return ((To *)(this->_void_ptr))->operator[](n); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Indexing operator // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reference PointerToArray:: operator [](int n) const { return operator[]((size_type)n); } #endif //////////////////////////////////////////////////////////////////// // Function: PointerToArray::get_element // Access: Published // Description: This method exists mainly to access the elements of // the array easily from a high-level language such as // Python, especially on Windows, where the above index // element accessor methods can't be defined because of // a confusion with the pointer typecast operator. //////////////////////////////////////////////////////////////////// template INLINE const Element &PointerToArray:: get_element(size_type n) const { return (*this)[n]; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::set_element // Access: Published // Description: This method exists mainly to access the elements of // the array easily from a high-level language such as // Python, especially on Windows, where the above index // element accessor methods can't be defined because of // a confusion with the pointer typecast operator. //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: set_element(size_type n, const Element &value) { nassertv(n < ((To *)(this->_void_ptr))->size()); (*this)[n] = value; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::push_back // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: push_back(const Element &x) { if ((this->_void_ptr) == NULL) { reassign(new RefCountObj >); } ((To *)(this->_void_ptr))->push_back(x); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::pop_back // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: pop_back() { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new RefCountObj >); } nassertv(!((To *)(this->_void_ptr))->empty()); ((To *)(this->_void_ptr))->pop_back(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::make_empty // Access: Published // Description: Empties the array pointed to. This is different from // clear(), which reassigns the pointer to a NULL // pointer. //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: make_empty() { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new RefCountObj >); } nassertv(!((To *)(this->_void_ptr))->empty()); ((To *)(this->_void_ptr))->clear(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Typecast operator // Access: Public // Description: The pointer typecast operator is convenient for // maintaining the fiction that we actually have a // C-style array. It returns the address of the first // element in the array, unless the pointer is // unassigned, in which case it returns NULL. //////////////////////////////////////////////////////////////////// template INLINE PointerToArray:: operator Element *() const { return ((this->_void_ptr) == NULL) ? (Element *)NULL : &(((To *)(this->_void_ptr))->front()); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::p // Access: Public // Description: Function p() is similar to the function from // PointerTo. It does the same thing: it returns the // same thing as the typecast operator, above. //////////////////////////////////////////////////////////////////// template INLINE Element *PointerToArray:: p() const { return ((this->_void_ptr) == NULL) ? (Element *)NULL : &(((To *)(this->_void_ptr))->front()); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::v // Access: Public // Description: To access the vector itself, for more direct fiddling // with some of the vector's esoteric functionality. //////////////////////////////////////////////////////////////////// template INLINE pvector &PointerToArray:: v() const { if ((this->_void_ptr) == NULL) { ((PointerToArray *)this)->reassign(new RefCountObj >); } return *((To *)(this->_void_ptr)); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::get(this->_void_ptr) // Access: Public // Description: Returns the reference to memory where the vector // is stored. To be used only with set_void_ptr //////////////////////////////////////////////////////////////////// template INLINE void *PointerToArray:: get_void_ptr() const { return (this->_void_ptr); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::set_void_ptr // Access: Public // Description: Sets this PTA to point to the pointer passed in //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: set_void_ptr(void *p) { reassign((To *)p); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::get_ref_count // Access: Public // Description: Returns the reference count of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE int PointerToArray:: get_ref_count() const { return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->get_ref_count(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray &PointerToArray:: operator = (RefCountObj > *ptr) { reassign(ptr); return *this; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray &PointerToArray:: operator = (const PointerToArray ©) { reassign(copy); return *this; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::clear // Access: Public // Description: To empty the PTA, use the clear() method, since // assignment to NULL is problematic (given the // ambiguity of the pointer type of NULL). //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: clear() { reassign((RefCountObj > *)NULL); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Constructor // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray:: ConstPointerToArray() : PointerToBase > >((RefCountObj > *)NULL) { } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Copy Constructor // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray:: ConstPointerToArray(const PointerToArray ©) : PointerToBase > >(copy) { } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Copy Constructor // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray:: ConstPointerToArray(const ConstPointerToArray ©) : PointerToBase > >(copy) { } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::begin // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::iterator ConstPointerToArray:: begin() const { if ((this->_void_ptr) == NULL) { return _empty_array.begin(); } return ((To *)(this->_void_ptr))->begin(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::end // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::iterator ConstPointerToArray:: end() const { if ((this->_void_ptr) == NULL) { return _empty_array.begin(); } return ((To *)(this->_void_ptr))->end(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::rbegin // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reverse_iterator ConstPointerToArray:: rbegin() const { if ((this->_void_ptr) == NULL) { return _empty_array.rbegin(); } return ((To *)(this->_void_ptr))->rbegin(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::rend // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reverse_iterator ConstPointerToArray:: rend() const { if ((this->_void_ptr) == NULL) { return _empty_array.rbegin(); } return ((To *)(this->_void_ptr))->rend(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::size // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::size_type ConstPointerToArray:: size() const { return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->size(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::max_size // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::size_type ConstPointerToArray:: max_size() const { nassertd((this->_void_ptr) != NULL) { ((ConstPointerToArray *)this)->reassign(new RefCountObj >); } return ((To *)(this->_void_ptr))->max_size(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::empty // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE bool ConstPointerToArray:: empty() const { return ((this->_void_ptr) == NULL) ? true : ((To *)(this->_void_ptr))->empty(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::capacity // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::size_type ConstPointerToArray:: capacity() const { nassertd((this->_void_ptr) != NULL) { ((ConstPointerToArray *)this)->reassign(new RefCountObj >); } return ((To *)(this->_void_ptr))->capacity(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::front // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reference ConstPointerToArray:: front() const { nassertd((this->_void_ptr) != NULL) { ((ConstPointerToArray *)this)->reassign(new RefCountObj >); } nassertd(!((To *)(this->_void_ptr))->empty()) { ((To *)(this->_void_ptr))->push_back(Element()); } return ((To *)(this->_void_ptr))->front(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::back // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reference ConstPointerToArray:: back() const { nassertd((this->_void_ptr) != NULL) { ((ConstPointerToArray *)this)->reassign(new RefCountObj >); } nassertd(!((To *)(this->_void_ptr))->empty()) { ((To *)(this->_void_ptr))->push_back(Element()); } return ((To *)(this->_void_ptr))->back(); } #ifndef WIN32_VC //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Indexing operator // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reference ConstPointerToArray:: operator [](size_type n) const { nassertd((this->_void_ptr) != NULL) { ((ConstPointerToArray *)this)->reassign(new RefCountObj >); } nassertd(!((To *)(this->_void_ptr))->empty()) { ((To *)(this->_void_ptr))->push_back(Element()); } nassertr(n < ((To *)(this->_void_ptr))->size(), ((To *)(this->_void_ptr))->operator[](0)); return ((To *)(this->_void_ptr))->operator[](n); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Indexing operator // Access: Published // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reference ConstPointerToArray:: operator [](int n) const { return operator[]((size_type)n); } #endif //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::get_element // Access: Published // Description: This method exists mainly to access the elements of // the array easily from a high-level language such as // Python, especially on Windows, where the above index // element accessor methods can't be defined because of // a confusion with the pointer typecast operator. //////////////////////////////////////////////////////////////////// template INLINE const Element &ConstPointerToArray:: get_element(size_type n) const { return (*this)[n]; } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Typecast operator // Access: Public // Description: The pointer typecast operator is convenient for // maintaining the fiction that we actually have a // C-style array. It returns the address of the first // element in the array, unless the pointer is // unassigned, in which case it returns NULL. //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray:: operator const Element *() const { return ((this->_void_ptr) == NULL) ? (const Element *)NULL : &(((To *)(this->_void_ptr))->front()); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::p // Access: Public // Description: Function p() is similar to the function from // ConstPointerTo. It does the same thing: it returns the // same thing as the typecast operator, above. //////////////////////////////////////////////////////////////////// template INLINE const Element *ConstPointerToArray:: p() const { return ((this->_void_ptr) == NULL) ? (const Element *)NULL : &(((To *)(this->_void_ptr))->front()); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::v // Access: Public // Description: To access the vector itself, for more direct fiddling // with some of the vector's esoteric functionality. //////////////////////////////////////////////////////////////////// template INLINE const pvector &ConstPointerToArray:: v() const { nassertd((this->_void_ptr) != NULL) { ((ConstPointerToArray *)this)->reassign(new RefCountObj >); } return *(To *)(this->_void_ptr); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::get_ref_count // Access: Public // Description: Returns the reference count of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE int ConstPointerToArray:: get_ref_count() const { return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->get_ref_count(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray &ConstPointerToArray:: operator = (RefCountObj > *ptr) { reassign(ptr); return *this; } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray &ConstPointerToArray:: operator = (const PointerToArray ©) { reassign(copy); return *this; } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray &ConstPointerToArray:: operator = (const ConstPointerToArray ©) { reassign(copy); return *this; } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::clear // Access: Public // Description: To empty the PTA, use the clear() method, since // assignment to NULL is problematic (given the // ambiguity of the pointer type of NULL). //////////////////////////////////////////////////////////////////// template INLINE void ConstPointerToArray:: clear() { reassign((RefCountObj > *)NULL); }