pcsx2/common/HeapArray.h

119 lines
2.9 KiB
C
Raw Normal View History

2022-12-04 14:51:05 +00:00
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <algorithm>
#include <cassert>
#include <type_traits>
template <typename T, std::size_t SIZE>
class HeapArray
{
public:
using value_type = T;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using this_type = HeapArray<T, SIZE>;
HeapArray() { m_data = new T[SIZE]; }
HeapArray(const this_type& copy)
{
m_data = new T[SIZE];
std::copy(copy.cbegin(), copy.cend(), begin());
}
HeapArray(this_type&& move)
{
m_data = move.m_data;
move.m_data = nullptr;
}
~HeapArray() { delete[] m_data; }
size_type size() const { return SIZE; }
size_type capacity() const { return SIZE; }
bool empty() const { return false; }
pointer begin() { return m_data; }
pointer end() { return m_data + SIZE; }
const_pointer data() const { return m_data; }
pointer data() { return m_data; }
const_pointer cbegin() const { return m_data; }
const_pointer cend() const { return m_data + SIZE; }
const_reference operator[](size_type index) const
{
assert(index < SIZE);
return m_data[index];
}
reference operator[](size_type index)
{
assert(index < SIZE);
return m_data[index];
}
const_reference front() const { return m_data[0]; }
const_reference back() const { return m_data[SIZE - 1]; }
reference front() { return m_data[0]; }
reference back() { return m_data[SIZE - 1]; }
void fill(const_reference value) { std::fill(begin(), end(), value); }
void swap(this_type& move) { std::swap(m_data, move.m_data); }
this_type& operator=(const this_type& rhs)
{
std::copy(begin(), end(), rhs.cbegin());
return *this;
}
this_type& operator=(this_type&& move)
{
delete[] m_data;
m_data = move.m_data;
move.m_data = nullptr;
return *this;
}
#define RELATIONAL_OPERATOR(op) \
bool operator op(const this_type& rhs) const \
{ \
for (size_type i = 0; i < SIZE; i++) \
{ \
if (!(m_data[i] op rhs.m_data[i])) \
return false; \
} \
}
RELATIONAL_OPERATOR(==);
RELATIONAL_OPERATOR(!=);
RELATIONAL_OPERATOR(<);
RELATIONAL_OPERATOR(<=);
RELATIONAL_OPERATOR(>);
RELATIONAL_OPERATOR(>=);
#undef RELATIONAL_OPERATOR
private:
T* m_data;
};