historical/toontown-classic.git/panda/include/pointerToArray.I
2024-01-16 11:20:27 -06:00

1113 lines
29 KiB
Text

/**
* 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."
*
* @file pointerToArray.I
* @author drose
* @date 2000-01-07
*/
#ifndef CPPPARSER
template<class Element>
pvector<Element> PointerToArray<Element>::_empty_array;
template<class Element>
pvector<Element> ConstPointerToArray<Element>::_empty_array;
/**
*
*/
template<class Element>
INLINE PointerToArray<Element>::
PointerToArray(TypeHandle type_handle) :
PointerToArrayBase<Element>(nullptr),
_type_handle(type_handle)
{
}
/**
* Return an empty array of size n
*/
template<class Element>
INLINE PointerToArray<Element>
PointerToArray<Element>::empty_array(size_type n, TypeHandle type_handle) {
PointerToArray<Element> temp(type_handle);
temp.reassign(new ReferenceCountedVector<Element>(type_handle));
To new_array(n, type_handle);
((To *)(temp._void_ptr))->swap(new_array);
return temp;
}
/**
*
*/
template<class Element>
INLINE PointerToArray<Element>::
PointerToArray(size_type n, const Element &value, TypeHandle type_handle) :
PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(type_handle)),
_type_handle(type_handle)
{
((To *)(this->_void_ptr))->reserve(n);
insert(begin(), n, value);
}
/**
*
*/
template<class Element>
INLINE PointerToArray<Element>::
PointerToArray(const PointerToArray<Element> &copy) :
PointerToArrayBase<Element>(copy),
_type_handle(copy._type_handle)
{
}
/**
* Initializes a PointerToArray by copying existing elements.
*/
template<class Element>
INLINE PointerToArray<Element>::
PointerToArray(const Element *begin, const Element *end, TypeHandle type_handle) :
PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(begin, end, type_handle)),
_type_handle(type_handle)
{
}
/**
*
*/
template<class Element>
INLINE PointerToArray<Element>::
PointerToArray(PointerToArray<Element> &&from) noexcept :
PointerToArrayBase<Element>(std::move(from)),
_type_handle(from._type_handle)
{
}
/**
* Initializes the PTA from a vector.
*/
template<class Element>
INLINE PointerToArray<Element>::
PointerToArray(pvector<Element> &&from, TypeHandle type_handle) :
PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(std::move(from))),
_type_handle(type_handle)
{
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
begin() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.begin();
}
return ((To *)(this->_void_ptr))->begin();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
end() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.begin();
}
return ((To *)(this->_void_ptr))->end();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::reverse_iterator PointerToArray<Element>::
rbegin() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.rbegin();
}
return ((To *)(this->_void_ptr))->rbegin();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::reverse_iterator PointerToArray<Element>::
rend() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.rbegin();
}
return ((To *)(this->_void_ptr))->rend();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
size() const {
return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->size();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
max_size() const {
nassertd((this->_void_ptr) != nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
return ((To *)(this->_void_ptr))->max_size();
}
/**
*
*/
template<class Element>
INLINE bool PointerToArray<Element>::
empty() const {
return ((this->_void_ptr) == nullptr) ? true : ((To *)(this->_void_ptr))->empty();
}
/**
*
*/
template<class Element>
INLINE void PointerToArray<Element>::
reserve(typename PointerToArray<Element>::size_type n) {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->reserve(n);
}
/**
*
*/
template<class Element>
INLINE void PointerToArray<Element>::
resize(typename PointerToArray<Element>::size_type n) {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->resize(n);
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
capacity() const {
nassertr((this->_void_ptr) != nullptr, 0);
return ((To *)(this->_void_ptr))->capacity();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
front() const {
nassertd((this->_void_ptr) != nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
nassertd(!((To *)(this->_void_ptr))->empty()) {
((To *)(this->_void_ptr))->push_back(Element());
}
return ((To *)(this->_void_ptr))->front();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
back() const {
nassertd((this->_void_ptr) != nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
nassertd(!((To *)(this->_void_ptr))->empty()) {
((To *)(this->_void_ptr))->push_back(Element());
}
return ((To *)(this->_void_ptr))->back();
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
insert(iterator position, const Element &x) {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_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);
}
/**
*
*/
template<class Element>
INLINE void PointerToArray<Element>::
insert(iterator position, size_type n, const Element &x) {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_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);
}
/**
*
*/
template<class Element>
INLINE void PointerToArray<Element>::
erase(iterator position) {
nassertv((this->_void_ptr) != nullptr);
nassertv(position >= ((To *)(this->_void_ptr))->begin() &&
position <= ((To *)(this->_void_ptr))->end());
((To *)(this->_void_ptr))->erase(position);
}
/**
*
*/
template<class Element>
INLINE void PointerToArray<Element>::
erase(iterator first, iterator last) {
nassertv((this->_void_ptr) != nullptr);
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)
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
operator [](size_type n) const {
nassertd((this->_void_ptr) != nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_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);
}
/**
*
*/
template<class Element>
INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
operator [](int n) const {
return operator[]((size_type)n);
}
#endif
/**
*
*/
template<class Element>
INLINE void PointerToArray<Element>::
push_back(const Element &x) {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->push_back(x);
}
/**
*
*/
template<class Element>
INLINE void PointerToArray<Element>::
pop_back() {
nassertd((this->_void_ptr) != nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
nassertv(!((To *)(this->_void_ptr))->empty());
((To *)(this->_void_ptr))->pop_back();
}
/**
* Empties the array pointed to. This is different from clear(), which
* reassigns the pointer to a NULL pointer.
*/
template<class Element>
INLINE void PointerToArray<Element>::
make_empty() {
nassertd((this->_void_ptr) != nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
nassertv(!((To *)(this->_void_ptr))->empty());
((To *)(this->_void_ptr))->clear();
}
/**
* 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<class Element>
INLINE PointerToArray<Element>::
operator Element *() const {
To *vec = (To *)(this->_void_ptr);
return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
}
/**
* 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<class Element>
INLINE Element *PointerToArray<Element>::
p() const {
To *vec = (To *)(this->_void_ptr);
return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
}
/**
* To access the vector itself, for more direct fiddling with some of the
* vector's esoteric functionality.
*/
template<class Element>
INLINE pvector<Element> &PointerToArray<Element>::
v() const {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
return *((To *)(this->_void_ptr));
}
/**
* To access the internal ReferenceCountedVector object, for very low-level
* fiddling. Know what you are doing!
*/
template<class Element>
INLINE ReferenceCountedVector<Element> *PointerToArray<Element>::
v0() const {
return (To *)(this->_void_ptr);
}
/**
* 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<class Element>
INLINE const Element &PointerToArray<Element>::
get_element(size_type n) const {
return (*this)[n];
}
/**
* 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<class Element>
INLINE void PointerToArray<Element>::
set_element(size_type n, const Element &value) {
nassertv(n < ((To *)(this->_void_ptr))->size());
(*this)[n] = value;
}
/**
* 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<class Element>
INLINE std::string PointerToArray<Element>::
get_data() const {
return get_subdata(0, size());
}
/**
* 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<class Element>
INLINE void PointerToArray<Element>::
set_data(const std::string &data) {
set_subdata(0, size(), data);
}
/**
* 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<class Element>
INLINE std::string PointerToArray<Element>::
get_subdata(size_type n, size_type count) const {
n = std::min(n, size());
count = std::max(count, n);
count = std::min(count, size() - n);
return std::string((const char *)(p() + n), sizeof(Element) * count);
}
/**
* 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<class Element>
INLINE void PointerToArray<Element>::
set_subdata(size_type n, size_type count, const std::string &data) {
nassertv((data.length() % sizeof(Element)) == 0);
nassertv(n <= size() && n + count <= size());
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_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);
}
/**
* Returns the reference to memory where the vector is stored. To be used
* only with set_void_ptr
*/
template<class Element>
INLINE void *PointerToArray<Element>::
get_void_ptr() const {
return (this->_void_ptr);
}
/**
* Sets this PTA to point to the pointer passed in
*/
template<class Element>
INLINE void PointerToArray<Element>::
set_void_ptr(void *p) {
((PointerToArray<Element> *)this)->reassign((To *)p);
}
/**
* Returns the reference count of the underlying vector.
*/
template<class Element>
INLINE int PointerToArray<Element>::
get_ref_count() const {
return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_ref_count();
}
/**
* Increments the reference count of the underlying vector.
*/
template<class Element>
INLINE void PointerToArray<Element>::
ref() const {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->ref();
}
/**
* Decrements the reference count of the underlying vector.
*/
template<class Element>
INLINE bool PointerToArray<Element>::
unref() const {
nassertr((this->_void_ptr) != nullptr, true);
return ((To *)(this->_void_ptr))->unref();
}
/**
* Returns the node_ref of the underlying vector.
*/
template<class Element>
INLINE int PointerToArray<Element>::
get_node_ref_count() const {
return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_node_ref_count();
}
/**
* Increments the node_ref of the underlying vector.
*/
template<class Element>
INLINE void PointerToArray<Element>::
node_ref() const {
if ((this->_void_ptr) == nullptr) {
((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->node_ref();
}
/**
* Decrements the node_ref of the underlying vector.
*/
template<class Element>
INLINE bool PointerToArray<Element>::
node_unref() const {
nassertr((this->_void_ptr) != nullptr, true);
return ((To *)(this->_void_ptr))->node_unref();
}
/**
* Counts the frequency at which the given element occurs in the vector.
*/
template<class Element>
INLINE size_t PointerToArray<Element>::
count(const Element &value) const {
if ((this->_void_ptr) != nullptr) {
return std::count(begin(), end(), value);
} else {
return 0;
}
}
/**
*
*/
template<class Element>
INLINE PointerToArray<Element> &PointerToArray<Element>::
operator = (ReferenceCountedVector<Element> *ptr) {
((PointerToArray<Element> *)this)->reassign(ptr);
return *this;
}
/**
*
*/
template<class Element>
INLINE PointerToArray<Element> &PointerToArray<Element>::
operator = (const PointerToArray<Element> &copy) {
_type_handle = copy._type_handle;
((PointerToArray<Element> *)this)->reassign(copy);
return *this;
}
/**
*
*/
template<class Element>
INLINE PointerToArray<Element> &PointerToArray<Element>::
operator = (PointerToArray<Element> &&from) noexcept {
_type_handle = from._type_handle;
((PointerToArray<Element> *)this)->reassign(std::move(from));
return *this;
}
/**
* To empty the PTA, use the clear() method, since assignment to NULL is
* problematic (given the ambiguity of the pointer type of NULL).
*/
template<class Element>
INLINE void PointerToArray<Element>::
clear() {
((PointerToArray<Element> *)this)->reassign(nullptr);
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(TypeHandle type_handle) :
PointerToArrayBase<Element>(nullptr),
_type_handle(type_handle)
{
}
/**
* Initializes a ConstPointerToArray by copying existing elements.
*/
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(const Element *begin, const Element *end, TypeHandle type_handle) :
PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(begin, end, type_handle)),
_type_handle(type_handle)
{
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(const PointerToArray<Element> &copy) :
PointerToArrayBase<Element>(copy),
_type_handle(copy._type_handle)
{
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(const ConstPointerToArray<Element> &copy) :
PointerToArrayBase<Element>(copy),
_type_handle(copy._type_handle)
{
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(PointerToArray<Element> &&from) noexcept :
PointerToArrayBase<Element>(std::move(from)),
_type_handle(from._type_handle)
{
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(ConstPointerToArray<Element> &&from) noexcept :
PointerToArrayBase<Element>(std::move(from)),
_type_handle(from._type_handle)
{
}
/**
* Initializes the PTA from a vector.
*/
template<class Element>
INLINE ConstPointerToArray<Element>::
ConstPointerToArray(pvector<Element> &&from, TypeHandle type_handle) :
PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(std::move(from))),
_type_handle(type_handle)
{
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::iterator ConstPointerToArray<Element>::
begin() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.begin();
}
return ((To *)(this->_void_ptr))->begin();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::iterator ConstPointerToArray<Element>::
end() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.begin();
}
return ((To *)(this->_void_ptr))->end();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::reverse_iterator ConstPointerToArray<Element>::
rbegin() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.rbegin();
}
return ((To *)(this->_void_ptr))->rbegin();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::reverse_iterator ConstPointerToArray<Element>::
rend() const {
if ((this->_void_ptr) == nullptr) {
return _empty_array.rbegin();
}
return ((To *)(this->_void_ptr))->rend();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
size() const {
return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->size();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
max_size() const {
nassertd((this->_void_ptr) != nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
return ((To *)(this->_void_ptr))->max_size();
}
/**
*
*/
template<class Element>
INLINE bool ConstPointerToArray<Element>::
empty() const {
return ((this->_void_ptr) == nullptr) ? true : ((To *)(this->_void_ptr))->empty();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
capacity() const {
nassertd((this->_void_ptr) != nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
return ((To *)(this->_void_ptr))->capacity();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
front() const {
nassertd((this->_void_ptr) != nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
nassertd(!((To *)(this->_void_ptr))->empty()) {
((To *)(this->_void_ptr))->push_back(Element());
}
return ((To *)(this->_void_ptr))->front();
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
back() const {
nassertd((this->_void_ptr) != nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_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)
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
operator [](size_type n) const {
nassertd((this->_void_ptr) != nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_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);
}
/**
*
*/
template<class Element>
INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
operator [](int n) const {
return operator[]((size_type)n);
}
#endif
/**
* 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<class Element>
INLINE ConstPointerToArray<Element>::
operator const Element *() const {
const To *vec = (const To *)(this->_void_ptr);
return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
}
/**
* 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<class Element>
INLINE const Element *ConstPointerToArray<Element>::
p() const {
const To *vec = (const To *)(this->_void_ptr);
return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
}
/**
* To access the vector itself, for more direct fiddling with some of the
* vector's esoteric functionality.
*/
template<class Element>
INLINE const pvector<Element> &ConstPointerToArray<Element>::
v() const {
nassertd((this->_void_ptr) != nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
return *(const To *)(this->_void_ptr);
}
/**
* To access the internal ReferenceCountedVector object, for very low-level
* fiddling. Know what you are doing!
*/
template<class Element>
INLINE const ReferenceCountedVector<Element> *ConstPointerToArray<Element>::
v0() const {
return (const To *)(this->_void_ptr);
}
/**
* Casts away the constness of the CPTA(Element), and returns an equivalent
* PTA(Element).
*/
template<class Element>
INLINE PointerToArray<Element> ConstPointerToArray<Element>::
cast_non_const() const {
PointerToArray<Element> non_const;
non_const = (To *)(this->_void_ptr);
return non_const;
}
/**
* 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<class Element>
INLINE const Element &ConstPointerToArray<Element>::
get_element(size_type n) const {
return (*this)[n];
}
/**
* 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<class Element>
INLINE std::string ConstPointerToArray<Element>::
get_data() const {
return get_subdata(0, size());
}
/**
* 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<class Element>
INLINE std::string ConstPointerToArray<Element>::
get_subdata(size_type n, size_type count) const {
n = std::min(n, size());
count = std::max(count, n);
count = std::min(count, size() - n);
return std::string((const char *)(p() + n), sizeof(Element) * count);
}
/**
* Returns the reference count of the underlying vector.
*/
template<class Element>
INLINE int ConstPointerToArray<Element>::
get_ref_count() const {
return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_ref_count();
}
/**
* Increments the reference count of the underlying vector.
*/
template<class Element>
INLINE void ConstPointerToArray<Element>::
ref() const {
if ((this->_void_ptr) == nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->ref();
}
/**
* Decrements the reference count of the underlying vector.
*/
template<class Element>
INLINE bool ConstPointerToArray<Element>::
unref() const {
nassertr((this->_void_ptr) != nullptr, true);
return ((To *)(this->_void_ptr))->unref();
}
/**
* Returns the node_ref of the underlying vector.
*/
template<class Element>
INLINE int ConstPointerToArray<Element>::
get_node_ref_count() const {
return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_node_ref_count();
}
/**
* Increments the node_ref of the underlying vector.
*/
template<class Element>
INLINE void ConstPointerToArray<Element>::
node_ref() const {
if ((this->_void_ptr) == nullptr) {
((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
}
((To *)(this->_void_ptr))->node_ref();
}
/**
* Decrements the node_ref of the underlying vector.
*/
template<class Element>
INLINE bool ConstPointerToArray<Element>::
node_unref() const {
nassertr((this->_void_ptr) != nullptr, true);
return ((To *)(this->_void_ptr))->node_unref();
}
/**
* Counts the frequency at which the given element occurs in the vector.
*/
template<class Element>
INLINE size_t ConstPointerToArray<Element>::
count(const Element &value) const {
if ((this->_void_ptr) != nullptr) {
return std::count(begin(), end(), value);
} else {
return 0;
}
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
operator = (ReferenceCountedVector<Element> *ptr) {
((ConstPointerToArray<Element> *)this)->reassign(ptr);
return *this;
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
operator = (const PointerToArray<Element> &copy) {
_type_handle = copy._type_handle;
((ConstPointerToArray<Element> *)this)->reassign(copy);
return *this;
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
operator = (const ConstPointerToArray<Element> &copy) {
_type_handle = copy._type_handle;
((ConstPointerToArray<Element> *)this)->reassign(copy);
return *this;
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
operator = (PointerToArray<Element> &&from) noexcept {
_type_handle = from._type_handle;
((ConstPointerToArray<Element> *)this)->reassign(std::move(from));
return *this;
}
/**
*
*/
template<class Element>
INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
operator = (ConstPointerToArray<Element> &&from) noexcept {
_type_handle = from._type_handle;
((ConstPointerToArray<Element> *)this)->reassign(std::move(from));
return *this;
}
/**
* To empty the PTA, use the clear() method, since assignment to NULL is
* problematic (given the ambiguity of the pointer type of NULL).
*/
template<class Element>
INLINE void ConstPointerToArray<Element>::
clear() {
((ConstPointerToArray<Element> *)this)->reassign(nullptr);
}
#endif // CPPPARSER