// // SPDX-License-Identifier: BSD-3-Clause // Copyright (c) Contributors to the OpenEXR Project. // #ifndef INCLUDED_IMF_ARRAY_H #define INCLUDED_IMF_ARRAY_H #include "ImfForward.h" //------------------------------------------------------------------------- // // class Array // class Array2D // // "Arrays of T" whose sizes are not known at compile time. // When an array goes out of scope, its elements are automatically // deleted. // // Usage example: // // struct C // { // C () {std::cout << "C::C (" << this << ")\n";}; // virtual ~C () {std::cout << "C::~C (" << this << ")\n";}; // }; // // int // main () // { // Array a(3); // // C &b = a[1]; // const C &c = a[1]; // C *d = a + 2; // const C *e = a; // // return 0; // } // //------------------------------------------------------------------------- OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER template class IMF_EXPORT_TEMPLATE_TYPE Array { public: //----------------------------- // Constructors and destructors //----------------------------- Array () { _data = 0; _size = 0; } Array (long size) { _data = new T[size]; _size = size; } ~Array () { delete[] _data; } //----------------------------- // Access to the array elements //----------------------------- operator T* () { return _data; } operator const T* () const { return _data; } //------------------------------------------------------ // Resize and clear the array (the contents of the array // are not preserved across the resize operation). // // resizeEraseUnsafe() is more memory efficient than // resizeErase() because it deletes the old memory block // before allocating a new one, but if allocating the // new block throws an exception, resizeEraseUnsafe() // leaves the array in an unusable state. // //------------------------------------------------------ void resizeErase (long size); void resizeEraseUnsafe (long size); //------------------------------- // Return the size of this array. //------------------------------- long size () const { return _size; } private: Array (const Array&) = delete; Array& operator= (const Array&) = delete; Array (Array&&) = delete; Array& operator= (Array&&) = delete; long _size; T* _data; }; template class IMF_EXPORT_TEMPLATE_TYPE Array2D { public: //----------------------------- // Constructors and destructors //----------------------------- Array2D (); // empty array, 0 by 0 elements Array2D (long sizeX, long sizeY); // sizeX by sizeY elements ~Array2D (); //----------------------------- // Access to the array elements //----------------------------- T* operator[] (long x); const T* operator[] (long x) const; //------------------------------------------------------ // Resize and clear the array (the contents of the array // are not preserved across the resize operation). // // resizeEraseUnsafe() is more memory efficient than // resizeErase() because it deletes the old memory block // before allocating a new one, but if allocating the // new block throws an exception, resizeEraseUnsafe() // leaves the array in an unusable state. // //------------------------------------------------------ void resizeErase (long sizeX, long sizeY); void resizeEraseUnsafe (long sizeX, long sizeY); //------------------------------- // Return the size of this array. //------------------------------- long height () const { return _sizeX; } long width () const { return _sizeY; } private: Array2D (const Array2D&) = delete; Array2D& operator= (const Array2D&) = delete; Array2D (Array2D&&) = delete; Array2D& operator= (Array2D&&) = delete; long _sizeX; long _sizeY; T* _data; }; //--------------- // Implementation //--------------- template inline void Array::resizeErase (long size) { T* tmp = new T[size]; delete[] _data; _size = size; _data = tmp; } template inline void Array::resizeEraseUnsafe (long size) { delete[] _data; _data = 0; _size = 0; _data = new T[size]; _size = size; } template inline Array2D::Array2D () : _sizeX (0), _sizeY (0), _data (0) { // empty } template inline Array2D::Array2D (long sizeX, long sizeY) : _sizeX (sizeX), _sizeY (sizeY), _data (new T[sizeX * sizeY]) { // empty } template inline Array2D::~Array2D () { delete[] _data; } template inline T* Array2D::operator[] (long x) { return _data + x * _sizeY; } template inline const T* Array2D::operator[] (long x) const { return _data + x * _sizeY; } template inline void Array2D::resizeErase (long sizeX, long sizeY) { T* tmp = new T[sizeX * sizeY]; delete[] _data; _sizeX = sizeX; _sizeY = sizeY; _data = tmp; } template inline void Array2D::resizeEraseUnsafe (long sizeX, long sizeY) { delete[] _data; _data = 0; _sizeX = 0; _sizeY = 0; _data = new T[sizeX * sizeY]; _sizeX = sizeX; _sizeY = sizeY; } OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT #endif