// Filename: pointerToArray.I // Created by: drose (07Jan00) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // // All use of this software is subject to the terms of the revised BSD // license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #ifndef CPPPARSER template pvector PointerToArray::_empty_array; template pvector ConstPointerToArray::_empty_array; //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray:: PointerToArray(TypeHandle type_handle) : PointerToArrayBase((ReferenceCountedVector *)NULL), _type_handle(type_handle) { } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::empty_array // Access: Public, Static // Description: Return an empty array of size n //////////////////////////////////////////////////////////////////// template INLINE PointerToArray PointerToArray::empty_array(size_type n, TypeHandle type_handle) { PointerToArray temp(type_handle); temp.reassign(new ReferenceCountedVector(type_handle)); To new_array(n, type_handle); ((To *)(temp._void_ptr))->swap(new_array); return temp; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray:: PointerToArray(size_type n, const Element &value, TypeHandle type_handle) : PointerToArrayBase(new ReferenceCountedVector(type_handle)), _type_handle(type_handle) { ((To *)(this->_void_ptr))->reserve(n); insert(begin(), n, value); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Copy Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray:: PointerToArray(const PointerToArray ©) : PointerToArrayBase(copy), _type_handle(copy._type_handle) { } #ifdef HAVE_PYTHON //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Constructor // Access: Published // Description: This special constructor accepts a Python list of // elements, or a Python string. //////////////////////////////////////////////////////////////////// template PointerToArray:: PointerToArray(PyObject *self, PyObject *sequence) : PointerToArrayBase((ReferenceCountedVector *)NULL), _type_handle(get_type_handle(Element)) { // We have to pre-initialize self's "this" pointer when we receive // self in the constructor--the caller can't initialize this for us. ((Dtool_PyInstDef *)self)->_ptr_to_object = this; if (!PySequence_Check(sequence)) { // If passed with a non-sequence, this isn't the right constructor. PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a sequence"); return; } if (PyString_CheckExact(sequence)) { // If we were passed a Python string, then instead of storing it // character-at-a-time, just load the whole string as a data // buffer. int size = PyString_Size(sequence); if (size % sizeof(Element) != 0) { ostringstream stream; stream << "Buffer not a multiple of " << sizeof(Element) << " bytes"; string str = stream.str(); PyErr_SetString(PyExc_ValueError, str.c_str()); return; } int num_elements = size / sizeof(Element); insert(begin(), num_elements, Element()); // Hope there aren't any constructors or destructors involved // here. if (size != 0) { const char *data = PyString_AsString(sequence); memcpy(p(), data, size); } return; } // Now construct the internal list by copying the elements // one-at-a-time from Python. int size = PySequence_Size(sequence); for (int i = 0; i < size; ++i) { PyObject *item = PySequence_GetItem(sequence, i); if (item == NULL) { return; } PyObject *result = PyObject_CallMethod(self, (char *)"pushBack", (char *)"O", item); Py_DECREF(item); if (result == NULL) { // Unable to add item--probably it wasn't of the appropriate type. ostringstream stream; stream << "Element " << i << " in sequence passed to PointerToArray constructor could not be added"; string str = stream.str(); PyErr_SetString(PyExc_TypeError, str.c_str()); return; } Py_DECREF(result); } } #endif // HAVE_PYTHON //////////////////////////////////////////////////////////////////// // 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 ReferenceCountedVector(_type_handle)); } 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) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } ((To *)(this->_void_ptr))->reserve(n); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::resize // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: resize(TYPENAME PointerToArray::size_type n) { if ((this->_void_ptr) == NULL) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } ((To *)(this->_void_ptr))->resize(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 ReferenceCountedVector(_type_handle)); } 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 ReferenceCountedVector(_type_handle)); } 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) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); 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) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); 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) && !defined(WIN64_VC) //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Indexing operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reference PointerToArray:: operator [](size_type n) const { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } 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: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME PointerToArray::reference PointerToArray:: operator [](int n) const { return operator[]((size_type)n); } #endif //////////////////////////////////////////////////////////////////// // Function: PointerToArray::push_back // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: push_back(const Element &x) { if ((this->_void_ptr) == NULL) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } ((To *)(this->_void_ptr))->push_back(x); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::pop_back // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: pop_back() { nassertd((this->_void_ptr) != NULL) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } nassertv(!((To *)(this->_void_ptr))->empty()); ((To *)(this->_void_ptr))->pop_back(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::make_empty // Access: Public // 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 ReferenceCountedVector(_type_handle)); } 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 { To *vec = (To *)(this->_void_ptr); return ((vec == NULL)||(vec->empty())) ? (Element *)NULL : &(vec->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 { To *vec = (To *)(this->_void_ptr); return ((vec == NULL)||(vec->empty())) ? (Element *)NULL : &(vec->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 ReferenceCountedVector(_type_handle)); } return *((To *)(this->_void_ptr)); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::v0 // Access: Public // Description: To access the internal ReferenceCountedVector object, // for very low-level fiddling. Know what you are doing! //////////////////////////////////////////////////////////////////// template INLINE ReferenceCountedVector *PointerToArray:: v0() const { return (To *)(this->_void_ptr); } //////////////////////////////////////////////////////////////////// // 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::__getitem__ // Access: Published // Description: Same as get_element(), this returns the nth element // of the array. //////////////////////////////////////////////////////////////////// template INLINE const Element &PointerToArray:: __getitem__(size_type n) const { return (*this)[n]; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::__setitem__ // Access: Published // Description: Same as set_element(), this replaces the nth element // of the array. //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: __setitem__(size_type n, const Element &value) { nassertv(n < ((To *)(this->_void_ptr))->size()); (*this)[n] = value; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::get_data // Access: Published // Description: This method exists mainly to access the data of // the array easily from a high-level language such as // Python. // // It returns the entire contents of the vector as a // block of raw data in a string. //////////////////////////////////////////////////////////////////// template INLINE string PointerToArray:: get_data() const { return get_subdata(0, size()); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::set_data // Access: Published // Description: This method exists mainly to access the data of // the array easily from a high-level language such as // Python. // // It replaces the entire contents of the vector from a // block of raw data in a string. //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: set_data(const string &data) { set_subdata(0, size(), data); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::get_subdata // Access: Published // Description: This method exists mainly to access the data of // the array easily from a high-level language such as // Python. // // It returns the contents of a portion of the // vector--from element (n) through element (n + count - // 1)--as a block of raw data in a string. //////////////////////////////////////////////////////////////////// template INLINE string PointerToArray:: get_subdata(size_type n, size_type count) const { n = min(n, size()); count = max(count, n); count = min(count, size() - n); return string((const char *)(p() + n), sizeof(Element) * count); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::set_subdata // Access: Published // Description: This method exists mainly to access the data of // the array easily from a high-level language such as // Python. // // It replaces the contents of a portion of the // vector--from element (n) through element (n + count - // 1)--as a block of raw data in a string. The length // of the string must be an even multiple of Element // size bytes. The array may be expanded or truncated // if the length of the string does not correspond to // exactly count elements. //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: set_subdata(size_type n, size_type count, const string &data) { nassertv((data.length() % sizeof(Element)) == 0); nassertv(n <= size() && n + count <= size()); if ((this->_void_ptr) == NULL) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } size_type ncount = data.length() / sizeof(Element); if (ncount < count) { // Reduce the array. erase(begin() + n + ncount, begin() + n + count); } else if (count < ncount) { // Expand the array. insert(begin() + n + count, ncount - count, Element()); } // Now boldly replace the data. Hope there aren't any constructors // or destructors involved here. The user better know what she is // doing. memcpy(p() + n, data.data(), sizeof(Element) * ncount); } //////////////////////////////////////////////////////////////////// // 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) { ((PointerToArray *)this)->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::get_node_ref_count // Access: Public // Description: Returns the node_ref of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE int PointerToArray:: get_node_ref_count() const { return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->get_node_ref_count(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::node_ref // Access: Public // Description: Increments the node_ref of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE void PointerToArray:: node_ref() const { if ((this->_void_ptr) == NULL) { ((PointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } ((To *)(this->_void_ptr))->node_ref(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::node_unref // Access: Public // Description: Decrements the node_ref of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE bool PointerToArray:: node_unref() const { nassertr((this->_void_ptr) != NULL, true); return ((To *)(this->_void_ptr))->node_unref(); } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray &PointerToArray:: operator = (ReferenceCountedVector *ptr) { ((PointerToArray *)this)->reassign(ptr); return *this; } //////////////////////////////////////////////////////////////////// // Function: PointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE PointerToArray &PointerToArray:: operator = (const PointerToArray ©) { _type_handle = copy._type_handle; ((PointerToArray *)this)->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() { ((PointerToArray *)this)->reassign((ReferenceCountedVector *)NULL); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray:: ConstPointerToArray(TypeHandle type_handle) : PointerToArrayBase((ReferenceCountedVector *)NULL), _type_handle(type_handle) { } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Copy Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray:: ConstPointerToArray(const PointerToArray ©) : PointerToArrayBase(copy), _type_handle(copy._type_handle) { } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Copy Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray:: ConstPointerToArray(const ConstPointerToArray ©) : PointerToArrayBase(copy), _type_handle(copy._type_handle) { } //////////////////////////////////////////////////////////////////// // 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: Public // 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 ReferenceCountedVector(_type_handle)); } 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 ReferenceCountedVector(_type_handle)); } 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 ReferenceCountedVector(_type_handle)); } 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 ReferenceCountedVector(_type_handle)); } nassertd(!((To *)(this->_void_ptr))->empty()) { ((To *)(this->_void_ptr))->push_back(Element()); } return ((To *)(this->_void_ptr))->back(); } #if !defined(WIN32_VC) && !defined(WIN64_VC) //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Indexing operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reference ConstPointerToArray:: operator [](size_type n) const { nassertd((this->_void_ptr) != NULL) { ((ConstPointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } 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: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE TYPENAME ConstPointerToArray::reference ConstPointerToArray:: operator [](int n) const { return operator[]((size_type)n); } #endif //////////////////////////////////////////////////////////////////// // 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 { const To *vec = (const To *)(this->_void_ptr); return ((vec == NULL)||(vec->empty())) ? (const Element *)NULL : &(vec->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 { const To *vec = (const To *)(this->_void_ptr); return ((vec == NULL)||(vec->empty())) ? (const Element *)NULL : &(vec->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 ReferenceCountedVector(_type_handle)); } return *(const To *)(this->_void_ptr); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::v0 // Access: Public // Description: To access the internal ReferenceCountedVector object, // for very low-level fiddling. Know what you are doing! //////////////////////////////////////////////////////////////////// template INLINE const ReferenceCountedVector *ConstPointerToArray:: v0() const { return (const To *)(this->_void_ptr); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::cast_non_const // Access: Public // Description: Casts away the constness of the CPTA(Element), and // returns an equivalent PTA(Element). //////////////////////////////////////////////////////////////////// template INLINE PointerToArray ConstPointerToArray:: cast_non_const() const { PointerToArray non_const; non_const = (To *)(this->_void_ptr); return non_const; } //////////////////////////////////////////////////////////////////// // 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::__getitem__ // Access: Published // Description: Same as get_element(), this returns the nth element // of the array. //////////////////////////////////////////////////////////////////// template INLINE const Element &ConstPointerToArray:: __getitem__(size_type n) const { return (*this)[n]; } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::get_data // Access: Published // Description: This method exists mainly to access the data of // the array easily from a high-level language such as // Python. // // It returns the entire contents of the vector as a // block of raw data in a string. //////////////////////////////////////////////////////////////////// template INLINE string ConstPointerToArray:: get_data() const { return get_subdata(0, size()); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::get_subdata // Access: Published // Description: This method exists mainly to access the data of // the array easily from a high-level language such as // Python. // // It returns the contents of a portion of the // vector--from element (n) through element (n + count - // 1)--as a block of raw data in a string. //////////////////////////////////////////////////////////////////// template INLINE string ConstPointerToArray:: get_subdata(size_type n, size_type count) const { n = min(n, size()); count = max(count, n); count = min(count, size() - n); return string((const char *)(p() + n), sizeof(Element) * count); } //////////////////////////////////////////////////////////////////// // 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::get_node_ref_count // Access: Public // Description: Returns the node_ref of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE int ConstPointerToArray:: get_node_ref_count() const { return ((this->_void_ptr) == NULL) ? 0 : ((To *)(this->_void_ptr))->get_node_ref_count(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::node_ref // Access: Public // Description: Increments the node_ref of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE void ConstPointerToArray:: node_ref() const { if ((this->_void_ptr) == NULL) { ((ConstPointerToArray *)this)->reassign(new ReferenceCountedVector(_type_handle)); } ((To *)(this->_void_ptr))->node_ref(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::node_unref // Access: Public // Description: Decrements the node_ref of the underlying vector. //////////////////////////////////////////////////////////////////// template INLINE bool ConstPointerToArray:: node_unref() const { nassertr((this->_void_ptr) != NULL, true); return ((To *)(this->_void_ptr))->node_unref(); } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray &ConstPointerToArray:: operator = (ReferenceCountedVector *ptr) { ((ConstPointerToArray *)this)->reassign(ptr); return *this; } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray &ConstPointerToArray:: operator = (const PointerToArray ©) { _type_handle = copy._type_handle; ((ConstPointerToArray *)this)->reassign(copy); return *this; } //////////////////////////////////////////////////////////////////// // Function: ConstPointerToArray::Assignment operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// template INLINE ConstPointerToArray &ConstPointerToArray:: operator = (const ConstPointerToArray ©) { _type_handle = copy._type_handle; ((ConstPointerToArray *)this)->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() { ((ConstPointerToArray *)this)->reassign((ReferenceCountedVector *)NULL); } #endif // CPPPARSER