Panda3D
|
00001 // Filename: pointerToArray.h 00002 // Created by: drose (14Jan99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef POINTERTOARRAY_H 00016 #define POINTERTOARRAY_H 00017 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // 00021 // This file defines the classes PointerToArray and 00022 // ConstPointerToArray (and their abbreviations, PTA and CPTA), which 00023 // are extensions to the PointerTo class that support 00024 // reference-counted arrays. 00025 // 00026 // You may think of a PointerToArray as the same thing as a 00027 // traditional C-style array. However, it actually stores a pointer 00028 // to an STL vector, which is then reference-counted. Thus, most 00029 // vector operations may be applied directly to a PointerToArray 00030 // object, including dynamic resizing via push_back() and pop_back(). 00031 // 00032 // Unlike the PointerTo class, the PointerToArray may store pointers 00033 // to any kind of object, not just those derived from ReferenceCount. 00034 // 00035 // Like PointerTo and ConstPointerTo, the macro abbreviations PTA and 00036 // CPTA are defined for convenience. 00037 // 00038 // Some examples of syntax: instead of: 00039 // 00040 // PTA(int) array(10); int *array = new int[10]; 00041 // memset(array, 0, sizeof(int) * 10); memset(array, 0, sizeof(int) * 10); 00042 // array[i] = array[i+1]; array[i] = array[i+1]; 00043 // num_elements = array.size(); (no equivalent) 00044 // 00045 // PTA(int) copy = array; int *copy = array; 00046 // 00047 // Note that in the above example, unlike an STL vector (but like a 00048 // C-style array), assigning a PointerToArray object from another 00049 // simply copies the pointer, and does not copy individual elements. 00050 // (Of course, reference counts are adjusted appropriately7.) If you 00051 // actually wanted an element-by-element copy of the array, you would 00052 // do this: 00053 // 00054 // PTA(int) copy(0); // Create a pointer to an empty vector. 00055 // copy.v() = array.v(); // v() is the STL vector itself. 00056 // 00057 // The (0) parameter to the constructor in the above example is 00058 // crucial. When a numeric length parameter, such as zero, is given 00059 // to the constructor, it means to define a new STL vector with that 00060 // number of elements initially in it. If no parameter is given, on 00061 // the other hand, it means the PointerToArray should point to 00062 // nothing--no STL vector is created. This is equivalent to a C array 00063 // that points to NULL. 00064 // 00065 //////////////////////////////////////////////////////////////////// 00066 00067 #include "pandabase.h" 00068 00069 #include "pointerToArrayBase.h" 00070 #ifdef HAVE_PYTHON 00071 #include "py_panda.h" 00072 #endif 00073 00074 #if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(__INTEL_COMPILER) 00075 // disable mysterious MSVC warning for static inline PTA::empty_array method 00076 // need to chk if vc 7.0 still has this problem, would like to keep it enabled 00077 #pragma warning (disable : 4506) 00078 #endif 00079 00080 template <class Element> 00081 class ConstPointerToArray; 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Class : PointerToArray 00085 // Description : A special kind of PointerTo that stores an array of 00086 // the indicated element type, instead of a single 00087 // element. This is actually implemented as an STL 00088 // vector, using the RefCountObj class to wrap it up 00089 // with a reference count. 00090 // 00091 // We actually inherit from NodeRefCountObj these days, 00092 // which adds node_ref() and node_unref() to the 00093 // standard ref() and unref(). This is particularly 00094 // useful for GeomVertexArrayData; other classes may or 00095 // may not find this additional counter useful, but 00096 // since it adds relatively little overhead (compared 00097 // with what is presumably a largish array), we go ahead 00098 // and add it here, even though it is inherited by many 00099 // different parts of the system that may not use it. 00100 //////////////////////////////////////////////////////////////////// 00101 template <class Element> 00102 class PointerToArray : public PointerToArrayBase<Element> { 00103 public: 00104 // By hiding this template from interrogate, we would improve 00105 // compile-time speed and memory utilization. However, we do want 00106 // to export a minimal subset of this class. So we define just the 00107 // exportable interface here. 00108 #ifdef CPPPARSER 00109 PUBLISHED: 00110 typedef TYPENAME pvector<Element>::size_type size_type; 00111 INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element)); 00112 INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element)); 00113 INLINE PointerToArray(const PointerToArray<Element> ©); 00114 00115 #ifdef HAVE_PYTHON 00116 PointerToArray(PyObject *self, PyObject *sequence); 00117 #endif 00118 00119 INLINE size_type size() const; 00120 INLINE void push_back(const Element &x); 00121 INLINE void pop_back(); 00122 INLINE const Element &get_element(size_type n) const; 00123 INLINE void set_element(size_type n, const Element &value); 00124 INLINE const Element &__getitem__(size_type n) const; 00125 INLINE void __setitem__(size_type n, const Element &value); 00126 INLINE string get_data() const; 00127 INLINE void set_data(const string &data); 00128 INLINE string get_subdata(size_type n, size_type count) const; 00129 INLINE void set_subdata(size_type n, size_type count, const string &data); 00130 INLINE int get_ref_count() const; 00131 INLINE int get_node_ref_count() const; 00132 00133 #else // CPPPARSER 00134 // This is the actual, complete interface. 00135 typedef TYPENAME PointerToArrayBase<Element>::To To; 00136 typedef TYPENAME pvector<Element>::value_type value_type; 00137 typedef TYPENAME pvector<Element>::reference reference; 00138 typedef TYPENAME pvector<Element>::const_reference const_reference; 00139 typedef TYPENAME pvector<Element>::iterator iterator; 00140 typedef TYPENAME pvector<Element>::const_iterator const_iterator; 00141 typedef TYPENAME pvector<Element>::reverse_iterator reverse_iterator; 00142 typedef TYPENAME pvector<Element>::const_reverse_iterator const_reverse_iterator; 00143 typedef TYPENAME pvector<Element>::difference_type difference_type; 00144 typedef TYPENAME pvector<Element>::size_type size_type; 00145 00146 public: 00147 INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element)); 00148 INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element)); 00149 INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element)); 00150 INLINE PointerToArray(const PointerToArray<Element> ©); 00151 00152 #ifdef HAVE_PYTHON 00153 PointerToArray(PyObject *self, PyObject *sequence); 00154 #endif 00155 00156 public: 00157 // Duplicating the interface of vector. The following member 00158 // functions are all const, because they do not reassign the 00159 // pointer--they operate only within the vector itself, which is 00160 // non-const in this class. 00161 00162 INLINE iterator begin() const; 00163 INLINE iterator end() const; 00164 INLINE TYPENAME PointerToArray<Element>::reverse_iterator rbegin() const; 00165 INLINE TYPENAME PointerToArray<Element>::reverse_iterator rend() const; 00166 00167 // Equality and comparison operators are pointerwise for 00168 // PointerToArrays, not elementwise as in vector. 00169 INLINE size_type size() const; 00170 INLINE size_type max_size() const; 00171 INLINE bool empty() const; 00172 00173 // Functions specific to vectors. 00174 INLINE void reserve(size_type n); 00175 INLINE void resize(size_type n); 00176 INLINE size_type capacity() const; 00177 INLINE reference front() const; 00178 INLINE reference back() const; 00179 INLINE iterator insert(iterator position, const Element &x); 00180 INLINE void insert(iterator position, size_type n, const Element &x); 00181 00182 // We don't define the insert() method that accepts a pair of 00183 // iterators to copy from. That's problematic because of the whole 00184 // member template thing. If you really need this, use 00185 // pta.v().insert(...); if you're doing this on a vector that has to 00186 // be exported from the DLL, you should use 00187 // insert_into_vector(pta.v(), ...). 00188 00189 INLINE void erase(iterator position); 00190 INLINE void erase(iterator first, iterator last); 00191 00192 #if !defined(WIN32_VC) && !defined (WIN64_VC) 00193 INLINE reference operator [](size_type n) const; 00194 INLINE reference operator [](int n) const; 00195 #endif 00196 00197 INLINE void push_back(const Element &x); 00198 INLINE void pop_back(); 00199 INLINE void make_empty(); 00200 00201 INLINE operator Element *() const; 00202 INLINE Element *p() const; 00203 INLINE pvector<Element> &v() const; 00204 INLINE ReferenceCountedVector<Element> *v0() const; 00205 00206 // Methods to help out Python and other high-level languages. 00207 INLINE const Element &get_element(size_type n) const; 00208 INLINE void set_element(size_type n, const Element &value); 00209 INLINE const Element &__getitem__(size_type n) const; 00210 INLINE void __setitem__(size_type n, const Element &value); 00211 INLINE string get_data() const; 00212 INLINE void set_data(const string &data); 00213 INLINE string get_subdata(size_type n, size_type count) const; 00214 INLINE void set_subdata(size_type n, size_type count, const string &data); 00215 00216 //These functions are only to be used in Reading through BamReader. 00217 //They are designed to work in pairs, so that you register what is 00218 //returned by get_void_ptr with BamReader and when you are setting 00219 //another PTA with what is returned by BamReader, you set it with 00220 //set_void_ptr. If you used the provided macro of READ_PTA, this is 00221 //done for you. So you should never call these functions directly 00222 INLINE void *get_void_ptr() const; 00223 INLINE void set_void_ptr(void* p); 00224 00225 INLINE int get_ref_count() const; 00226 00227 INLINE int get_node_ref_count() const; 00228 INLINE void node_ref() const; 00229 INLINE bool node_unref() const; 00230 00231 // Reassignment is by pointer, not memberwise as with a vector. 00232 INLINE PointerToArray<Element> & 00233 operator = (ReferenceCountedVector<Element> *ptr); 00234 INLINE PointerToArray<Element> & 00235 operator = (const PointerToArray<Element> ©); 00236 INLINE void clear(); 00237 00238 private: 00239 TypeHandle _type_handle; 00240 00241 private: 00242 // This static empty array is kept around just so we can return 00243 // something meaningful when begin() or end() is called and we have a 00244 // NULL pointer. It might not be shared properly between different 00245 // .so's, since it's a static member of a template class, but we 00246 // don't really care. 00247 static pvector<Element> _empty_array; 00248 #endif // CPPPARSER 00249 00250 friend class ConstPointerToArray<Element>; 00251 }; 00252 00253 //////////////////////////////////////////////////////////////////// 00254 // Class : ConstPointerToArray 00255 // Description : Similar to PointerToArray, except that its contents 00256 // may not be modified. 00257 //////////////////////////////////////////////////////////////////// 00258 template <class Element> 00259 class ConstPointerToArray : public PointerToArrayBase<Element> { 00260 public: 00261 // By hiding this template from interrogate, we would improve 00262 // compile-time speed and memory utilization. However, we do want 00263 // to export a minimal subset of this class. So we define just the 00264 // exportable interface here. 00265 #ifdef CPPPARSER 00266 PUBLISHED: 00267 INLINE ConstPointerToArray(const PointerToArray<Element> ©); 00268 INLINE ConstPointerToArray(const ConstPointerToArray<Element> ©); 00269 00270 typedef TYPENAME pvector<Element>::size_type size_type; 00271 INLINE size_type size() const; 00272 INLINE const Element &get_element(size_type n) const; 00273 INLINE const Element &__getitem__(size_type n) const; 00274 INLINE string get_data() const; 00275 INLINE string get_subdata(size_type n, size_type count) const; 00276 INLINE int get_ref_count() const; 00277 INLINE int get_node_ref_count() const; 00278 00279 #else // CPPPARSER 00280 // This is the actual, complete interface. 00281 typedef TYPENAME PointerToArrayBase<Element>::To To; 00282 typedef TYPENAME pvector<Element>::value_type value_type; 00283 typedef TYPENAME pvector<Element>::const_reference reference; 00284 typedef TYPENAME pvector<Element>::const_reference const_reference; 00285 typedef TYPENAME pvector<Element>::const_iterator iterator; 00286 typedef TYPENAME pvector<Element>::const_iterator const_iterator; 00287 #if defined(WIN32_VC) || defined(WIN64_VC) 00288 // VC++ seems to break the const_reverse_iterator definition somehow. 00289 typedef TYPENAME pvector<Element>::reverse_iterator reverse_iterator; 00290 #else 00291 typedef TYPENAME pvector<Element>::const_reverse_iterator reverse_iterator; 00292 #endif 00293 typedef TYPENAME pvector<Element>::const_reverse_iterator const_reverse_iterator; 00294 typedef TYPENAME pvector<Element>::difference_type difference_type; 00295 typedef TYPENAME pvector<Element>::size_type size_type; 00296 00297 INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element)); 00298 INLINE ConstPointerToArray(const PointerToArray<Element> ©); 00299 INLINE ConstPointerToArray(const ConstPointerToArray<Element> ©); 00300 00301 // Duplicating the interface of vector. 00302 00303 INLINE iterator begin() const; 00304 INLINE iterator end() const; 00305 INLINE TYPENAME ConstPointerToArray<Element>::reverse_iterator rbegin() const; 00306 INLINE TYPENAME ConstPointerToArray<Element>::reverse_iterator rend() const; 00307 00308 // Equality and comparison operators are pointerwise for 00309 // PointerToArrays, not elementwise as in vector. 00310 00311 INLINE size_type size() const; 00312 INLINE size_type max_size() const; 00313 INLINE bool empty() const; 00314 00315 // Functions specific to vectors. 00316 INLINE size_type capacity() const; 00317 INLINE reference front() const; 00318 INLINE reference back() const; 00319 00320 #if !defined(WIN32_VC) && !defined(WIN64_VC) 00321 INLINE reference operator [](size_type n) const; 00322 INLINE reference operator [](int n) const; 00323 #endif 00324 00325 INLINE operator const Element *() const; 00326 INLINE const Element *p() const; 00327 INLINE const pvector<Element> &v() const; 00328 INLINE const ReferenceCountedVector<Element> *v0() const; 00329 INLINE PointerToArray<Element> cast_non_const() const; 00330 00331 // Methods to help out Python and other high-level languages. 00332 INLINE const Element &get_element(size_type n) const; 00333 INLINE const Element &__getitem__(size_type n) const; 00334 INLINE string get_data() const; 00335 INLINE string get_subdata(size_type n, size_type count) const; 00336 00337 INLINE int get_ref_count() const; 00338 00339 INLINE int get_node_ref_count() const; 00340 INLINE void node_ref() const; 00341 INLINE bool node_unref() const; 00342 00343 // Reassignment is by pointer, not memberwise as with a vector. 00344 INLINE ConstPointerToArray<Element> & 00345 operator = (ReferenceCountedVector<Element> *ptr); 00346 INLINE ConstPointerToArray<Element> & 00347 operator = (const PointerToArray<Element> ©); 00348 INLINE ConstPointerToArray<Element> & 00349 operator = (const ConstPointerToArray<Element> ©); 00350 INLINE void clear(); 00351 00352 private: 00353 TypeHandle _type_handle; 00354 00355 private: 00356 // This static empty array is kept around just so we can return 00357 // something meangful when begin() or end() is called and we have a 00358 // NULL pointer. It might not be shared properly between different 00359 // .so's, since it's a static member of a template class, but we 00360 // don't really care. 00361 static pvector<Element> _empty_array; 00362 #endif // CPPPARSER 00363 00364 friend class PointerToArray<Element>; 00365 }; 00366 00367 00368 // And the brevity macros. 00369 00370 #define PTA(type) PointerToArray< type > 00371 #define CPTA(type) ConstPointerToArray< type > 00372 00373 #include "pointerToArray.I" 00374 00375 #endif