canvas.h

 avatar
unknown
c_cpp
23 days ago
1.8 kB
2
Indexable
#ifndef CANVAS_H
#define CANVAS_H

#include "aligned_vector.h"

#include <stdexcept>
#include <type_traits>

template<typename T, size_t Alignment = DEFAULT_MEMORY_ALIGNMENT>
class Canvas
{
	static_assert(std::is_trivially_copyable_v<T>);

public:

	Canvas(size_t a_width, size_t a_height, const T & a_fillValue = T()) :
		  m_width(a_width)
		, m_height(a_height)
	{
		if((a_width == 0) || (a_height == 0))
			throw std::bad_array_new_length();

		m_rowSize = a_width * sizeof(T);
		m_stride = ((m_rowSize + Alignment - 1) / Alignment) * Alignment;
		m_data = std::move(aligned_vector<T, Alignment>(m_height * m_stride, a_fillValue));
	}

	Canvas(const Canvas & a_other) = default;
	Canvas(Canvas && a_other) = default;
	Canvas & operator=(const Canvas & a_other) = default;
	Canvas & operator=(Canvas && a_other) = default;

	virtual ~Canvas() = default;

	size_t width() const
	{
		return m_width;
	}

	size_t height() const
	{
		return m_height;
	}

	size_t stride() const
	{
		return m_stride;
	}

	size_t rowSize() const
	{
		return m_rowSize;
	}

	std::byte * bytes()
	{
		return (std::byte *)m_data.data();
	}

	const std::byte * bytes() const
	{
		return (const std::byte *)m_data.data();
	}

	const T * operator[](size_t a_row) const
	{
		return (const T *)(bytes() + a_row * m_stride);
	}

	T * operator[](size_t a_row)
	{
		return (T *)(bytes() + a_row * m_stride);
	}

	[[nodiscard]] Canvas resized(size_t a_width, size_t a_height, const T & a_fillValue = T()) const
	{
		Canvas newCanvas(a_width, a_height, a_fillValue);

		for(size_t i = 0; i < std::min(m_height, a_height); ++i)
			memcpy(newCanvas[i], operator[](i), std::min(m_rowSize, newCanvas.rowSize()));

		return newCanvas;
	}

protected:

	size_t m_width{0};
	size_t m_height{0};
	size_t m_stride{0};
	size_t m_rowSize{0};

	aligned_vector<T, Alignment> m_data;
};

#endif
Leave a Comment