5#include <initializer_list>
9#include <unordered_map>
12typedef unsigned int row_size_t;
13typedef unsigned int row_id_t;
14typedef unsigned long int data_size_t;
28 static_assert(std::is_arithmetic<T>::value,
"skipzero_span: Template parameter T must be an arithmetic type");
35 using iterator_category = std::contiguous_iterator_tag;
36 using difference_type = std::ptrdiff_t;
49 reference operator*()
const {
return *m_ptr; }
50 pointer operator->() {
return m_ptr; }
72 skip_zeros_backward();
85 friend difference_type operator-(
const Iterator& a,
const Iterator& b) {
return a.m_ptr - b.m_ptr; }
86 friend bool operator==(
const Iterator& a,
const Iterator& b) {
return a.m_ptr == b.m_ptr; }
87 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return a.m_ptr != b.m_ptr; }
92 while (m_ptr != m_end && *m_ptr == 0) {
97 void skip_zeros_backward()
99 while (m_ptr != m_begin && *m_ptr == 0) {
105 const pointer m_begin;
116 : m_begin(vec.data())
117 , m_end(vec.data() + vec.size())
120 for (T number : vec) {
126 Iterator begin()
const {
return Iterator(m_begin, m_end); }
127 Iterator end()
const {
return Iterator(m_end, m_end); }
129 row_size_t capacity()
const {
return m_end - m_begin; }
130 row_size_t size()
const {
return this->m_size; }
132 T* data() {
return m_begin; }
133 const T* data()
const {
return m_begin; }
135 T& front() {
return *this->begin(); }
136 const T& front()
const {
return *this->begin(); }
138 T& back() {
return *(--this->end()); }
139 const T& back()
const {
return *(--this->end()); }
149#define CHECK_BOUNDS(i) ((void)0)
151#define CHECK_BOUNDS(i) \
153 if (!ROW_SIZE(i)) { \
154 throw std::invalid_argument("Clause at given index is deleted"); \
156 if (i >= capacities.size() || i >= indexes.size()) { \
157 throw std::out_of_range("Index out of range"); \
162#define ROW_SIZE(i) this->data[indexes[i]]
163#define ROW_BEGIN(i) this->indexes[i] + 1
164#define ROW_CAP(i) this->capacities[i]
165#define ROW_END(i) ROW_BEGIN(i) + ROW_CAP(i)
176 static_assert(std::is_arithmetic<T>::value,
"vector2D: Template parameter T must be an arithmetic type");
205 inline T*
end(row_id_t
id);
212 inline const T*
begin(row_id_t
id)
const;
219 inline const T*
end(row_id_t
id)
const;
232 inline row_size_t
getRowsCount()
const {
return this->indexes.size(); };
267 std::vector<row_size_t> capacities;
268 std::vector<data_size_t> indexes;
269 std::unordered_map<row_size_t, data_size_t> freeRows;
298 return (data.data() + ROW_BEGIN(
id));
307 return (data.data() + ROW_END(
id));
315 return (data.data() + ROW_BEGIN(
id));
324 return (data.data() + ROW_END(
id));
344 indexes.push_back(data.size());
345 data.push_back(row.size());
346 capacities.push_back(row.size());
347 data.insert(data.end(), row.begin(), row.end());
357 indexes.push_back(data.size());
358 data.push_back(row.size());
359 capacities.push_back(row.size());
360 data.insert(data.end(), row.begin(), row.end());
380 data_size_t i = ROW_BEGIN(rowId) + offset;
381 assert(i < data.size());
384 if (--ROW_SIZE(rowId) == 0)
395 std::vector<T> newData;
396 std::vector<row_size_t> newCapacities;
397 std::vector<data_size_t> newIndexes;
400 newData.reserve(data.size());
402 for (row_id_t rowId = 0; rowId < indexes.size(); ++rowId) {
403 if (ROW_SIZE(rowId) == 0) {
407 newIndexes.push_back(newData.size());
408 newCapacities.push_back(ROW_SIZE(rowId));
409 data_size_t start = ROW_BEGIN(rowId);
410 data_size_t end = ROW_END(rowId);
412 for (data_size_t i = start; i < end; ++i) {
414 newData.push_back(data[i]);
420 data = std::move(newData);
421 capacities = std::move(newCapacities);
422 indexes = std::move(newIndexes);
425 data.shrink_to_fit();
426 capacities.shrink_to_fit();
427 indexes.shrink_to_fit();
Definition vector2D.hpp:33
A span-like container that skips zero elements when iterating.
Definition vector2D.hpp:27
A 2D vector implementation optimized for sparse data.
Definition vector2D.hpp:175
void emplace_row(std::initializer_list< int > row)
Adds a new row to the 2D vector using an initializer list.
Definition vector2D.hpp:352
void cleanup()
Cleans up the 2D vector by removing deleted rows and compacting data.
Definition vector2D.hpp:393
T * begin(row_id_t id)
Gets the beginning iterator for a specific row.
Definition vector2D.hpp:295
skipzero_span< T > operator[](row_id_t id)
Accesses a row in the 2D vector.
Definition vector2D.hpp:279
void delete_row(row_id_t id)
Marks a row as deleted.
Definition vector2D.hpp:368
const T * end(row_id_t id) const
Gets the end const iterator for a specific row.
Definition vector2D.hpp:320
T * end(row_id_t id)
Gets the end iterator for a specific row.
Definition vector2D.hpp:303
row_size_t getRowsCount() const
Gets the number of rows in the 2D vector.
Definition vector2D.hpp:232
row_size_t getRowSize(row_id_t id) const
Gets the size of a specific row.
Definition vector2D.hpp:329
bool delete_element(row_id_t rowId, row_size_t offset)
Deletes an element in a specific row.
Definition vector2D.hpp:376
const T * begin(row_id_t id) const
Gets the beginning const iterator for a specific row.
Definition vector2D.hpp:312
skipzero_span< const T > operator[](row_id_t id) const
Accesses a row in the 2D vector (const version).
Definition vector2D.hpp:287
void push_row(const std::vector< int > &row)
Adds a new row to the 2D vector.
Definition vector2D.hpp:340