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
Element * p() const
Function p() is similar to the function from PointerTo.
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...
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
void node_ref() const
Increments the node_ref of the underlying vector.
void * get_void_ptr() const
Returns the reference to memory where the vector is stored.
int get_ref_count() const
Returns the reference count of the underlying vector.
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 ...
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 ...
bool node_unref() const
Decrements the node_ref of the underlying vector.
A special kind of PointerTo that stores an array of the indicated element type, instead of a single e...
static PointerToArray< Element > empty_array(size_type n, TypeHandle type_handle=get_type_handle(Element))
Return an empty array of size n.
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...
ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
void make_empty()
Empties the array pointed to.
void set_void_ptr(void *p)
Sets this PTA to point to the pointer passed in.
void swap(PointerToVoid &other) noexcept
Swaps the contents of this PointerTo with the other, without touching the reference counts.
Definition: pointerToVoid.I:78
void ref() const
Increments the reference count of the underlying vector.
PointerToArray< Element > cast_non_const() const
Casts away the constness of the CPTA(Element), and returns an equivalent PTA(Element).
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...
const pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
void node_ref() const
Increments the node_ref of the underlying vector.
bool unref() const
Decrements the reference count of the underlying vector.
This is the base class for PointerToArray and ConstPointerToArray.
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
int get_ref_count() const
Returns the reference count of the underlying vector.
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
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...
const ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
This defines the object that is actually stored and reference-counted internally by a PointerToArray.
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
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...
void ref() const
Increments the reference count of the underlying vector.
Similar to PointerToArray, except that its contents may not be modified.
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 ...
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...
bool node_unref() const
Decrements the node_ref of the underlying vector.
bool unref() const
Decrements the reference count of the underlying vector.