#ifndef JAGGEDARRAY_H #define JAGGEDARRAY_H namespace rtengine { // These emulate a jagged array, but use only 2 allocations instead of 1 + W. template inline T** const allocJaggedArray (const int W, const int H, const bool initZero = false) { T** const a = new T*[H]; a[0] = new T[H * W]; for (int i = 1; i < H; ++i) { a[i] = a[i - 1] + W; } if (initZero) { std::memset(a[0], 0, sizeof(T) * W * H); } return a; } template inline void freeJaggedArray (T** const a) { delete [] a[0]; delete [] a; } template class JaggedArray { public: JaggedArray (const int W, const int H, const bool initZero = false) { a = allocJaggedArray (W, H, initZero); } ~JaggedArray () { if (a) { freeJaggedArray (a); a = nullptr; } } JaggedArray (const JaggedArray&) = delete; JaggedArray& operator= (const JaggedArray&) = delete; public: operator T** const () const { return a; } private: T** a; }; // Declared but not defined to prevent // explicitly freeing a JaggedArray implicitly cast to T**. template void freeJaggedArray (JaggedArray&); } // rtengine #endif // JAGGEDARRAY_H