156 lines
4.2 KiB
C++
156 lines
4.2 KiB
C++
// File: crn_vector2d.h
|
|
#pragma once
|
|
|
|
namespace crnlib
|
|
{
|
|
template <typename T>
|
|
class vector2D
|
|
{
|
|
public:
|
|
typedef crnlib::vector<T> vector_type;
|
|
typedef T value_type;
|
|
typedef T& reference;
|
|
typedef const T& const_reference;
|
|
typedef T* pointer;
|
|
typedef const T* const_pointer;
|
|
|
|
inline vector2D(uint width = 0, uint height = 0, const T& def = T()) :
|
|
m_width(width),
|
|
m_height(height),
|
|
m_vec(width * height),
|
|
m_def(def)
|
|
{
|
|
}
|
|
|
|
inline vector2D(const vector2D& other) :
|
|
m_width(other.m_width),
|
|
m_height(other.m_height),
|
|
m_vec(other.m_vec),
|
|
m_def(other.m_def)
|
|
{
|
|
}
|
|
|
|
inline vector2D& operator= (const vector2D& rhs)
|
|
{
|
|
if (this == &rhs)
|
|
return *this;
|
|
|
|
m_width = rhs.m_width;
|
|
m_height = rhs.m_height;
|
|
m_vec = rhs.m_vec;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool try_resize(uint width, uint height, bool preserve = true)
|
|
{
|
|
if ((width == m_width) && (height == m_height))
|
|
return true;
|
|
|
|
vector_type new_vec;
|
|
if (!new_vec.try_resize(width * height))
|
|
return false;
|
|
|
|
if (preserve)
|
|
{
|
|
const uint nx = math::minimum(width, m_width);
|
|
const uint ny = math::minimum(height, m_height);
|
|
|
|
for (uint y = 0; y < ny; y++)
|
|
{
|
|
const T* pSrc = &m_vec[y * m_width];
|
|
T* pDst = &new_vec[y * width];
|
|
if (CRNLIB_IS_BITWISE_COPYABLE_OR_MOVABLE(T))
|
|
memcpy(pDst, pSrc, nx * sizeof(T));
|
|
else
|
|
{
|
|
for (uint x = 0; x < nx; x++)
|
|
*pDst++ = *pSrc++;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_width = width;
|
|
m_height = height;
|
|
m_vec.swap(new_vec);
|
|
|
|
return true;
|
|
}
|
|
|
|
void resize(uint width, uint height, bool preserve = true)
|
|
{
|
|
if (!try_resize(width, height, preserve))
|
|
{
|
|
CRNLIB_FAIL("vector2D::resize: Out of memory");
|
|
}
|
|
}
|
|
|
|
inline void clear()
|
|
{
|
|
m_vec.clear();
|
|
m_width = 0;
|
|
m_height = 0;
|
|
}
|
|
|
|
inline uint width() const { return m_width; }
|
|
inline uint height() const { return m_height; }
|
|
inline uint size() const { return m_vec.size(); }
|
|
|
|
inline uint size_in_bytes() const { return m_vec.size() * sizeof(T); }
|
|
|
|
const vector_type& get_vec() const { return m_vec; }
|
|
vector_type& get_vec() { return m_vec; }
|
|
|
|
inline const T* get_ptr() const { return m_vec.get_ptr(); }
|
|
inline T* get_ptr() { return m_vec.get_ptr(); }
|
|
|
|
inline const T& operator[] (uint i) const { return m_vec[i]; }
|
|
inline T& operator[] (uint i) { return m_vec[i]; }
|
|
|
|
inline const T& operator() (uint x, uint y) const
|
|
{
|
|
CRNLIB_ASSERT((x < m_width) && (y < m_height));
|
|
return m_vec[x + y * m_width];
|
|
}
|
|
|
|
inline T& operator() (uint x, uint y)
|
|
{
|
|
CRNLIB_ASSERT((x < m_width) && (y < m_height));
|
|
return m_vec[x + y * m_width];
|
|
}
|
|
|
|
inline const T& at (uint x, uint y) const
|
|
{
|
|
if ((x >= m_width) || (y >= m_height))
|
|
return m_def;
|
|
return m_vec[x + y * m_width];
|
|
}
|
|
|
|
inline T& at (uint x, uint y)
|
|
{
|
|
if ((x >= m_width) || (y >= m_height))
|
|
return m_def;
|
|
return m_vec[x + y * m_width];
|
|
}
|
|
|
|
inline void swap(vector2D& other)
|
|
{
|
|
m_vec.swap(other.m_vec);
|
|
anvil::swap(m_width, other.m_width);
|
|
anvil::swap(m_height, other.m_height);
|
|
}
|
|
|
|
inline void set_all(const T& x)
|
|
{
|
|
m_vec.set_all(x);
|
|
}
|
|
|
|
private:
|
|
vector_type m_vec;
|
|
uint m_width;
|
|
uint m_height;
|
|
T m_def;
|
|
};
|
|
|
|
} // namespace anvil
|