/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * * All use of this software is subject to the terms of the revised BSD * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * * @file pointerToArray.h * @author drose * @date 1999-01-14 */ #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 "pointerToArrayBase.h" #if (defined(WIN32_VC) || defined(WIN64_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 template class ConstPointerToArray; /** * 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. * * We actually inherit from NodeRefCountObj these days, which adds node_ref() * and node_unref() to the standard ref() and unref(). This is particularly * useful for GeomVertexArrayData; other classes may or may not find this * additional counter useful, but since it adds relatively little overhead * (compared with what is presumably a largish array), we go ahead and add it * here, even though it is inherited by many different parts of the system * that may not use it. */ template class PointerToArray : public PointerToArrayBase { public: // By hiding this template from interrogate, we would improve compile-time // speed and memory utilization. However, we do want to export a minimal // subset of this class. So we define just the exportable interface here. #ifdef CPPPARSER PUBLISHED: typedef typename pvector::size_type size_type; INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element)); INLINE static PointerToArray empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element)); INLINE PointerToArray(const PointerToArray ©); EXTENSION(PointerToArray(PyObject *self, PyObject *source)); INLINE void clear(); INLINE size_type size() const; INLINE void push_back(const Element &x); INLINE void pop_back(); INLINE const Element &get_element(size_type n) const; INLINE void set_element(size_type n, const Element &value); EXTENSION(const Element &__getitem__(size_type n) const); EXTENSION(void __setitem__(size_type n, const Element &value)); EXTENSION(PyObject *get_data() const); EXTENSION(void set_data(PyObject *data)); EXTENSION(PyObject *get_subdata(size_type n, size_type count) const); INLINE void set_subdata(size_type n, size_type count, const std::string &data); INLINE int get_ref_count() const; INLINE int get_node_ref_count() const; INLINE size_t count(const Element &) const; #ifdef HAVE_PYTHON EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags)); EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const); #endif #else // CPPPARSER // This is the actual, complete interface. typedef typename PointerToArrayBase::To To; 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; public: INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element)); INLINE static PointerToArray empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element)); INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element)); INLINE PointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element)); INLINE PointerToArray(const PointerToArray ©); INLINE PointerToArray(PointerToArray &&from) noexcept; INLINE explicit PointerToArray(pvector &&from, TypeHandle type_handle = get_type_handle(Element)); 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. INLINE size_type size() const; INLINE size_type max_size() const; INLINE bool empty() const; INLINE void clear(); // Functions specific to vectors. INLINE void reserve(size_type n); INLINE void resize(size_type n); INLINE size_type capacity() const; INLINE reference front() const; INLINE reference back() const; INLINE iterator insert(iterator position, const Element &x); INLINE void insert(iterator position, size_type n, const Element &x); // 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); INLINE void erase(iterator first, iterator last); #if !defined(WIN32_VC) && !defined (WIN64_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(); INLINE operator Element *() const; INLINE Element *p() const; INLINE pvector &v() const; INLINE ReferenceCountedVector *v0() const; // Methods to help out Python and other high-level languages. INLINE const Element &get_element(size_type n) const; INLINE void set_element(size_type n, const Element &value); INLINE std::string get_data() const; INLINE void set_data(const std::string &data); INLINE std::string get_subdata(size_type n, size_type count) const; INLINE void set_subdata(size_type n, size_type count, const std::string &data); // 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; INLINE void ref() const; INLINE bool unref() const; INLINE int get_node_ref_count() const; INLINE void node_ref() const; INLINE bool node_unref() const; INLINE size_t count(const Element &) const; #endif // CPPPARSER public: // Reassignment is by pointer, not memberwise as with a vector. INLINE PointerToArray & operator = (ReferenceCountedVector *ptr); INLINE PointerToArray & operator = (const PointerToArray ©); INLINE PointerToArray & operator = (PointerToArray &&from) noexcept; private: TypeHandle _type_handle; // This static empty array is kept around just so we can return something // meaningful 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; friend class ConstPointerToArray; }; /** * Similar to PointerToArray, except that its contents may not be modified. */ template class ConstPointerToArray : public PointerToArrayBase { public: INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element)); // By hiding this template from interrogate, we would improve compile-time // speed and memory utilization. However, we do want to export a minimal // subset of this class. So we define just the exportable interface here. #ifdef CPPPARSER PUBLISHED: INLINE ConstPointerToArray(const PointerToArray ©); INLINE ConstPointerToArray(const ConstPointerToArray ©); INLINE void clear(); typedef typename pvector::size_type size_type; INLINE size_type size() const; INLINE const Element &get_element(size_type n) const; EXTENSION(const Element &__getitem__(size_type n) const); EXTENSION(PyObject *get_data() const); EXTENSION(PyObject *get_subdata(size_type n, size_type count) const); INLINE int get_ref_count() const; INLINE int get_node_ref_count() const; INLINE size_t count(const Element &) const; #ifdef HAVE_PYTHON EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const); EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const); #endif #else // CPPPARSER // This is the actual, complete interface. typedef typename PointerToArrayBase::To To; 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; #if defined(WIN32_VC) || defined(WIN64_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(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element)); INLINE ConstPointerToArray(const PointerToArray ©); INLINE ConstPointerToArray(const ConstPointerToArray ©); INLINE ConstPointerToArray(PointerToArray &&from) noexcept; INLINE ConstPointerToArray(ConstPointerToArray &&from) noexcept; INLINE explicit ConstPointerToArray(pvector &&from, TypeHandle type_handle = get_type_handle(Element)); // 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; INLINE void clear(); // Functions specific to vectors. INLINE size_type capacity() const; INLINE reference front() const; INLINE reference back() const; #if !defined(WIN32_VC) && !defined(WIN64_VC) INLINE reference operator [](size_type n) const; INLINE reference operator [](int n) const; #endif INLINE operator const Element *() const; INLINE const Element *p() const; INLINE const pvector &v() const; INLINE const ReferenceCountedVector *v0() const; INLINE PointerToArray cast_non_const() const; // Methods to help out Python and other high-level languages. INLINE const Element &get_element(size_type n) const; INLINE std::string get_data() const; INLINE std::string get_subdata(size_type n, size_type count) const; INLINE int get_ref_count() const; INLINE void ref() const; INLINE bool unref() const; INLINE int get_node_ref_count() const; INLINE void node_ref() const; INLINE bool node_unref() const; INLINE size_t count(const Element &) const; #endif // CPPPARSER public: // Reassignment is by pointer, not memberwise as with a vector. INLINE ConstPointerToArray & operator = (ReferenceCountedVector *ptr); INLINE ConstPointerToArray & operator = (const PointerToArray ©); INLINE ConstPointerToArray & operator = (const ConstPointerToArray ©); INLINE ConstPointerToArray & operator = (PointerToArray &&from) noexcept; INLINE ConstPointerToArray & operator = (ConstPointerToArray &&from) noexcept; private: TypeHandle _type_handle; // 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; friend class PointerToArray; }; // And the brevity macros. #define PTA(type) PointerToArray< type > #define CPTA(type) ConstPointerToArray< type > #include "pointerToArray.I" #endif // HAVE_POINTERTOARRAY_H