Panda3D
 All Classes Functions Variables Enumerations
pointerToArray.h
1 // Filename: pointerToArray.h
2 // Created by: drose (14Jan99)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef POINTERTOARRAY_H
16 #define POINTERTOARRAY_H
17 
18 
19 ////////////////////////////////////////////////////////////////////
20 //
21 // This file defines the classes PointerToArray and
22 // ConstPointerToArray (and their abbreviations, PTA and CPTA), which
23 // are extensions to the PointerTo class that support
24 // reference-counted arrays.
25 //
26 // You may think of a PointerToArray as the same thing as a
27 // traditional C-style array. However, it actually stores a pointer
28 // to an STL vector, which is then reference-counted. Thus, most
29 // vector operations may be applied directly to a PointerToArray
30 // object, including dynamic resizing via push_back() and pop_back().
31 //
32 // Unlike the PointerTo class, the PointerToArray may store pointers
33 // to any kind of object, not just those derived from ReferenceCount.
34 //
35 // Like PointerTo and ConstPointerTo, the macro abbreviations PTA and
36 // CPTA are defined for convenience.
37 //
38 // Some examples of syntax: instead of:
39 //
40 // PTA(int) array(10); int *array = new int[10];
41 // memset(array, 0, sizeof(int) * 10); memset(array, 0, sizeof(int) * 10);
42 // array[i] = array[i+1]; array[i] = array[i+1];
43 // num_elements = array.size(); (no equivalent)
44 //
45 // PTA(int) copy = array; int *copy = array;
46 //
47 // Note that in the above example, unlike an STL vector (but like a
48 // C-style array), assigning a PointerToArray object from another
49 // simply copies the pointer, and does not copy individual elements.
50 // (Of course, reference counts are adjusted appropriately7.) If you
51 // actually wanted an element-by-element copy of the array, you would
52 // do this:
53 //
54 // PTA(int) copy(0); // Create a pointer to an empty vector.
55 // copy.v() = array.v(); // v() is the STL vector itself.
56 //
57 // The (0) parameter to the constructor in the above example is
58 // crucial. When a numeric length parameter, such as zero, is given
59 // to the constructor, it means to define a new STL vector with that
60 // number of elements initially in it. If no parameter is given, on
61 // the other hand, it means the PointerToArray should point to
62 // nothing--no STL vector is created. This is equivalent to a C array
63 // that points to NULL.
64 //
65 ////////////////////////////////////////////////////////////////////
66 
67 #include "pandabase.h"
68 
69 #include "pointerToArrayBase.h"
70 
71 #if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(__INTEL_COMPILER)
72 // disable mysterious MSVC warning for static inline PTA::empty_array method
73 // need to chk if vc 7.0 still has this problem, would like to keep it enabled
74 #pragma warning (disable : 4506)
75 #endif
76 
77 template <class Element>
79 
80 ////////////////////////////////////////////////////////////////////
81 // Class : PointerToArray
82 // Description : A special kind of PointerTo that stores an array of
83 // the indicated element type, instead of a single
84 // element. This is actually implemented as an STL
85 // vector, using the RefCountObj class to wrap it up
86 // with a reference count.
87 //
88 // We actually inherit from NodeRefCountObj these days,
89 // which adds node_ref() and node_unref() to the
90 // standard ref() and unref(). This is particularly
91 // useful for GeomVertexArrayData; other classes may or
92 // may not find this additional counter useful, but
93 // since it adds relatively little overhead (compared
94 // with what is presumably a largish array), we go ahead
95 // and add it here, even though it is inherited by many
96 // different parts of the system that may not use it.
97 ////////////////////////////////////////////////////////////////////
98 template <class Element>
99 class PointerToArray : public PointerToArrayBase<Element> {
100 public:
101  // By hiding this template from interrogate, we would improve
102  // compile-time speed and memory utilization. However, we do want
103  // to export a minimal subset of this class. So we define just the
104  // exportable interface here.
105 #ifdef CPPPARSER
106 PUBLISHED:
107  typedef TYPENAME pvector<Element>::size_type size_type;
108  INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
109  INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
110  INLINE PointerToArray(const PointerToArray<Element> &copy);
111 
112  EXTENSION(PointerToArray(PyObject *self, PyObject *source));
113 
114  INLINE size_type size() const;
115  INLINE void push_back(const Element &x);
116  INLINE void pop_back();
117  INLINE const Element &get_element(size_type n) const;
118  INLINE void set_element(size_type n, const Element &value);
119  EXTENSION(const Element &__getitem__(size_type n) const);
120  EXTENSION(void __setitem__(size_type n, const Element &value));
121  INLINE string get_data() const;
122  INLINE void set_data(const string &data);
123  INLINE string get_subdata(size_type n, size_type count) const;
124  INLINE void set_subdata(size_type n, size_type count, const string &data);
125  INLINE int get_ref_count() const;
126  INLINE int get_node_ref_count() const;
127 
128 #ifdef HAVE_PYTHON
129 #if PY_VERSION_HEX >= 0x02060000
130  EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
131  EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
132 #endif
133 #endif
134 
135 #else // CPPPARSER
136  // This is the actual, complete interface.
137  typedef TYPENAME PointerToArrayBase<Element>::To To;
138  typedef TYPENAME pvector<Element>::value_type value_type;
139  typedef TYPENAME pvector<Element>::reference reference;
140  typedef TYPENAME pvector<Element>::const_reference const_reference;
141  typedef TYPENAME pvector<Element>::iterator iterator;
142  typedef TYPENAME pvector<Element>::const_iterator const_iterator;
143  typedef TYPENAME pvector<Element>::reverse_iterator reverse_iterator;
144  typedef TYPENAME pvector<Element>::const_reverse_iterator const_reverse_iterator;
145  typedef TYPENAME pvector<Element>::difference_type difference_type;
146  typedef TYPENAME pvector<Element>::size_type size_type;
147 
148 public:
149  INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
150  INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
151  INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
152  INLINE PointerToArray(const PointerToArray<Element> &copy);
153 
154 #ifdef USE_MOVE_SEMANTICS
155  INLINE PointerToArray(PointerToArray<Element> &&from) NOEXCEPT;
156 #endif
157 
158 public:
159  // Duplicating the interface of vector. The following member
160  // functions are all const, because they do not reassign the
161  // pointer--they operate only within the vector itself, which is
162  // non-const in this class.
163 
164  INLINE iterator begin() const;
165  INLINE iterator end() const;
166  INLINE TYPENAME PointerToArray<Element>::reverse_iterator rbegin() const;
167  INLINE TYPENAME PointerToArray<Element>::reverse_iterator rend() const;
168 
169  // Equality and comparison operators are pointerwise for
170  // PointerToArrays, not elementwise as in vector.
171  INLINE size_type size() const;
172  INLINE size_type max_size() const;
173  INLINE bool empty() const;
174 
175  // Functions specific to vectors.
176  INLINE void reserve(size_type n);
177  INLINE void resize(size_type n);
178  INLINE size_type capacity() const;
179  INLINE reference front() const;
180  INLINE reference back() const;
181  INLINE iterator insert(iterator position, const Element &x);
182  INLINE void insert(iterator position, size_type n, const Element &x);
183 
184  // We don't define the insert() method that accepts a pair of
185  // iterators to copy from. That's problematic because of the whole
186  // member template thing. If you really need this, use
187  // pta.v().insert(...); if you're doing this on a vector that has to
188  // be exported from the DLL, you should use
189  // insert_into_vector(pta.v(), ...).
190 
191  INLINE void erase(iterator position);
192  INLINE void erase(iterator first, iterator last);
193 
194 #if !defined(WIN32_VC) && !defined (WIN64_VC)
195  INLINE reference operator [](size_type n) const;
196  INLINE reference operator [](int n) const;
197 #endif
198 
199  INLINE void push_back(const Element &x);
200  INLINE void pop_back();
201  INLINE void make_empty();
202 
203  INLINE operator Element *() const;
204  INLINE Element *p() const;
205  INLINE pvector<Element> &v() const;
206  INLINE ReferenceCountedVector<Element> *v0() const;
207 
208  // Methods to help out Python and other high-level languages.
209  INLINE const Element &get_element(size_type n) const;
210  INLINE void set_element(size_type n, const Element &value);
211  INLINE string get_data() const;
212  INLINE void set_data(const string &data);
213  INLINE string get_subdata(size_type n, size_type count) const;
214  INLINE void set_subdata(size_type n, size_type count, const string &data);
215 
216  //These functions are only to be used in Reading through BamReader.
217  //They are designed to work in pairs, so that you register what is
218  //returned by get_void_ptr with BamReader and when you are setting
219  //another PTA with what is returned by BamReader, you set it with
220  //set_void_ptr. If you used the provided macro of READ_PTA, this is
221  //done for you. So you should never call these functions directly
222  INLINE void *get_void_ptr() const;
223  INLINE void set_void_ptr(void* p);
224 
225  INLINE int get_ref_count() const;
226  INLINE void ref() const;
227  INLINE bool unref() const;
228 
229  INLINE int get_node_ref_count() const;
230  INLINE void node_ref() const;
231  INLINE bool node_unref() const;
232 
233  // Reassignment is by pointer, not memberwise as with a vector.
234  INLINE PointerToArray<Element> &
235  operator = (ReferenceCountedVector<Element> *ptr);
236  INLINE PointerToArray<Element> &
237  operator = (const PointerToArray<Element> &copy);
238 
239 #ifdef USE_MOVE_SEMANTICS
240  INLINE PointerToArray<Element> &
241  operator = (PointerToArray<Element> &&from) NOEXCEPT;
242 #endif
243 
244  INLINE void clear();
245 
246 private:
247  TypeHandle _type_handle;
248 
249 private:
250  // This static empty array is kept around just so we can return
251  // something meaningful when begin() or end() is called and we have a
252  // NULL pointer. It might not be shared properly between different
253  // .so's, since it's a static member of a template class, but we
254  // don't really care.
255  static pvector<Element> _empty_array;
256 #endif // CPPPARSER
257 
258  friend class ConstPointerToArray<Element>;
259 };
260 
261 ////////////////////////////////////////////////////////////////////
262 // Class : ConstPointerToArray
263 // Description : Similar to PointerToArray, except that its contents
264 // may not be modified.
265 ////////////////////////////////////////////////////////////////////
266 template <class Element>
267 class ConstPointerToArray : public PointerToArrayBase<Element> {
268 public:
269  // By hiding this template from interrogate, we would improve
270  // compile-time speed and memory utilization. However, we do want
271  // to export a minimal subset of this class. So we define just the
272  // exportable interface here.
273 #ifdef CPPPARSER
274 PUBLISHED:
275  INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
277 
278  EXTENSION(ConstPointerToArray(PyObject *self, PyObject *source));
279 
280  typedef TYPENAME pvector<Element>::size_type size_type;
281  INLINE size_type size() const;
282  INLINE const Element &get_element(size_type n) const;
283  EXTENSION(const Element &__getitem__(size_type n) const);
284  INLINE string get_data() const;
285  INLINE string get_subdata(size_type n, size_type count) const;
286  INLINE int get_ref_count() const;
287  INLINE int get_node_ref_count() const;
288 
289 #ifdef HAVE_PYTHON
290 #if PY_VERSION_HEX >= 0x02060000
291  EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
292  EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
293 #endif
294 #endif
295 
296 #else // CPPPARSER
297  // This is the actual, complete interface.
298  typedef TYPENAME PointerToArrayBase<Element>::To To;
299  typedef TYPENAME pvector<Element>::value_type value_type;
300  typedef TYPENAME pvector<Element>::const_reference reference;
301  typedef TYPENAME pvector<Element>::const_reference const_reference;
302  typedef TYPENAME pvector<Element>::const_iterator iterator;
303  typedef TYPENAME pvector<Element>::const_iterator const_iterator;
304 #if defined(WIN32_VC) || defined(WIN64_VC)
305  // VC++ seems to break the const_reverse_iterator definition somehow.
306  typedef TYPENAME pvector<Element>::reverse_iterator reverse_iterator;
307 #else
308  typedef TYPENAME pvector<Element>::const_reverse_iterator reverse_iterator;
309 #endif
310  typedef TYPENAME pvector<Element>::const_reverse_iterator const_reverse_iterator;
311  typedef TYPENAME pvector<Element>::difference_type difference_type;
312  typedef TYPENAME pvector<Element>::size_type size_type;
313 
314  INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
315  INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
317 
318 #ifdef USE_MOVE_SEMANTICS
319  INLINE ConstPointerToArray(PointerToArray<Element> &&from) NOEXCEPT;
320  INLINE ConstPointerToArray(ConstPointerToArray<Element> &&from) NOEXCEPT;
321 #endif
322 
323  // Duplicating the interface of vector.
324 
325  INLINE iterator begin() const;
326  INLINE iterator end() const;
327  INLINE TYPENAME ConstPointerToArray<Element>::reverse_iterator rbegin() const;
328  INLINE TYPENAME ConstPointerToArray<Element>::reverse_iterator rend() const;
329 
330  // Equality and comparison operators are pointerwise for
331  // PointerToArrays, not elementwise as in vector.
332 
333  INLINE size_type size() const;
334  INLINE size_type max_size() const;
335  INLINE bool empty() const;
336 
337  // Functions specific to vectors.
338  INLINE size_type capacity() const;
339  INLINE reference front() const;
340  INLINE reference back() const;
341 
342 #if !defined(WIN32_VC) && !defined(WIN64_VC)
343  INLINE reference operator [](size_type n) const;
344  INLINE reference operator [](int n) const;
345 #endif
346 
347  INLINE operator const Element *() const;
348  INLINE const Element *p() const;
349  INLINE const pvector<Element> &v() const;
350  INLINE const ReferenceCountedVector<Element> *v0() const;
352 
353  // Methods to help out Python and other high-level languages.
354  INLINE const Element &get_element(size_type n) const;
355  INLINE string get_data() const;
356  INLINE string get_subdata(size_type n, size_type count) const;
357 
358  INLINE int get_ref_count() const;
359  INLINE void ref() const;
360  INLINE bool unref() const;
361 
362  INLINE int get_node_ref_count() const;
363  INLINE void node_ref() const;
364  INLINE bool node_unref() const;
365 
366  // Reassignment is by pointer, not memberwise as with a vector.
368  operator = (ReferenceCountedVector<Element> *ptr);
370  operator = (const PointerToArray<Element> &copy);
372  operator = (const ConstPointerToArray<Element> &copy);
373 
374 #ifdef USE_MOVE_SEMANTICS
376  operator = (PointerToArray<Element> &&from) NOEXCEPT;
377  INLINE ConstPointerToArray<Element> &
378  operator = (ConstPointerToArray<Element> &&from) NOEXCEPT;
379 #endif
380 
381  INLINE void clear();
382 
383 private:
384  TypeHandle _type_handle;
385 
386 private:
387  // This static empty array is kept around just so we can return
388  // something meangful when begin() or end() is called and we have a
389  // NULL pointer. It might not be shared properly between different
390  // .so's, since it's a static member of a template class, but we
391  // don't really care.
392  static pvector<Element> _empty_array;
393 #endif // CPPPARSER
394 
395  friend class PointerToArray<Element>;
396 };
397 
398 // And the brevity macros.
399 #define PTA(type) PointerToArray< type >
400 #define CPTA(type) ConstPointerToArray< type >
401 
402 #include "pointerToArray.I"
403 
404 #endif // HAVE_POINTERTOARRAY_H
int get_node_ref_count() const
Returns 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&#39;s esoteric functionalit...
void * get_void_ptr() const
Returns the reference to memory where the vector is stored.
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...
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 ...
int get_ref_count() const
Returns the reference count of the underlying vector.
bool node_unref() const
Decrements the node_ref of the underlying vector.
void node_ref() const
Increments the node_ref of the underlying vector.
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 ...
A special kind of PointerTo that stores an array of the indicated element type, instead of a single e...
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...
bool unref() const
Decrements the reference count of the underlying vector.
void ref() const
Increments 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.
int get_ref_count() const
Returns the reference count of the underlying vector.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
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 set_data(const string &data)
This method exists mainly to access the data of the array easily from a high-level language such as P...
void node_ref() const
Increments the node_ref of the underlying vector.
pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector&#39;s esoteric functionalit...
This is the base class for PointerToArray and ConstPointerToArray.
void set_subdata(size_type n, size_type count, const string &data)
This method exists mainly to access the data of the array easily from a high-level language such as P...
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
const ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
PointerToArray< Element > cast_non_const() const
Casts away the constness of the CPTA(Element), and returns an equivalent PTA(Element).
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...
string get_data() 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.
bool node_unref() const
Decrements the node_ref of the underlying vector.
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:85
string get_data() const
This method exists mainly to access the data of the array easily from a high-level language such as P...
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 ...
This defines the object that is actually stored and reference-counted internally by a PointerToArray...
Element * p() const
Function p() is similar to the function from PointerTo.
bool unref() const
Decrements the reference count of the underlying vector.
Similar to PointerToArray, except that its contents may not be modified.