// Filename: pointerToArray.h // Created by: drose (14Jan99) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license // along with this source code; you will also find a current copy of // the license at http://www.panda3d.org/license.txt . // // To contact the maintainers of this program write to // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// #ifndef POINTERTOARRAY_H #define POINTERTOARRAY_H //////////////////////////////////////////////////////////////////// // // This file defines the classes PointerToArray and // ConstPointerToArray (and their abbreviations, PTA and CPTA), which // are extensions to the PointerTo class that support // reference-counted arrays. // // You may think of a PointerToArray as the same thing as a // traditional C-style array. However, it actually stores a pointer // to an STL vector, which is then reference-counted. Thus, most // vector operations may be applied directly to a PointerToArray // object, including dynamic resizing via push_back() and pop_back(). // // Unlike the PointerTo class, the PointerToArray may store pointers // to any kind of object, not just those derived from ReferenceCount. // // Like PointerTo and ConstPointerTo, the macro abbreviations PTA and // CPTA are defined for convenience. // // Some examples of syntax: instead of: // // PTA(int) array(10); int *array = new int[10]; // memset(array, 0, sizeof(int) * 10); memset(array, 0, sizeof(int) * 10); // array[i] = array[i+1]; array[i] = array[i+1]; // num_elements = array.size(); (no equivalent) // // PTA(int) copy = array; int *copy = array; // // Note that in the above example, unlike an STL vector (but like a // C-style array), assigning a PointerToArray object from another // simply copies the pointer, and does not copy individual elements. // (Of course, reference counts are adjusted appropriately.) If you // actually wanted an element-by-element copy of the array, you would // do this: // // PTA(int) copy(0); // Create a pointer to an empty vector. // copy.v() = array.v(); // v() is the STL vector itself. // // The (0) parameter to the constructor in the above example is // crucial. When a numeric length parameter, such as zero, is given // to the constructor, it means to define a new STL vector with that // number of elements initially in it. If no parameter is given, on // the other hand, it means the PointerToArray should point to // nothing--no STL vector is created. This is equivalent to a C array // that points to NULL. // //////////////////////////////////////////////////////////////////// #include "pandabase.h" #include "referenceCount.h" #include "pointerTo.h" #include "pvector.h" #if defined(WIN32_VC) && !defined(__INTEL_COMPILER) // disable mysterious MSVC warning for static inline PTA::empty_array method // need to chk if vc 7.0 still has this problem, would like to keep it enabled #pragma warning (disable : 4506) #endif //////////////////////////////////////////////////////////////////// // Class : PointerToArray // Description : A special kind of PointerTo that stores an array of // the indicated element type, instead of a single // element. This is actually implemented as an STL // vector, using the RefCountObj class to wrap it up // with a reference count. //////////////////////////////////////////////////////////////////// template class PointerToArray : public PointerToBase > > { public: typedef TYPENAME pvector::value_type value_type; typedef TYPENAME pvector::reference reference; typedef TYPENAME pvector::const_reference const_reference; typedef TYPENAME pvector::iterator iterator; typedef TYPENAME pvector::const_iterator const_iterator; typedef TYPENAME pvector::reverse_iterator reverse_iterator; typedef TYPENAME pvector::const_reverse_iterator const_reverse_iterator; typedef TYPENAME pvector::difference_type difference_type; typedef TYPENAME pvector::size_type size_type; PUBLISHED: INLINE PointerToArray(); // INLINE PointerToArray(size_type n); this is too dangerous to use, since arrays created automatically for any const parameter, use empty_array instead INLINE static PointerToArray empty_array(size_type n); INLINE PointerToArray(size_type n, const Element &value); INLINE PointerToArray(const PointerToArray ©); public: // Duplicating the interface of vector. The following member // functions are all const, because they do not reassign the // pointer--they operate only within the vector itself, which is // non-const in this class. INLINE iterator begin() const; INLINE iterator end() const; INLINE TYPENAME PointerToArray::reverse_iterator rbegin() const; INLINE TYPENAME PointerToArray::reverse_iterator rend() const; // Equality and comparison operators are pointerwise for // PointerToArrays, not elementwise as in vector. PUBLISHED: INLINE size_type size() const; public: INLINE size_type max_size() const; INLINE bool empty() const; // Functions specific to vectors. INLINE void reserve(size_type n); INLINE size_type capacity() const; INLINE reference front() const; INLINE reference back() const; INLINE iterator insert(iterator position, const Element &x) const; INLINE void insert(iterator position, size_type n, const Element &x) const; // We don't define the insert() method that accepts a pair of // iterators to copy from. That's problematic because of the whole // member template thing. If you really need this, use // pta.v().insert(...); if you're doing this on a vector that has to // be exported from the DLL, you should use // insert_into_vector(pta.v(), ...). INLINE void erase(iterator position) const; INLINE void erase(iterator first, iterator last) const; PUBLISHED: #if !defined(WIN32_VC) INLINE reference operator [](size_type n) const; INLINE reference operator [](int n) const; #endif INLINE void push_back(const Element &x); INLINE void pop_back(); INLINE void make_empty(); public: INLINE operator Element *() const; INLINE Element *p() const; INLINE pvector &v() const; //These functions are only to be used in Reading through BamReader. //They are designed to work in pairs, so that you register what is //returned by get_void_ptr with BamReader and when you are setting //another PTA with what is returned by BamReader, you set it with //set_void_ptr. If you used the provided macro of READ_PTA, this is //done for you. So you should never call these functions directly INLINE void *get_void_ptr() const; INLINE void set_void_ptr(void* p); INLINE int get_ref_count() const; // Reassignment is by pointer, not memberwise as with a vector. INLINE PointerToArray & operator = (RefCountObj > *ptr); INLINE PointerToArray & operator = (const PointerToArray ©); INLINE void clear(); private: // This static empty array is kept around just so we can return // something meangful when begin() or end() is called and we have a // NULL pointer. It might not be shared properly between different // .so's, since it's a static member of a template class, but we // don't really care. static pvector _empty_array; }; //////////////////////////////////////////////////////////////////// // Class : ConstPointerToArray // Description : Similar to PointerToArray, except that its contents // may not be modified. //////////////////////////////////////////////////////////////////// template class ConstPointerToArray : public PointerToBase > > { public: typedef TYPENAME pvector::value_type value_type; typedef TYPENAME pvector::const_reference reference; typedef TYPENAME pvector::const_reference const_reference; typedef TYPENAME pvector::const_iterator iterator; typedef TYPENAME pvector::const_iterator const_iterator; #ifdef WIN32_VC // VC++ seems to break the const_reverse_iterator definition somehow. typedef TYPENAME pvector::reverse_iterator reverse_iterator; #else typedef TYPENAME pvector::const_reverse_iterator reverse_iterator; #endif typedef TYPENAME pvector::const_reverse_iterator const_reverse_iterator; typedef TYPENAME pvector::difference_type difference_type; typedef TYPENAME pvector::size_type size_type; INLINE ConstPointerToArray(); INLINE ConstPointerToArray(const PointerToArray ©); INLINE ConstPointerToArray(const ConstPointerToArray ©); // Duplicating the interface of vector. INLINE iterator begin() const; INLINE iterator end() const; INLINE TYPENAME ConstPointerToArray::reverse_iterator rbegin() const; INLINE TYPENAME ConstPointerToArray::reverse_iterator rend() const; // Equality and comparison operators are pointerwise for // PointerToArrays, not elementwise as in vector. INLINE size_type size() const; INLINE size_type max_size() const; INLINE bool empty() const; // Functions specific to vectors. INLINE size_type capacity() const; #ifndef WIN32_VC INLINE reference operator [](size_type n) const; INLINE reference operator [](int n) const; #endif INLINE reference front() const; INLINE reference back() const; INLINE operator const Element *() const; INLINE const Element *p() const; INLINE const pvector &v() const; INLINE int get_ref_count() const; // Reassignment is by pointer, not memberwise as with a vector. INLINE ConstPointerToArray & operator = (RefCountObj > *ptr); INLINE ConstPointerToArray & operator = (const PointerToArray ©); INLINE ConstPointerToArray & operator = (const ConstPointerToArray ©); INLINE void clear(); private: // This static empty array is kept around just so we can return // something meangful when begin() or end() is called and we have a // NULL pointer. It might not be shared properly between different // .so's, since it's a static member of a template class, but we // don't really care. static pvector _empty_array; }; // And the brevity macros. #define PTA(type) PointerToArray< type > #define CPTA(type) ConstPointerToArray< type > #include "pointerToArray.I" #endif