00001 // Filename: pointerToArray.h 00002 // Created by: drose (14Jan99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #ifndef POINTERTOARRAY_H 00020 #define POINTERTOARRAY_H 00021 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // 00025 // This file defines the classes PointerToArray and 00026 // ConstPointerToArray (and their abbreviations, PTA and CPTA), which 00027 // are extensions to the PointerTo class that support 00028 // reference-counted arrays. 00029 // 00030 // You may think of a PointerToArray as the same thing as a 00031 // traditional C-style array. However, it actually stores a pointer 00032 // to an STL vector, which is then reference-counted. Thus, most 00033 // vector operations may be applied directly to a PointerToArray 00034 // object, including dynamic resizing via push_back() and pop_back(). 00035 // 00036 // Unlike the PointerTo class, the PointerToArray may store pointers 00037 // to any kind of object, not just those derived from ReferenceCount. 00038 // 00039 // Like PointerTo and ConstPointerTo, the macro abbreviations PTA and 00040 // CPTA are defined for convenience. 00041 // 00042 // Some examples of syntax: instead of: 00043 // 00044 // PTA(int) array(10); int *array = new int[10]; 00045 // memset(array, 0, sizeof(int) * 10); memset(array, 0, sizeof(int) * 10); 00046 // array[i] = array[i+1]; array[i] = array[i+1]; 00047 // num_elements = array.size(); (no equivalent) 00048 // 00049 // PTA(int) copy = array; int *copy = array; 00050 // 00051 // Note that in the above example, unlike an STL vector (but like a 00052 // C-style array), assigning a PointerToArray object from another 00053 // simply copies the pointer, and does not copy individual elements. 00054 // (Of course, reference counts are adjusted appropriately.) If you 00055 // actually wanted an element-by-element copy of the array, you would 00056 // do this: 00057 // 00058 // PTA(int) copy(0); // Create a pointer to an empty vector. 00059 // copy.v() = array.v(); // v() is the STL vector itself. 00060 // 00061 // The (0) parameter to the constructor in the above example is 00062 // crucial. When a numeric length parameter, such as zero, is given 00063 // to the constructor, it means to define a new STL vector with that 00064 // number of elements initially in it. If no parameter is given, on 00065 // the other hand, it means the PointerToArray should point to 00066 // nothing--no STL vector is created. This is equivalent to a C array 00067 // that points to NULL. 00068 // 00069 //////////////////////////////////////////////////////////////////// 00070 00071 #include <pandabase.h> 00072 00073 #include "referenceCount.h" 00074 #include "pointerTo.h" 00075 #include "pvector.h" 00076 00077 #if defined(WIN32_VC) && !defined(__INTEL_COMPILER) 00078 // disable mysterious MSVC warning for static inline PTA::empty_array method 00079 // need to chk if vc 7.0 still has this problem, would like to keep it enabled 00080 #pragma warning (disable : 4506) 00081 #endif 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 template <class Element> 00092 class PointerToArray : public PointerToBase<RefCountObj<pvector<Element> > > { 00093 public: 00094 typedef TYPENAME pvector<Element>::value_type value_type; 00095 typedef TYPENAME pvector<Element>::reference reference; 00096 typedef TYPENAME pvector<Element>::const_reference const_reference; 00097 typedef TYPENAME pvector<Element>::iterator iterator; 00098 typedef TYPENAME pvector<Element>::const_iterator const_iterator; 00099 typedef TYPENAME pvector<Element>::reverse_iterator reverse_iterator; 00100 typedef TYPENAME pvector<Element>::const_reverse_iterator const_reverse_iterator; 00101 typedef TYPENAME pvector<Element>::difference_type difference_type; 00102 typedef TYPENAME pvector<Element>::size_type size_type; 00103 00104 PUBLISHED: 00105 INLINE PointerToArray(); 00106 // INLINE PointerToArray(size_type n); this is too dangerous to use, since arrays created automatically for any const parameter, use empty_array instead 00107 INLINE static PointerToArray<Element> empty_array(size_type n); 00108 INLINE PointerToArray(size_type n, const Element &value); 00109 INLINE PointerToArray(const PointerToArray<Element> ©); 00110 00111 public: 00112 // Duplicating the interface of vector. The following member 00113 // functions are all const, because they do not reassign the 00114 // pointer--they operate only within the vector itself, which is 00115 // non-const in this class. 00116 00117 INLINE iterator begin() const; 00118 INLINE iterator end() const; 00119 INLINE TYPENAME PointerToArray<Element>::reverse_iterator rbegin() const; 00120 INLINE TYPENAME PointerToArray<Element>::reverse_iterator rend() const; 00121 00122 // Equality and comparison operators are pointerwise for 00123 // PointerToArrays, not elementwise as in vector. 00124 00125 PUBLISHED: 00126 INLINE size_type size() const; 00127 00128 public: 00129 INLINE size_type max_size() const; 00130 INLINE bool empty() const; 00131 00132 // Functions specific to vectors. 00133 INLINE void reserve(size_type n); 00134 INLINE size_type capacity() const; 00135 INLINE reference front() const; 00136 INLINE reference back() const; 00137 INLINE iterator insert(iterator position, const Element &x) const; 00138 INLINE void insert(iterator position, size_type n, const Element &x) const; 00139 00140 // We don't define the insert() method that accepts a pair of 00141 // iterators to copy from. That's problematic because of the whole 00142 // member template thing. If you really need this, use 00143 // pta.v().insert(...); if you're doing this on a vector that has to 00144 // be exported from the DLL, you should use 00145 // insert_into_vector(pta.v(), ...). 00146 00147 INLINE void erase(iterator position) const; 00148 INLINE void erase(iterator first, iterator last) const; 00149 00150 PUBLISHED: 00151 #if !defined(WIN32_VC) 00152 INLINE reference operator [](size_type n) const; 00153 INLINE reference operator [](int n) const; 00154 #endif 00155 INLINE void push_back(const Element &x); 00156 INLINE void pop_back(); 00157 INLINE void make_empty(); 00158 00159 public: 00160 00161 INLINE operator Element *() const; 00162 INLINE Element *p() const; 00163 INLINE pvector<Element> &v() const; 00164 00165 //These functions are only to be used in Reading through BamReader. 00166 //They are designed to work in pairs, so that you register what is 00167 //returned by get_void_ptr with BamReader and when you are setting 00168 //another PTA with what is returned by BamReader, you set it with 00169 //set_void_ptr. If you used the provided macro of READ_PTA, this is 00170 //done for you. So you should never call these functions directly 00171 INLINE void *get_void_ptr() const; 00172 INLINE void set_void_ptr(void* p); 00173 00174 INLINE int get_ref_count() const; 00175 00176 // Reassignment is by pointer, not memberwise as with a vector. 00177 INLINE PointerToArray<Element> & 00178 operator = (RefCountObj<pvector<Element> > *ptr); 00179 INLINE PointerToArray<Element> & 00180 operator = (const PointerToArray<Element> ©); 00181 INLINE void clear(); 00182 00183 private: 00184 // This static empty array is kept around just so we can return 00185 // something meangful when begin() or end() is called and we have a 00186 // NULL pointer. It might not be shared properly between different 00187 // .so's, since it's a static member of a template class, but we 00188 // don't really care. 00189 static pvector<Element> _empty_array; 00190 }; 00191 00192 //////////////////////////////////////////////////////////////////// 00193 // Class : ConstPointerToArray 00194 // Description : Similar to PointerToArray, except that its contents 00195 // may not be modified. 00196 //////////////////////////////////////////////////////////////////// 00197 template <class Element> 00198 class ConstPointerToArray : public PointerToBase<RefCountObj<pvector<Element> > > { 00199 public: 00200 typedef TYPENAME pvector<Element>::value_type value_type; 00201 typedef TYPENAME pvector<Element>::const_reference reference; 00202 typedef TYPENAME pvector<Element>::const_reference const_reference; 00203 typedef TYPENAME pvector<Element>::const_iterator iterator; 00204 typedef TYPENAME pvector<Element>::const_iterator const_iterator; 00205 #ifdef WIN32_VC 00206 // VC++ seems to break the const_reverse_iterator definition somehow. 00207 typedef TYPENAME pvector<Element>::reverse_iterator reverse_iterator; 00208 #else 00209 typedef TYPENAME pvector<Element>::const_reverse_iterator reverse_iterator; 00210 #endif 00211 typedef TYPENAME pvector<Element>::const_reverse_iterator const_reverse_iterator; 00212 typedef TYPENAME pvector<Element>::difference_type difference_type; 00213 typedef TYPENAME pvector<Element>::size_type size_type; 00214 00215 INLINE ConstPointerToArray(); 00216 INLINE ConstPointerToArray(const PointerToArray<Element> ©); 00217 INLINE ConstPointerToArray(const ConstPointerToArray<Element> ©); 00218 00219 // Duplicating the interface of vector. 00220 00221 INLINE iterator begin() const; 00222 INLINE iterator end() const; 00223 INLINE TYPENAME ConstPointerToArray<Element>::reverse_iterator rbegin() const; 00224 INLINE TYPENAME ConstPointerToArray<Element>::reverse_iterator rend() const; 00225 00226 // Equality and comparison operators are pointerwise for 00227 // PointerToArrays, not elementwise as in vector. 00228 00229 INLINE size_type size() const; 00230 INLINE size_type max_size() const; 00231 INLINE bool empty() const; 00232 00233 // Functions specific to vectors. 00234 INLINE size_type capacity() const; 00235 #ifndef WIN32_VC 00236 INLINE reference operator [](size_type n) const; 00237 INLINE reference operator [](int n) const; 00238 #endif 00239 INLINE reference front() const; 00240 INLINE reference back() const; 00241 00242 INLINE operator const Element *() const; 00243 INLINE const Element *p() const; 00244 INLINE const pvector<Element> &v() const; 00245 00246 INLINE int get_ref_count() const; 00247 00248 // Reassignment is by pointer, not memberwise as with a vector. 00249 INLINE ConstPointerToArray<Element> & 00250 operator = (RefCountObj<pvector<Element> > *ptr); 00251 INLINE ConstPointerToArray<Element> & 00252 operator = (const PointerToArray<Element> ©); 00253 INLINE ConstPointerToArray<Element> & 00254 operator = (const ConstPointerToArray<Element> ©); 00255 INLINE void clear(); 00256 00257 private: 00258 // This static empty array is kept around just so we can return 00259 // something meangful when begin() or end() is called and we have a 00260 // NULL pointer. It might not be shared properly between different 00261 // .so's, since it's a static member of a template class, but we 00262 // don't really care. 00263 static pvector<Element> _empty_array; 00264 }; 00265 00266 00267 // And the brevity macros. 00268 00269 #define PTA(type) PointerToArray< type > 00270 #define CPTA(type) ConstPointerToArray< type > 00271 00272 #include "pointerToArray.I" 00273 00274 #endif