Panda3D
Loading...
Searching...
No Matches
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
16template<class Element>
18
19template<class Element>
21
22/**
23 *
24 */
25template<class Element>
27PointerToArray(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 */
36template<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 */
50template<class Element>
52PointerToArray(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 */
63template<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 */
74template<class Element>
76PointerToArray(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 */
85template<class Element>
88 PointerToArrayBase<Element>(std::move(from)),
89 _type_handle(from._type_handle)
90{
91}
92
93/**
94 * Initializes the PTA from a vector.
95 */
96template<class Element>
98PointerToArray(pvector<Element> &&from, TypeHandle type_handle) :
99 PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(std::move(from))),
100 _type_handle(type_handle)
101{
102}
103
104/**
105 *
106 */
107template<class Element>
108INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
109begin() 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 */
119template<class Element>
120INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
121end() 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 */
131template<class Element>
132INLINE typename PointerToArray<Element>::reverse_iterator PointerToArray<Element>::
133rbegin() 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 */
143template<class Element>
144INLINE typename PointerToArray<Element>::reverse_iterator PointerToArray<Element>::
145rend() 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 */
155template<class Element>
156INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
157size() const {
158 return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->size();
159}
160
161/**
162 *
163 */
164template<class Element>
165INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
166max_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 */
176template<class Element>
178empty() const {
179 return ((this->_void_ptr) == nullptr) ? true : ((To *)(this->_void_ptr))->empty();
180}
181
182/**
183 *
184 */
185template<class Element>
187reserve(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 */
197template<class Element>
199resize(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 */
209template<class Element>
210INLINE typename PointerToArray<Element>::size_type PointerToArray<Element>::
211capacity() const {
212 nassertr((this->_void_ptr) != nullptr, 0);
213 return ((To *)(this->_void_ptr))->capacity();
214}
215
216/**
217 *
218 */
219template<class Element>
220INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
221front() 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 */
234template<class Element>
235INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
236back() 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 */
249template<class Element>
250INLINE typename PointerToArray<Element>::iterator PointerToArray<Element>::
251insert(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 */
264template<class Element>
266insert(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 */
279template<class Element>
281erase(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 */
291template<class Element>
293erase(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 */
304template<class Element>
305INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
306operator [](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 */
320template<class Element>
321INLINE typename PointerToArray<Element>::reference PointerToArray<Element>::
322operator [](int n) const {
323 return operator[]((size_type)n);
324}
325#endif
326
327/**
328 *
329 */
330template<class Element>
332push_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/**
341 */
342template<class Element>
344pop_back() {
345 nassertd((this->_void_ptr) != nullptr) {
346 ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
348 nassertv(!((To *)(this->_void_ptr))->empty());
349 ((To *)(this->_void_ptr))->pop_back();
352/**
353 * Empties the array pointed to. This is different from clear(), which
354 * reassigns the pointer to a NULL pointer.
355 */
356template<class 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 */
372template<class Element>
374operator 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 */
383template<class Element>
385p() 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 */
394template<class Element>
396v() 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 */
407template<class Element>
409v0() 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 */
419template<class Element>
420INLINE const Element &PointerToArray<Element>::
421get_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 */
431template<class Element>
433set_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 */
445template<class Element>
447get_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 */
458template<class Element>
460set_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 */
471template<class Element>
473get_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 */
490template<class Element>
492set_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 */
516template<class Element>
518get_void_ptr() const {
519 return (this->_void_ptr);
520}
521
522/**
523 * Sets this PTA to point to the pointer passed in
524 */
525template<class Element>
527set_void_ptr(void *p) {
528 ((PointerToArray<Element> *)this)->reassign((To *)p);
529}
530
531/**
532 * Returns the reference count of the underlying vector.
533 */
534template<class Element>
536get_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 */
543template<class Element>
545ref() 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 */
555template<class Element>
557unref() 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 */
565template<class Element>
567get_node_ref_count() const {
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 */
574template<class Element>
576node_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 */
586template<class Element>
588node_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 */
596template<class Element>
598count(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 */
609template<class Element>
612 ((PointerToArray<Element> *)this)->reassign(ptr);
613 return *this;
614}
615
616/**
617 *
618 */
619template<class Element>
622 _type_handle = copy._type_handle;
623 ((PointerToArray<Element> *)this)->reassign(copy);
624 return *this;
625}
626
627/**
628 *
629 */
630template<class Element>
632operator = (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 */
642template<class Element>
644clear() {
645 ((PointerToArray<Element> *)this)->reassign(nullptr);
646}
647
648
649
650/**
651 *
652 */
653template<class Element>
655ConstPointerToArray(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 */
664template<class Element>
666ConstPointerToArray(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 */
675template<class Element>
678 PointerToArrayBase<Element>(copy),
679 _type_handle(copy._type_handle)
680{
681}
682
683/**
684 *
685 */
686template<class Element>
689 PointerToArrayBase<Element>(copy),
690 _type_handle(copy._type_handle)
691{
692}
693
694/**
695 *
696 */
697template<class Element>
700 PointerToArrayBase<Element>(std::move(from)),
701 _type_handle(from._type_handle)
702{
703}
704
705/**
706 *
707 */
708template<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 */
719template<class Element>
722 PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(std::move(from))),
723 _type_handle(type_handle)
724{
725}
726
727/**
728 *
729 */
730template<class Element>
731INLINE typename ConstPointerToArray<Element>::iterator ConstPointerToArray<Element>::
732begin() 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 */
742template<class Element>
743INLINE typename ConstPointerToArray<Element>::iterator ConstPointerToArray<Element>::
744end() 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 */
754template<class Element>
755INLINE typename ConstPointerToArray<Element>::reverse_iterator ConstPointerToArray<Element>::
756rbegin() 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 */
766template<class Element>
767INLINE typename ConstPointerToArray<Element>::reverse_iterator ConstPointerToArray<Element>::
768rend() 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 */
778template<class Element>
779INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
780size() const {
781 return ((this->_void_ptr) == nullptr) ? 0 : ((To *)(this->_void_ptr))->size();
782}
783
784/**
785 *
786 */
787template<class Element>
788INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
789max_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 */
799template<class Element>
801empty() const {
802 return ((this->_void_ptr) == nullptr) ? true : ((To *)(this->_void_ptr))->empty();
803}
804
805/**
806 *
807 */
808template<class Element>
809INLINE typename ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
810capacity() 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 */
820template<class Element>
821INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
822front() 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 */
835template<class Element>
836INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
837back() 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 */
851template<class Element>
852INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
853operator [](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 */
867template<class Element>
868INLINE typename ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
869operator [](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 */
880template<class Element>
882operator 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 */
891template<class Element>
893p() 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 */
902template<class Element>
904v() 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 */
915template<class Element>
917v0() 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 */
925template<class Element>
927cast_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 */
939template<class Element>
941get_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 */
952template<class Element>
954get_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 */
965template<class Element>
967get_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 */
977template<class Element>
979get_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 */
986template<class Element>
988ref() 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 */
998template<class Element>
1000unref() 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 */
1008template<class Element>
1010get_node_ref_count() const {
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 */
1017template<class Element>
1019node_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 */
1029template<class Element>
1031node_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 */
1039template<class Element>
1041count(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 */
1052template<class Element>
1055 ((ConstPointerToArray<Element> *)this)->reassign(ptr);
1056 return *this;
1057}
1058
1059/**
1060 *
1061 */
1062template<class Element>
1065 _type_handle = copy._type_handle;
1066 ((ConstPointerToArray<Element> *)this)->reassign(copy);
1067 return *this;
1068}
1069
1070/**
1071 *
1072 */
1073template<class Element>
1076 _type_handle = copy._type_handle;
1077 ((ConstPointerToArray<Element> *)this)->reassign(copy);
1078 return *this;
1079}
1080
1081/**
1082 *
1083 */
1084template<class Element>
1086operator = (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 */
1095template<class Element>
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 */
1107template<class Element>
1109clear() {
1110 ((ConstPointerToArray<Element> *)this)->reassign(nullptr);
1111}
1112
1113#endif // CPPPARSER
Similar to PointerToArray, except that its contents may not be modified.
int get_ref_count() const
Returns the reference count of the underlying vector.
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...
bool node_unref() const
Decrements the node_ref of the underlying vector.
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
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.
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
void node_ref() const
Increments the node_ref of the underlying vector.
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
const pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
bool unref() const
Decrements 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 ...
PointerToArray< Element > cast_non_const() const
Casts away the constness of the CPTA(Element), and returns an equivalent PTA(Element).
void ref() const
Increments the reference count of the underlying vector.
This is the base class for PointerToArray and ConstPointerToArray.
A special kind of PointerTo that stores an array of the indicated element type, instead of a single e...
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...
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
void set_void_ptr(void *p)
Sets this PTA to point to the pointer passed in.
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...
int get_ref_count() const
Returns the reference count of the underlying vector.
static PointerToArray< Element > empty_array(size_type n, TypeHandle type_handle=get_type_handle(Element))
Return an empty array of size n.
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...
ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
int get_node_ref_count() const
Returns the node_ref 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 clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
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 ...
void * get_void_ptr() const
Returns the reference to memory where the vector is stored.
void ref() const
Increments the reference count of the underlying vector.
void make_empty()
Empties the array pointed to.
bool unref() const
Decrements the reference count of the underlying vector.
Element * p() const
Function p() is similar to the function from PointerTo.
bool node_unref() const
Decrements the node_ref of the underlying vector.
void node_ref() const
Increments the node_ref of the underlying vector.
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...
This defines the object that is actually stored and reference-counted internally by a PointerToArray.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
STL namespace.