Panda3D
pointerToArray.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file pointerToArray.I
10  * @author drose
11  * @date 2000-01-07
12  */
13 
14 #ifndef CPPPARSER
15 
16 template<class Element>
18 
19 template<class Element>
21 
22 /**
23  *
24  */
25 template<class Element>
27 PointerToArray(TypeHandle type_handle) :
28  PointerToArrayBase<Element>(nullptr),
29  _type_handle(type_handle)
30 {
31 }
32 
33 /**
34  * Return an empty array of size n
35  */
36 template<class Element>
39  PointerToArray<Element> temp(type_handle);
40  temp.reassign(new ReferenceCountedVector<Element>(type_handle));
41 
42  To new_array(n, type_handle);
43  ((To *)(temp._void_ptr))->swap(new_array);
44  return temp;
45 }
46 
47 /**
48  *
49  */
50 template<class Element>
52 PointerToArray(size_type n, const Element &value, TypeHandle type_handle) :
53  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(type_handle)),
54  _type_handle(type_handle)
55 {
56  ((To *)(this->_void_ptr))->reserve(n);
57  insert(begin(), n, value);
58 }
59 
60 /**
61  *
62  */
63 template<class Element>
66  PointerToArrayBase<Element>(copy),
67  _type_handle(copy._type_handle)
68 {
69 }
70 
71 /**
72  * Initializes a PointerToArray by copying existing elements.
73  */
74 template<class Element>
76 PointerToArray(const Element *begin, const Element *end, TypeHandle type_handle) :
77  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(begin, end, type_handle)),
78  _type_handle(type_handle)
79 {
80 }
81 
82 /**
83  *
84  */
85 template<class Element>
87 PointerToArray(PointerToArray<Element> &&from) noexcept :
88  PointerToArrayBase<Element>(std::move(from)),
89  _type_handle(from._type_handle)
90 {
91 }
92 
93 /**
94  * Initializes the PTA from a vector.
95  */
96 template<class Element>
99  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(std::move(from))),
100  _type_handle(type_handle)
101 {
102 }
103 
104 /**
105  *
106  */
107 template<class Element>
108 INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
109 begin() const {
110  if ((this->_void_ptr) == nullptr) {
111  return _empty_array.begin();
112  }
113  return ((To *)(this->_void_ptr))->begin();
114 }
115 
116 /**
117  *
118  */
119 template<class Element>
120 INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
121 end() const {
122  if ((this->_void_ptr) == nullptr) {
123  return _empty_array.begin();
124  }
125  return ((To *)(this->_void_ptr))->end();
126 }
127 
128 /**
129  *
130  */
131 template<class Element>
132 INLINE typename PointerToArray<Element>::reverse_iterator PointerToArray<Element>::
133 rbegin() const {
134  if ((this->_void_ptr) == nullptr) {
135  return _empty_array.rbegin();
136  }
137  return ((To *)(this->_void_ptr))->rbegin();
138 }
139 
140 /**
141  *
142  */
143 template<class Element>
144 INLINE typename PointerToArray<Element>::reverse_iterator PointerToArray<Element>::
145 rend() const {
146  if ((this->_void_ptr) == nullptr) {
147  return _empty_array.rbegin();
148  }
149  return ((To *)(this->_void_ptr))->rend();
150 }
151 
152 /**
153  *
154  */
155 template<class Element>
156 INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
157 size() const {
158  return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->size();
159 }
160 
161 /**
162  *
163  */
164 template<class Element>
165 INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
166 max_size() const {
167  nassertd((this->_void_ptr) != nullptr) {
168  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
169  }
170  return ((To *)(this->_void_ptr))->max_size();
171 }
172 
173 /**
174  *
175  */
176 template<class Element>
177 INLINE bool PointerToArray<Element>::
178 empty() const {
179  return ((this->_void_ptr) == nullptr) ? true : ((To *)(this->_void_ptr))->empty();
180 }
181 
182 /**
183  *
184  */
185 template<class Element>
186 INLINE void PointerToArray<Element>::
187 reserve(typename PointerToArray<Element>::size_type n) {
188  if ((this->_void_ptr) == nullptr) {
189  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
190  }
191  ((To *)(this->_void_ptr))->reserve(n);
192 }
193 
194 /**
195  *
196  */
197 template<class Element>
198 INLINE void PointerToArray<Element>::
199 resize(typename PointerToArray<Element>::size_type n) {
200  if ((this->_void_ptr) == nullptr) {
201  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
202  }
203  ((To *)(this->_void_ptr))->resize(n);
204 }
205 
206 /**
207  *
208  */
209 template<class Element>
210 INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
211 capacity() const {
212  nassertr((this->_void_ptr) != nullptr, 0);
213  return ((To *)(this->_void_ptr))->capacity();
214 }
215 
216 /**
217  *
218  */
219 template<class Element>
220 INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
221 front() const {
222  nassertd((this->_void_ptr) != nullptr) {
223  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
224  }
225  nassertd(!((To *)(this->_void_ptr))->empty()) {
226  ((To *)(this->_void_ptr))->push_back(Element());
227  }
228  return ((To *)(this->_void_ptr))->front();
229 }
230 
231 /**
232  *
233  */
234 template<class Element>
235 INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
236 back() const {
237  nassertd((this->_void_ptr) != nullptr) {
238  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
239  }
240  nassertd(!((To *)(this->_void_ptr))->empty()) {
241  ((To *)(this->_void_ptr))->push_back(Element());
242  }
243  return ((To *)(this->_void_ptr))->back();
244 }
245 
246 /**
247  *
248  */
249 template<class Element>
250 INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
251 insert(iterator position, const Element &x) {
252  if ((this->_void_ptr) == nullptr) {
253  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
254  position = end();
255  }
256  nassertr(position >= ((To *)(this->_void_ptr))->begin() &&
257  position <= ((To *)(this->_void_ptr))->end(), position);
258  return ((To *)(this->_void_ptr))->insert(position, x);
259 }
260 
261 /**
262  *
263  */
264 template<class Element>
265 INLINE void PointerToArray<Element>::
266 insert(iterator position, size_type n, const Element &x) {
267  if ((this->_void_ptr) == nullptr) {
268  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
269  position = end();
270  }
271  nassertv(position >= ((To *)(this->_void_ptr))->begin() &&
272  position <= ((To *)(this->_void_ptr))->end());
273  ((To *)(this->_void_ptr))->insert(position, n, x);
274 }
275 
276 /**
277  *
278  */
279 template<class Element>
280 INLINE void PointerToArray<Element>::
281 erase(iterator position) {
282  nassertv((this->_void_ptr) != nullptr);
283  nassertv(position >= ((To *)(this->_void_ptr))->begin() &&
284  position <= ((To *)(this->_void_ptr))->end());
285  ((To *)(this->_void_ptr))->erase(position);
286 }
287 
288 /**
289  *
290  */
291 template<class Element>
292 INLINE void PointerToArray<Element>::
293 erase(iterator first, iterator last) {
294  nassertv((this->_void_ptr) != nullptr);
295  nassertv(first >= ((To *)(this->_void_ptr))->begin() && first <= ((To *)(this->_void_ptr))->end());
296  nassertv(last >= ((To *)(this->_void_ptr))->begin() && last <= ((To *)(this->_void_ptr))->end());
297  ((To *)(this->_void_ptr))->erase(first, last);
298 }
299 
300 #if !defined(WIN32_VC) && !defined(WIN64_VC)
301 /**
302  *
303  */
304 template<class Element>
305 INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
306 operator [](size_type n) const {
307  nassertd((this->_void_ptr) != nullptr) {
308  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
309  }
310  nassertd(!((To *)(this->_void_ptr))->empty()) {
311  ((To *)(this->_void_ptr))->push_back(Element());
312  }
313  nassertr(n < ((To *)(this->_void_ptr))->size(), ((To *)(this->_void_ptr))->operator[](0));
314  return ((To *)(this->_void_ptr))->operator[](n);
315 }
316 
317 /**
318  *
319  */
320 template<class Element>
321 INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
322 operator [](int n) const {
323  return operator[]((size_type)n);
324 }
325 #endif
326 
327 /**
328  *
329  */
330 template<class Element>
331 INLINE void PointerToArray<Element>::
332 push_back(const Element &x) {
333  if ((this->_void_ptr) == nullptr) {
334  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
335  }
336  ((To *)(this->_void_ptr))->push_back(x);
337 }
338 
339 /**
340  *
341  */
342 template<class Element>
343 INLINE void PointerToArray<Element>::
344 pop_back() {
345  nassertd((this->_void_ptr) != nullptr) {
346  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
347  }
348  nassertv(!((To *)(this->_void_ptr))->empty());
349  ((To *)(this->_void_ptr))->pop_back();
350 }
351 
352 /**
353  * Empties the array pointed to. This is different from clear(), which
354  * reassigns the pointer to a NULL pointer.
355  */
356 template<class Element>
357 INLINE void PointerToArray<Element>::
359  nassertd((this->_void_ptr) != nullptr) {
360  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
361  }
362  nassertv(!((To *)(this->_void_ptr))->empty());
363  ((To *)(this->_void_ptr))->clear();
364 }
365 
366 /**
367  * The pointer typecast operator is convenient for maintaining the fiction
368  * that we actually have a C-style array. It returns the address of the first
369  * element in the array, unless the pointer is unassigned, in which case it
370  * returns NULL.
371  */
372 template<class Element>
374 operator Element *() const {
375  To *vec = (To *)(this->_void_ptr);
376  return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
377 }
378 
379 /**
380  * Function p() is similar to the function from PointerTo. It does the same
381  * thing: it returns the same thing as the typecast operator, above.
382  */
383 template<class Element>
384 INLINE Element *PointerToArray<Element>::
385 p() const {
386  To *vec = (To *)(this->_void_ptr);
387  return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
388 }
389 
390 /**
391  * To access the vector itself, for more direct fiddling with some of the
392  * vector's esoteric functionality.
393  */
394 template<class Element>
396 v() const {
397  if ((this->_void_ptr) == nullptr) {
398  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
399  }
400  return *((To *)(this->_void_ptr));
401 }
402 
403 /**
404  * To access the internal ReferenceCountedVector object, for very low-level
405  * fiddling. Know what you are doing!
406  */
407 template<class Element>
409 v0() const {
410  return (To *)(this->_void_ptr);
411 }
412 
413 /**
414  * This method exists mainly to access the elements of the array easily from a
415  * high-level language such as Python, especially on Windows, where the above
416  * index element accessor methods can't be defined because of a confusion with
417  * the pointer typecast operator.
418  */
419 template<class Element>
420 INLINE const Element &PointerToArray<Element>::
421 get_element(size_type n) const {
422  return (*this)[n];
423 }
424 
425 /**
426  * This method exists mainly to access the elements of the array easily from a
427  * high-level language such as Python, especially on Windows, where the above
428  * index element accessor methods can't be defined because of a confusion with
429  * the pointer typecast operator.
430  */
431 template<class Element>
432 INLINE void PointerToArray<Element>::
433 set_element(size_type n, const Element &value) {
434  nassertv(n < ((To *)(this->_void_ptr))->size());
435  (*this)[n] = value;
436 }
437 
438 /**
439  * This method exists mainly to access the data of the array easily from a
440  * high-level language such as Python.
441  *
442  * It returns the entire contents of the vector as a block of raw data in a
443  * string.
444  */
445 template<class Element>
446 INLINE std::string PointerToArray<Element>::
447 get_data() const {
448  return get_subdata(0, size());
449 }
450 
451 /**
452  * This method exists mainly to access the data of the array easily from a
453  * high-level language such as Python.
454  *
455  * It replaces the entire contents of the vector from a block of raw data in a
456  * string.
457  */
458 template<class Element>
459 INLINE void PointerToArray<Element>::
460 set_data(const std::string &data) {
461  set_subdata(0, size(), data);
462 }
463 
464 /**
465  * This method exists mainly to access the data of the array easily from a
466  * high-level language such as Python.
467  *
468  * It returns the contents of a portion of the vector--from element (n)
469  * through element (n + count - 1)--as a block of raw data in a string.
470  */
471 template<class Element>
472 INLINE std::string PointerToArray<Element>::
473 get_subdata(size_type n, size_type count) const {
474  n = std::min(n, size());
475  count = std::max(count, n);
476  count = std::min(count, size() - n);
477  return std::string((const char *)(p() + n), sizeof(Element) * count);
478 }
479 
480 /**
481  * This method exists mainly to access the data of the array easily from a
482  * high-level language such as Python.
483  *
484  * It replaces the contents of a portion of the vector--from element (n)
485  * through element (n + count - 1)--as a block of raw data in a string. The
486  * length of the string must be an even multiple of Element size bytes. The
487  * array may be expanded or truncated if the length of the string does not
488  * correspond to exactly count elements.
489  */
490 template<class Element>
491 INLINE void PointerToArray<Element>::
492 set_subdata(size_type n, size_type count, const std::string &data) {
493  nassertv((data.length() % sizeof(Element)) == 0);
494  nassertv(n <= size() && n + count <= size());
495  if ((this->_void_ptr) == nullptr) {
496  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
497  }
498  size_type ncount = data.length() / sizeof(Element);
499  if (ncount < count) {
500  // Reduce the array.
501  erase(begin() + n + ncount, begin() + n + count);
502  } else if (count < ncount) {
503  // Expand the array.
504  insert(begin() + n + count, ncount - count, Element());
505  }
506 
507  // Now boldly replace the data. Hope there aren't any constructors or
508  // destructors involved here. The user better know what she is doing.
509  memcpy(p() + n, data.data(), sizeof(Element) * ncount);
510 }
511 
512 /**
513  * Returns the reference to memory where the vector is stored. To be used
514  * only with set_void_ptr
515  */
516 template<class Element>
517 INLINE void *PointerToArray<Element>::
518 get_void_ptr() const {
519  return (this->_void_ptr);
520 }
521 
522 /**
523  * Sets this PTA to point to the pointer passed in
524  */
525 template<class Element>
526 INLINE void PointerToArray<Element>::
527 set_void_ptr(void *p) {
528  ((PointerToArray<Element> *)this)->reassign((To *)p);
529 }
530 
531 /**
532  * Returns the reference count of the underlying vector.
533  */
534 template<class Element>
535 INLINE int PointerToArray<Element>::
536 get_ref_count() const {
537  return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_ref_count();
538 }
539 
540 /**
541  * Increments the reference count of the underlying vector.
542  */
543 template<class Element>
544 INLINE void PointerToArray<Element>::
545 ref() const {
546  if ((this->_void_ptr) == nullptr) {
547  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
548  }
549  ((To *)(this->_void_ptr))->ref();
550 }
551 
552 /**
553  * Decrements the reference count of the underlying vector.
554  */
555 template<class Element>
556 INLINE bool PointerToArray<Element>::
557 unref() const {
558  nassertr((this->_void_ptr) != nullptr, true);
559  return ((To *)(this->_void_ptr))->unref();
560 }
561 
562 /**
563  * Returns the node_ref of the underlying vector.
564  */
565 template<class Element>
566 INLINE int PointerToArray<Element>::
568  return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_node_ref_count();
569 }
570 
571 /**
572  * Increments the node_ref of the underlying vector.
573  */
574 template<class Element>
575 INLINE void PointerToArray<Element>::
576 node_ref() const {
577  if ((this->_void_ptr) == nullptr) {
578  ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
579  }
580  ((To *)(this->_void_ptr))->node_ref();
581 }
582 
583 /**
584  * Decrements the node_ref of the underlying vector.
585  */
586 template<class Element>
587 INLINE bool PointerToArray<Element>::
588 node_unref() const {
589  nassertr((this->_void_ptr) != nullptr, true);
590  return ((To *)(this->_void_ptr))->node_unref();
591 }
592 
593 /**
594  * Counts the frequency at which the given element occurs in the vector.
595  */
596 template<class Element>
597 INLINE size_t PointerToArray<Element>::
598 count(const Element &value) const {
599  if ((this->_void_ptr) != nullptr) {
600  return std::count(begin(), end(), value);
601  } else {
602  return 0;
603  }
604 }
605 
606 /**
607  *
608  */
609 template<class Element>
612  ((PointerToArray<Element> *)this)->reassign(ptr);
613  return *this;
614 }
615 
616 /**
617  *
618  */
619 template<class Element>
622  _type_handle = copy._type_handle;
623  ((PointerToArray<Element> *)this)->reassign(copy);
624  return *this;
625 }
626 
627 /**
628  *
629  */
630 template<class Element>
632 operator = (PointerToArray<Element> &&from) noexcept {
633  _type_handle = from._type_handle;
634  ((PointerToArray<Element> *)this)->reassign(std::move(from));
635  return *this;
636 }
637 
638 /**
639  * To empty the PTA, use the clear() method, since assignment to NULL is
640  * problematic (given the ambiguity of the pointer type of NULL).
641  */
642 template<class Element>
643 INLINE void PointerToArray<Element>::
644 clear() {
645  ((PointerToArray<Element> *)this)->reassign(nullptr);
646 }
647 
648 
649 
650 /**
651  *
652  */
653 template<class Element>
655 ConstPointerToArray(TypeHandle type_handle) :
656  PointerToArrayBase<Element>(nullptr),
657  _type_handle(type_handle)
658 {
659 }
660 
661 /**
662  * Initializes a ConstPointerToArray by copying existing elements.
663  */
664 template<class Element>
666 ConstPointerToArray(const Element *begin, const Element *end, TypeHandle type_handle) :
667  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(begin, end, type_handle)),
668  _type_handle(type_handle)
669 {
670 }
671 
672 /**
673  *
674  */
675 template<class Element>
678  PointerToArrayBase<Element>(copy),
679  _type_handle(copy._type_handle)
680 {
681 }
682 
683 /**
684  *
685  */
686 template<class Element>
689  PointerToArrayBase<Element>(copy),
690  _type_handle(copy._type_handle)
691 {
692 }
693 
694 /**
695  *
696  */
697 template<class Element>
700  PointerToArrayBase<Element>(std::move(from)),
701  _type_handle(from._type_handle)
702 {
703 }
704 
705 /**
706  *
707  */
708 template<class Element>
711  PointerToArrayBase<Element>(std::move(from)),
712  _type_handle(from._type_handle)
713 {
714 }
715 
716 /**
717  * Initializes the PTA from a vector.
718  */
719 template<class Element>
722  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(std::move(from))),
723  _type_handle(type_handle)
724 {
725 }
726 
727 /**
728  *
729  */
730 template<class Element>
731 INLINE typename ConstPointerToArray<Element>::iterator ConstPointerToArray<Element>::
732 begin() const {
733  if ((this->_void_ptr) == nullptr) {
734  return _empty_array.begin();
735  }
736  return ((To *)(this->_void_ptr))->begin();
737 }
738 
739 /**
740  *
741  */
742 template<class Element>
743 INLINE typename ConstPointerToArray<Element>::iterator ConstPointerToArray<Element>::
744 end() const {
745  if ((this->_void_ptr) == nullptr) {
746  return _empty_array.begin();
747  }
748  return ((To *)(this->_void_ptr))->end();
749 }
750 
751 /**
752  *
753  */
754 template<class Element>
755 INLINE typename ConstPointerToArray<Element>::reverse_iterator ConstPointerToArray<Element>::
756 rbegin() const {
757  if ((this->_void_ptr) == nullptr) {
758  return _empty_array.rbegin();
759  }
760  return ((To *)(this->_void_ptr))->rbegin();
761 }
762 
763 /**
764  *
765  */
766 template<class Element>
767 INLINE typename ConstPointerToArray<Element>::reverse_iterator ConstPointerToArray<Element>::
768 rend() const {
769  if ((this->_void_ptr) == nullptr) {
770  return _empty_array.rbegin();
771  }
772  return ((To *)(this->_void_ptr))->rend();
773 }
774 
775 /**
776  *
777  */
778 template<class Element>
779 INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
780 size() const {
781  return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->size();
782 }
783 
784 /**
785  *
786  */
787 template<class Element>
788 INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
789 max_size() const {
790  nassertd((this->_void_ptr) != nullptr) {
791  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
792  }
793  return ((To *)(this->_void_ptr))->max_size();
794 }
795 
796 /**
797  *
798  */
799 template<class Element>
801 empty() const {
802  return ((this->_void_ptr) == nullptr) ? true : ((To *)(this->_void_ptr))->empty();
803 }
804 
805 /**
806  *
807  */
808 template<class Element>
809 INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
810 capacity() const {
811  nassertd((this->_void_ptr) != nullptr) {
812  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
813  }
814  return ((To *)(this->_void_ptr))->capacity();
815 }
816 
817 /**
818  *
819  */
820 template<class Element>
821 INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
822 front() const {
823  nassertd((this->_void_ptr) != nullptr) {
824  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
825  }
826  nassertd(!((To *)(this->_void_ptr))->empty()) {
827  ((To *)(this->_void_ptr))->push_back(Element());
828  }
829  return ((To *)(this->_void_ptr))->front();
830 }
831 
832 /**
833  *
834  */
835 template<class Element>
836 INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
837 back() const {
838  nassertd((this->_void_ptr) != nullptr) {
839  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
840  }
841  nassertd(!((To *)(this->_void_ptr))->empty()) {
842  ((To *)(this->_void_ptr))->push_back(Element());
843  }
844  return ((To *)(this->_void_ptr))->back();
845 }
846 
847 #if !defined(WIN32_VC) && !defined(WIN64_VC)
848 /**
849  *
850  */
851 template<class Element>
852 INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
853 operator [](size_type n) const {
854  nassertd((this->_void_ptr) != nullptr) {
855  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
856  }
857  nassertd(!((To *)(this->_void_ptr))->empty()) {
858  ((To *)(this->_void_ptr))->push_back(Element());
859  }
860  nassertr(n < ((To *)(this->_void_ptr))->size(), ((To *)(this->_void_ptr))->operator[](0));
861  return ((To *)(this->_void_ptr))->operator[](n);
862 }
863 
864 /**
865  *
866  */
867 template<class Element>
868 INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
869 operator [](int n) const {
870  return operator[]((size_type)n);
871 }
872 #endif
873 
874 /**
875  * The pointer typecast operator is convenient for maintaining the fiction
876  * that we actually have a C-style array. It returns the address of the first
877  * element in the array, unless the pointer is unassigned, in which case it
878  * returns NULL.
879  */
880 template<class Element>
882 operator const Element *() const {
883  const To *vec = (const To *)(this->_void_ptr);
884  return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
885 }
886 
887 /**
888  * Function p() is similar to the function from ConstPointerTo. It does the
889  * same thing: it returns the same thing as the typecast operator, above.
890  */
891 template<class Element>
892 INLINE const Element *ConstPointerToArray<Element>::
893 p() const {
894  const To *vec = (const To *)(this->_void_ptr);
895  return ((vec == nullptr)||(vec->empty())) ? nullptr : &(vec->front());
896 }
897 
898 /**
899  * To access the vector itself, for more direct fiddling with some of the
900  * vector's esoteric functionality.
901  */
902 template<class Element>
904 v() const {
905  nassertd((this->_void_ptr) != nullptr) {
906  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
907  }
908  return *(const To *)(this->_void_ptr);
909 }
910 
911 /**
912  * To access the internal ReferenceCountedVector object, for very low-level
913  * fiddling. Know what you are doing!
914  */
915 template<class Element>
917 v0() const {
918  return (const To *)(this->_void_ptr);
919 }
920 
921 /**
922  * Casts away the constness of the CPTA(Element), and returns an equivalent
923  * PTA(Element).
924  */
925 template<class Element>
927 cast_non_const() const {
928  PointerToArray<Element> non_const;
929  non_const = (To *)(this->_void_ptr);
930  return non_const;
931 }
932 
933 /**
934  * This method exists mainly to access the elements of the array easily from a
935  * high-level language such as Python, especially on Windows, where the above
936  * index element accessor methods can't be defined because of a confusion with
937  * the pointer typecast operator.
938  */
939 template<class Element>
940 INLINE const Element &ConstPointerToArray<Element>::
941 get_element(size_type n) const {
942  return (*this)[n];
943 }
944 
945 /**
946  * This method exists mainly to access the data of the array easily from a
947  * high-level language such as Python.
948  *
949  * It returns the entire contents of the vector as a block of raw data in a
950  * string.
951  */
952 template<class Element>
953 INLINE std::string ConstPointerToArray<Element>::
954 get_data() const {
955  return get_subdata(0, size());
956 }
957 
958 /**
959  * This method exists mainly to access the data of the array easily from a
960  * high-level language such as Python.
961  *
962  * It returns the contents of a portion of the vector--from element (n)
963  * through element (n + count - 1)--as a block of raw data in a string.
964  */
965 template<class Element>
966 INLINE std::string ConstPointerToArray<Element>::
967 get_subdata(size_type n, size_type count) const {
968  n = std::min(n, size());
969  count = std::max(count, n);
970  count = std::min(count, size() - n);
971  return std::string((const char *)(p() + n), sizeof(Element) * count);
972 }
973 
974 /**
975  * Returns the reference count of the underlying vector.
976  */
977 template<class Element>
979 get_ref_count() const {
980  return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_ref_count();
981 }
982 
983 /**
984  * Increments the reference count of the underlying vector.
985  */
986 template<class Element>
988 ref() const {
989  if ((this->_void_ptr) == nullptr) {
990  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
991  }
992  ((To *)(this->_void_ptr))->ref();
993 }
994 
995 /**
996  * Decrements the reference count of the underlying vector.
997  */
998 template<class Element>
1000 unref() const {
1001  nassertr((this->_void_ptr) != nullptr, true);
1002  return ((To *)(this->_void_ptr))->unref();
1003 }
1004 
1005 /**
1006  * Returns the node_ref of the underlying vector.
1007  */
1008 template<class Element>
1011  return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->get_node_ref_count();
1012 }
1013 
1014 /**
1015  * Increments the node_ref of the underlying vector.
1016  */
1017 template<class Element>
1019 node_ref() const {
1020  if ((this->_void_ptr) == nullptr) {
1021  ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
1022  }
1023  ((To *)(this->_void_ptr))->node_ref();
1024 }
1025 
1026 /**
1027  * Decrements the node_ref of the underlying vector.
1028  */
1029 template<class Element>
1031 node_unref() const {
1032  nassertr((this->_void_ptr) != nullptr, true);
1033  return ((To *)(this->_void_ptr))->node_unref();
1034 }
1035 
1036 /**
1037  * Counts the frequency at which the given element occurs in the vector.
1038  */
1039 template<class Element>
1040 INLINE size_t ConstPointerToArray<Element>::
1041 count(const Element &value) const {
1042  if ((this->_void_ptr) != nullptr) {
1043  return std::count(begin(), end(), value);
1044  } else {
1045  return 0;
1046  }
1047 }
1048 
1049 /**
1050  *
1051  */
1052 template<class Element>
1055  ((ConstPointerToArray<Element> *)this)->reassign(ptr);
1056  return *this;
1057 }
1058 
1059 /**
1060  *
1061  */
1062 template<class Element>
1064 operator = (const PointerToArray<Element> &copy) {
1065  _type_handle = copy._type_handle;
1066  ((ConstPointerToArray<Element> *)this)->reassign(copy);
1067  return *this;
1068 }
1069 
1070 /**
1071  *
1072  */
1073 template<class Element>
1076  _type_handle = copy._type_handle;
1077  ((ConstPointerToArray<Element> *)this)->reassign(copy);
1078  return *this;
1079 }
1080 
1081 /**
1082  *
1083  */
1084 template<class Element>
1086 operator = (PointerToArray<Element> &&from) noexcept {
1087  _type_handle = from._type_handle;
1088  ((ConstPointerToArray<Element> *)this)->reassign(std::move(from));
1089  return *this;
1090 }
1091 
1092 /**
1093  *
1094  */
1095 template<class Element>
1097 operator = (ConstPointerToArray<Element> &&from) noexcept {
1098  _type_handle = from._type_handle;
1099  ((ConstPointerToArray<Element> *)this)->reassign(std::move(from));
1100  return *this;
1101 }
1102 
1103 /**
1104  * To empty the PTA, use the clear() method, since assignment to NULL is
1105  * problematic (given the ambiguity of the pointer type of NULL).
1106  */
1107 template<class Element>
1110  ((ConstPointerToArray<Element> *)this)->reassign(nullptr);
1111 }
1112 
1113 #endif // CPPPARSER
ConstPointerToArray::get_element
const Element & get_element(size_type n) const
This method exists mainly to access the elements of the array easily from a high-level language such ...
Definition: pointerToArray.I:941
PointerToArray::ref
void ref() const
Increments the reference count of the underlying vector.
Definition: pointerToArray.I:545
ConstPointerToArray::get_subdata
std::string get_subdata(size_type n, size_type count) const
This method exists mainly to access the data of the array easily from a high-level language such as P...
Definition: pointerToArray.I:967
pvector< Element >
PointerToArray::count
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
Definition: pointerToArray.I:598
ConstPointerToArray::count
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
Definition: pointerToArray.I:1041
ConstPointerToArray::unref
bool unref() const
Decrements the reference count of the underlying vector.
Definition: pointerToArray.I:1000
PointerToArray::set_data
void set_data(const std::string &data)
This method exists mainly to access the data of the array easily from a high-level language such as P...
Definition: pointerToArray.I:460
PointerToArrayBase
This is the base class for PointerToArray and ConstPointerToArray.
Definition: pointerToArrayBase.h:69
PointerToArray::get_element
const Element & get_element(size_type n) const
This method exists mainly to access the elements of the array easily from a high-level language such ...
Definition: pointerToArray.I:421
ConstPointerToArray
Similar to PointerToArray, except that its contents may not be modified.
Definition: pointerToArray.h:71
PointerToArray::node_unref
bool node_unref() const
Decrements the node_ref of the underlying vector.
Definition: pointerToArray.I:588
ConstPointerToArray::clear
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
Definition: pointerToArray.I:1109
PointerToArray::set_element
void set_element(size_type n, const Element &value)
This method exists mainly to access the elements of the array easily from a high-level language such ...
Definition: pointerToArray.I:433
PointerToArray::p
Element * p() const
Function p() is similar to the function from PointerTo.
Definition: pointerToArray.I:385
ConstPointerToArray::ref
void ref() const
Increments the reference count of the underlying vector.
Definition: pointerToArray.I:988
PointerToArray::get_ref_count
int get_ref_count() const
Returns the reference count of the underlying vector.
Definition: pointerToArray.I:536
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PointerToArray::get_node_ref_count
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
Definition: pointerToArray.I:567
ConstPointerToArray::node_ref
void node_ref() const
Increments the node_ref of the underlying vector.
Definition: pointerToArray.I:1019
PointerToArray::empty_array
static PointerToArray< Element > empty_array(size_type n, TypeHandle type_handle=get_type_handle(Element))
Return an empty array of size n.
Definition: pointerToArray.I:38
PointerToVoid::swap
void swap(PointerToVoid &other) noexcept
Swaps the contents of this PointerTo with the other, without touching the reference counts.
Definition: pointerToVoid.I:78
PointerToArray::v0
ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
Definition: pointerToArray.I:409
PointerToArray::v
pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
Definition: pointerToArray.I:396
PointerToArray::unref
bool unref() const
Decrements the reference count of the underlying vector.
Definition: pointerToArray.I:557
ConstPointerToArray::get_ref_count
int get_ref_count() const
Returns the reference count of the underlying vector.
Definition: pointerToArray.I:979
ConstPointerToArray::node_unref
bool node_unref() const
Decrements the node_ref of the underlying vector.
Definition: pointerToArray.I:1031
PointerToArray::make_empty
void make_empty()
Empties the array pointed to.
Definition: pointerToArray.I:358
ConstPointerToArray::v
const pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
Definition: pointerToArray.I:904
PointerToArray::node_ref
void node_ref() const
Increments the node_ref of the underlying vector.
Definition: pointerToArray.I:576
PointerToArray::get_data
std::string get_data() const
This method exists mainly to access the data of the array easily from a high-level language such as P...
Definition: pointerToArray.I:447
ConstPointerToArray::cast_non_const
PointerToArray< Element > cast_non_const() const
Casts away the constness of the CPTA(Element), and returns an equivalent PTA(Element).
Definition: pointerToArray.I:927
PointerToArray::set_void_ptr
void set_void_ptr(void *p)
Sets this PTA to point to the pointer passed in.
Definition: pointerToArray.I:527
ConstPointerToArray::v0
const ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
Definition: pointerToArray.I:917
ConstPointerToArray::p
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
Definition: pointerToArray.I:893
PointerToArray::set_subdata
void set_subdata(size_type n, size_type count, const std::string &data)
This method exists mainly to access the data of the array easily from a high-level language such as P...
Definition: pointerToArray.I:492
ConstPointerToArray::get_data
std::string get_data() const
This method exists mainly to access the data of the array easily from a high-level language such as P...
Definition: pointerToArray.I:954
PointerToArray
A special kind of PointerTo that stores an array of the indicated element type, instead of a single e...
Definition: pointerToArray.h:87
PointerToArray::clear
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
Definition: pointerToArray.I:644
ReferenceCountedVector
This defines the object that is actually stored and reference-counted internally by a PointerToArray.
Definition: pointerToArrayBase.h:38
ConstPointerToArray::get_node_ref_count
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
Definition: pointerToArray.I:1010
PointerToArray::get_void_ptr
void * get_void_ptr() const
Returns the reference to memory where the vector is stored.
Definition: pointerToArray.I:518
PointerToArray::get_subdata
std::string get_subdata(size_type n, size_type count) const
This method exists mainly to access the data of the array easily from a high-level language such as P...
Definition: pointerToArray.I:473