diff options
Diffstat (limited to 'src/utils/array_2d.h')
-rw-r--r-- | src/utils/array_2d.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/utils/array_2d.h b/src/utils/array_2d.h new file mode 100644 index 0000000..2df6241 --- /dev/null +++ b/src/utils/array_2d.h @@ -0,0 +1,131 @@ +/* + * Copyright 2019 The libgav1 Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBGAV1_SRC_UTILS_ARRAY_2D_H_ +#define LIBGAV1_SRC_UTILS_ARRAY_2D_H_ + +#include <cassert> +#include <cstddef> +#include <cstring> +#include <memory> +#include <new> +#include <type_traits> + +#include "src/utils/compiler_attributes.h" + +namespace libgav1 { + +// Exposes a 1D allocated memory buffer as a 2D array. +template <typename T> +class Array2DView { + public: + Array2DView() = default; + Array2DView(int rows, int columns, T* const data) { + Reset(rows, columns, data); + } + + // Copyable and Movable. + Array2DView(const Array2DView& rhs) = default; + Array2DView& operator=(const Array2DView& rhs) = default; + + void Reset(int rows, int columns, T* const data) { + rows_ = rows; + columns_ = columns; + data_ = data; + } + + int rows() const { return rows_; } + int columns() const { return columns_; } + + T* operator[](int row) { return const_cast<T*>(GetRow(row)); } + + const T* operator[](int row) const { return GetRow(row); } + + private: + const T* GetRow(int row) const { + assert(row < rows_); + const ptrdiff_t offset = static_cast<ptrdiff_t>(row) * columns_; + return data_ + offset; + } + + int rows_ = 0; + int columns_ = 0; + T* data_ = nullptr; +}; + +// Allocates and owns the contiguous memory and exposes an Array2DView of +// dimension |rows| x |columns|. +template <typename T> +class Array2D { + public: + Array2D() = default; + + // Copyable and Movable. + Array2D(const Array2D& rhs) = default; + Array2D& operator=(const Array2D& rhs) = default; + + LIBGAV1_MUST_USE_RESULT bool Reset(int rows, int columns, + bool zero_initialize = true) { + size_ = rows * columns; + // If T is not a trivial type, we should always reallocate the data_ + // buffer, so that the destructors of any existing objects are invoked. + if (!std::is_trivial<T>::value || allocated_size_ < size_) { + // Note: This invokes the global operator new if T is a non-class type, + // such as integer or enum types, or a class type that is not derived + // from libgav1::Allocable, such as std::unique_ptr. If we enforce a + // maximum allocation size or keep track of our own heap memory + // consumption, we will need to handle the allocations here that use the + // global operator new. + if (zero_initialize) { + data_.reset(new (std::nothrow) T[size_]()); + } else { + data_.reset(new (std::nothrow) T[size_]); + } + if (data_ == nullptr) { + allocated_size_ = 0; + return false; + } + allocated_size_ = size_; + } else if (zero_initialize) { + // Cast the data_ pointer to void* to avoid the GCC -Wclass-memaccess + // warning. The memset is safe because T is a trivial type. + void* dest = data_.get(); + memset(dest, 0, sizeof(T) * size_); + } + data_view_.Reset(rows, columns, data_.get()); + return true; + } + + int rows() const { return data_view_.rows(); } + int columns() const { return data_view_.columns(); } + size_t size() const { return size_; } + T* data() { return data_.get(); } + const T* data() const { return data_.get(); } + + T* operator[](int row) { return data_view_[row]; } + + const T* operator[](int row) const { return data_view_[row]; } + + private: + std::unique_ptr<T[]> data_ = nullptr; + size_t allocated_size_ = 0; + size_t size_ = 0; + Array2DView<T> data_view_; +}; + +} // namespace libgav1 + +#endif // LIBGAV1_SRC_UTILS_ARRAY_2D_H_ |