LAL: Linear Arrangement Library 23.01.00
A library focused on algorithms on linear arrangements of graphs.
Loading...
Searching...
No Matches
data_array.hpp
1/*********************************************************************
2 *
3 * Linear Arrangement Library - A library that implements a collection
4 * algorithms for linear arrangments of graphs.
5 *
6 * Copyright (C) 2019 - 2023
7 *
8 * This file is part of Linear Arrangement Library. The full code is available
9 * at:
10 * https://github.com/LAL-project/linear-arrangement-library.git
11 *
12 * Linear Arrangement Library is free software: you can redistribute it
13 * and/or modify it under the terms of the GNU Affero General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * Linear Arrangement Library is distributed in the hope that it will be
18 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public License
23 * along with Linear Arrangement Library. If not, see <http://www.gnu.org/licenses/>.
24 *
25 * Contact:
26 *
27 * LluĂ­s Alemany Puig (lalemany@cs.upc.edu)
28 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
29 * CQL (Complexity and Quantitative Linguistics Lab)
30 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
31 * Webpage: https://cqllab.upc.edu/people/lalemany/
32 *
33 * Ramon Ferrer i Cancho (rferrericancho@cs.upc.edu)
34 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
35 * CQL (Complexity and Quantitative Linguistics Lab)
36 * Office S124, Omega building
37 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
38 * Webpage: https://cqllab.upc.edu/people/rferrericancho/
39 *
40 ********************************************************************/
41
42#pragma once
43
44// C++ includes
45#if defined DEBUG
46#include <cassert>
47#endif
48#include <algorithm>
49
50namespace lal {
51namespace detail {
52
58template <typename T>
59struct data_array {
60public:
62 data_array() noexcept = default;
63
65 data_array(std::initializer_list<T> l) noexcept : m_size(l.size()) {
66 // (un?)fortunately, this will call the constructor of T
67 // for every element in m_data.
68 alloc_data();
69 // array reference
70 const T* list_data = std::data(l);
71 for (std::size_t i = 0; i < l.size(); ++i) {
72 // the data has to be be copied, it cannot be moved
73 // unless 'list_data' is const_cast<T *>-ed.
74 m_data[i] = list_data[i];
75 }
76 }
77
82 data_array(const std::size_t n) noexcept : m_size(n) {
83 alloc_data();
84 }
90 data_array(const std::size_t n, const T& v) noexcept : data_array(n) {
91 fill(v);
92 }
94 data_array(const data_array& d) noexcept : data_array(d.m_size) {
95 if (m_size > 0) {
96 std::copy(d.begin(), d.end(), begin());
97 }
98 }
100 data_array& operator= (const data_array& d) noexcept {
101 if (m_size != d.m_size) {
102 delete[] m_data;
103 m_size = d.m_size;
104 alloc_data();
105 }
106 if (m_size > 0) {
107 std::copy(d.begin(), d.end(), begin());
108 }
109 return *this;
110 }
111
113 data_array(data_array&& d) noexcept {
114 // steal data
115 m_data = d.m_data;
116 m_size = d.m_size;
117 // invalidate data
118 d.m_data = nullptr;
119 d.m_size = 0;
120 }
123 // free yourself
124 delete[] m_data;
125 // steal from others
126 m_data = d.m_data;
127 m_size = d.m_size;
128 // invalidate data
129 d.m_data = nullptr;
130 d.m_size = 0;
131 return *this;
132 }
133
134 /*
136 template <template <typename... Args> class container, typename... Types>
137 data_array(const container<Types...>& v) noexcept : data_array(v.size()) {
138 // assert first type in Types... is 'T'
139 static_assert(std::is_same_v<T, std::tuple_element_t<0, std::tuple<Types...>>>);
140
141 std::copy(v.begin(), v.end(), begin());
142 }
143
145 template <template <typename... Args> class container, typename... Types>
146 data_array& operator= (const container<Types...>& v) noexcept {
147 // assert first type in Types... is 'T'
148 static_assert(std::is_same_v<T, std::tuple_element_t<0, std::tuple<Types...>>>);
149
150 resize(v.size());
151 std::copy(v.begin(), v.end(), begin());
152 return *this;
153 }
154 */
155
157 ~data_array() noexcept {
158 clear();
159 }
160
162 void clear() noexcept {
163 delete[] m_data;
164 m_size = 0;
165 // this is for those who like calling the destructor...
166 m_data = nullptr;
167 }
168
175 void resize(std::size_t new_size) noexcept {
176 if (new_size != m_size or m_data == nullptr) {
177 delete[] m_data;
178 m_size = new_size;
179 alloc_data();
180 }
181 }
182
190 void resize(std::size_t new_size, const T& v) noexcept {
191 resize(new_size);
192 if (m_size > 0) {
193 fill(v);
194 }
195 }
196
203 [[nodiscard]]
204 std::size_t size() const noexcept { return m_size; }
205
212 [[nodiscard]]
213 T& operator[] (const std::size_t i) noexcept {
214#if defined DEBUG
215 assert(i < size());
216#endif
217 return m_data[i];
218 }
225 [[nodiscard]]
226 const T& operator[] (const std::size_t i) const noexcept {
227#if defined DEBUG
228 assert(i < size());
229#endif
230 return m_data[i];
231 }
232
234 [[nodiscard]] T& first() noexcept {
235#if defined DEBUG
236 assert(m_size > 0);
237#endif
238 return *m_data;
239 }
241 [[nodiscard]] const T& first() const noexcept {
242#if defined DEBUG
243 assert(m_size > 0);
244#endif
245 return *m_data;
246 }
248 [[nodiscard]] T& back() noexcept {
249#if defined DEBUG
250 assert(m_size > 0);
251#endif
252 return *(m_data + m_size - 1);
253 }
255 [[nodiscard]] const T& back() const noexcept {
256#if defined DEBUG
257 assert(m_size > 0);
258#endif
259 return *(m_data + m_size - 1);
260 }
261
263 void fill(const T& v) noexcept {
264 std::fill(begin(), end(), v);
265 }
266
272 [[nodiscard]] T *at(std::size_t i) noexcept {
273#if defined DEBUG
274 assert(i < m_size);
275#endif
276 return &m_data[i];
277 }
283 [[nodiscard]] T const *at(std::size_t i) const noexcept {
284#if defined DEBUG
285 assert(i < m_size);
286#endif
287 return &m_data[i];
288 }
289
291 [[nodiscard]] T *begin() noexcept { return m_data; }
293 [[nodiscard]] T *end() noexcept { return m_data + m_size; }
294
296 [[nodiscard]] T const *begin() const noexcept { return m_data; }
298 [[nodiscard]] T const *end() const noexcept { return m_data + m_size; }
299
300private:
303 void alloc_data() noexcept {
304 m_data = m_size == 0 ? nullptr : new T[m_size];
305 }
306
307protected:
309 T *m_data = nullptr;
311 std::size_t m_size = 0;
312};
313
314} // -- namespace detail
315} // -- namespace lal
Main namespace of the library.
Definition: basic_types.hpp:50
Wrapper of a C array for autmatic deallocation of memory.
Definition: data_array.hpp:59
data_array(data_array &&d) noexcept
Move constructor.
Definition: data_array.hpp:113
T * at(std::size_t i) noexcept
Pointer at a specific location of the array.
Definition: data_array.hpp:272
T * m_data
Pointer to the memory allocated by this array.
Definition: data_array.hpp:309
T & first() noexcept
Non-constant reference to the first element in the array.
Definition: data_array.hpp:234
data_array() noexcept=default
Default constructor.
data_array(const std::size_t n) noexcept
Constructor with size.
Definition: data_array.hpp:82
const T & back() const noexcept
Constant reference to the first element in the array.
Definition: data_array.hpp:255
const T & first() const noexcept
Constant reference to the first element in the array.
Definition: data_array.hpp:241
void fill(const T &v) noexcept
Assign the same value to every element in the data.
Definition: data_array.hpp:263
data_array & operator=(const data_array &d) noexcept
Copy assignment operator.
Definition: data_array.hpp:100
data_array(const std::size_t n, const T &v) noexcept
Constructor with size.
Definition: data_array.hpp:90
std::size_t size() const noexcept
Size of the array.
Definition: data_array.hpp:204
T & operator[](const std::size_t i) noexcept
Element at position i.
Definition: data_array.hpp:213
void resize(std::size_t new_size, const T &v) noexcept
Resize-initialize the array.
Definition: data_array.hpp:190
void alloc_data() noexcept
Definition: data_array.hpp:303
T const * at(std::size_t i) const noexcept
Pointer at a specific location of the array.
Definition: data_array.hpp:283
void resize(std::size_t new_size) noexcept
Resize the array.
Definition: data_array.hpp:175
void clear() noexcept
Clear the contents of the array.
Definition: data_array.hpp:162
T & back() noexcept
Non-constant reference to the last element in the array.
Definition: data_array.hpp:248
T * end() noexcept
Non-constant raw pointer to last+1 element.
Definition: data_array.hpp:293
std::size_t m_size
The size of this array in number of elements.
Definition: data_array.hpp:311
T const * begin() const noexcept
Constant raw pointer to first element.
Definition: data_array.hpp:296
data_array(const data_array &d) noexcept
Copy constructor.
Definition: data_array.hpp:94
T * begin() noexcept
Non-constant raw pointer to first element.
Definition: data_array.hpp:291
T const * end() const noexcept
Constant raw pointer to last+1 element.
Definition: data_array.hpp:298
~data_array() noexcept
Destructor.
Definition: data_array.hpp:157