Panda3D
 All Classes Functions Variables Enumerations
pointerToArray.h
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> &copy);
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> &copy);
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> &copy);
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> &copy);
00268   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
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> &copy);
00299   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
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> &copy);
00348   INLINE ConstPointerToArray<Element> &
00349   operator = (const ConstPointerToArray<Element> &copy);
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
 All Classes Functions Variables Enumerations