Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_ca_storage_test.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
41# include <cstdint>
42# include <limits>
43# include <stdexcept>
44# include <type_traits>
45# include <utility>
46
47# include <gtest/gtest.h>
48
49# include <tpl_ca_concepts.H>
50# include <tpl_ca_storage.H>
51# include <tpl_ca_bit_storage.H>
52
53using namespace Aleph;
54using namespace Aleph::CA;
55
56// ---------------------------------------------------------------------------
57// Concept conformance — these are compile-time checks; if any fails the
58// test binary will not link.
59// ---------------------------------------------------------------------------
60
67
68// ---------------------------------------------------------------------------
69// Dense_Cell_Storage
70// ---------------------------------------------------------------------------
71
81
83{
84 Dense_Cell_Storage<int, 2> s({ 3, 4 }, 7);
85 EXPECT_EQ(s.size(), 12u);
86 EXPECT_EQ(s.size(0), 3u);
87 EXPECT_EQ(s.size(1), 4u);
88 for (ca_index_t i = 0; i < 3; ++i)
89 for (ca_index_t j = 0; j < 4; ++j)
90 EXPECT_EQ(s.at(i, j), 7);
91}
92
94{
96 // Row-major: idx = i*4 + j
97 EXPECT_EQ(s.linear_index({ 0, 0 }), 0u);
98 EXPECT_EQ(s.linear_index({ 0, 3 }), 3u);
99 EXPECT_EQ(s.linear_index({ 1, 0 }), 4u);
100 EXPECT_EQ(s.linear_index({ 2, 3 }), 11u);
101}
102
104{
105 Dense_Cell_Storage<int, 2> s({ 3, 4 }, 0);
106 s.set(1, 2, 42);
107 EXPECT_EQ(s.at(1, 2), 42);
108 EXPECT_EQ(s.at(0, 0), 0);
109 // Underlying buffer respects row-major:
110 EXPECT_EQ(s.data()[1 * 4 + 2], 42);
111}
112
114{
115 Dense_Cell_Storage<std::uint8_t, 3> s({ 2, 2, 2 }, 0);
116 s.set(1, 0, 1, 9);
117 s.set(0, 1, 1, 5);
118 EXPECT_EQ(s.at(1, 0, 1), 9);
119 EXPECT_EQ(s.at(0, 1, 1), 5);
120 EXPECT_EQ(s.size(), 8u);
121}
122
124{
125 Dense_Cell_Storage<int, 1> s({ 5 }, -1);
126 for (ca_index_t i = 0; i < 5; ++i)
127 EXPECT_EQ(s.at(i), -1);
128 s.set(2, 100);
129 EXPECT_EQ(s.at(2), 100);
130}
131
133{
134 Dense_Cell_Storage<int, 2> s({ 3, 4 }, 0);
135 EXPECT_THROW(s.at(3, 0), std::out_of_range);
136 EXPECT_THROW(s.at(0, 4), std::out_of_range);
137 EXPECT_THROW(s.at(-1, 0), std::out_of_range);
138 EXPECT_THROW(s.at(0, -1), std::out_of_range);
139 EXPECT_THROW(s.set({ -1, 0 }, 1), std::out_of_range);
140 EXPECT_THROW(s.size(2), std::out_of_range);
141}
142
144{
145 Dense_Cell_Storage<int, 2> s({ 3, 3 }, 0);
146 s.set(0, 0, 1); s.set(1, 1, 2); s.set(2, 2, 3);
147 s.fill(99);
148 for (ca_index_t i = 0; i < 3; ++i)
149 for (ca_index_t j = 0; j < 3; ++j)
150 EXPECT_EQ(s.at(i, j), 99);
151}
152
154{
155 Dense_Cell_Storage<int, 2> a({ 3, 3 }, 1);
156 Dense_Cell_Storage<int, 2> b({ 4, 4 }, 2);
157 const int * pa = a.data();
158 const int * pb = b.data();
159
160 a.swap(b);
161
162 EXPECT_EQ(a.size(0), 4u);
163 EXPECT_EQ(a.size(1), 4u);
164 EXPECT_EQ(b.size(0), 3u);
165 EXPECT_EQ(b.size(1), 3u);
166 // Pointers should follow the data, not the object slot.
167 EXPECT_EQ(a.data(), pb);
168 EXPECT_EQ(b.data(), pa);
169 EXPECT_EQ(a.at(0, 0), 2);
170 EXPECT_EQ(b.at(0, 0), 1);
171}
172
174{
175 Dense_Cell_Storage<int, 2> a({ 2, 2 }, 1);
176 Dense_Cell_Storage<int, 2> b({ 2, 2 }, 9);
177 swap(a, b);
178 EXPECT_EQ(a.at(0, 0), 9);
179 EXPECT_EQ(b.at(0, 0), 1);
180}
181
183{
184 Dense_Cell_Storage<int, 2> s({ 3, 4 }, 0);
185 auto v = s.view();
186 EXPECT_EQ(v.rank(), 2u);
187 EXPECT_EQ(v.extent(0), 3u);
188 EXPECT_EQ(v.extent(1), 4u);
189 EXPECT_EQ(v.data_handle(), s.data());
190}
191
193{
195 auto v = s.view();
196 EXPECT_EQ(v.size(), 0u);
197 EXPECT_EQ(v.data_handle(), nullptr);
198}
199
201{
202 Dense_Cell_Storage<int, 2> s({ 3, 4 }, 0);
203 auto v = s.view();
204 v(1, 2) = 42;
205 EXPECT_EQ(s.at(1, 2), 42);
206}
207
209{
210 Dense_Cell_Storage<int, 2> s({ 3, 4 }, 0);
211 auto v = s.view();
212 s.set(0, 0, 7);
213 EXPECT_EQ(v(0, 0), 7);
214}
215
217{
218 Dense_Cell_Storage<int, 2> s({ 2, 2 }, 5);
219 const auto &cs = s;
220 auto cv = cs.view();
221 EXPECT_EQ(cv(0, 0), 5);
222 static_assert(std::is_const_v<std::remove_reference_t<decltype(cv(0, 0))>>);
223}
224
226{
227 Dense_Cell_Storage<int, 2> s({ 2, 3 });
228 auto v = s.view();
229 int next = 0;
230 for (ca_size_t i = 0; i < v.extent(0); ++i)
231 for (ca_size_t j = 0; j < v.extent(1); ++j)
232 v(i, j) = next++;
233
234 next = 0;
235 for (ca_index_t i = 0; i < 2; ++i)
236 for (ca_index_t j = 0; j < 3; ++j)
237 EXPECT_EQ(s.at(i, j), next++);
238}
239
241{
242 Dense_Cell_Storage<int, 3> s({ 2, 2, 2 }, -1);
243 auto v = s.view();
244 v(1, 0, 1) = 99;
245 EXPECT_EQ(s.at(1, 0, 1), 99);
246 EXPECT_EQ(v.size(), s.size());
247}
248
250{
251 Dense_Cell_Storage<int, 2> a({ 3, 3 }, 4);
252 const int * p = a.data();
253 Dense_Cell_Storage<int, 2> b(std::move(a));
254 EXPECT_EQ(b.size(), 9u);
255 EXPECT_EQ(b.data(), p);
256 EXPECT_EQ(b.at(0, 0), 4);
257}
258
259// ---------------------------------------------------------------------------
260// Bit_Cell_Storage
261// ---------------------------------------------------------------------------
262
269
271{
272 Bit_Cell_Storage<2> s({ 5, 7 }, true);
273 EXPECT_EQ(s.size(), 35u);
274 for (ca_index_t i = 0; i < 5; ++i)
275 for (ca_index_t j = 0; j < 7; ++j)
276 EXPECT_TRUE(s.at(i, j));
277}
278
280{
281 Bit_Cell_Storage<2> s({ 4, 4 }, false);
282 s.set(1, 2, true);
283 s.set(3, 3, true);
284 for (ca_index_t i = 0; i < 4; ++i)
285 for (ca_index_t j = 0; j < 4; ++j)
286 EXPECT_EQ(s.at(i, j),
287 (i == 1 and j == 2) or (i == 3 and j == 3));
288}
289
291{
292 Bit_Cell_Storage<2> s({ 3, 5 }, false);
293 EXPECT_EQ(s.linear_index({ 0, 0 }), 0u);
294 EXPECT_EQ(s.linear_index({ 0, 4 }), 4u);
295 EXPECT_EQ(s.linear_index({ 2, 4 }), 14u);
296}
297
299{
300 Bit_Cell_Storage<1> s({ 17 }, false); // not byte-aligned
301 s.fill(true);
302 for (ca_index_t i = 0; i < 17; ++i)
303 EXPECT_TRUE(s.at(i));
304 s.fill(false);
305 for (ca_index_t i = 0; i < 17; ++i)
306 EXPECT_FALSE(s.at(i));
307}
308
310{
311 Bit_Cell_Storage<2> a({ 3, 3 }, true);
312 Bit_Cell_Storage<2> b({ 4, 4 }, false);
313 a.swap(b);
314 EXPECT_EQ(a.size(0), 4u);
315 EXPECT_EQ(b.size(0), 3u);
316 EXPECT_FALSE(a.at(0, 0));
317 EXPECT_TRUE(b.at(0, 0));
318}
319
321{
322 Bit_Cell_Storage<2> s({ 3, 3 }, false);
323 EXPECT_THROW(s.at(3, 0), std::out_of_range);
324 EXPECT_THROW(s.at(-1, 0), std::out_of_range);
325 EXPECT_THROW(s.set({ 0, 3 }, true), std::out_of_range);
326}
327
329{
330 Bit_Cell_Storage<3> s({ 2, 2, 2 }, false);
331 s.set(1, 1, 1, true);
332 EXPECT_TRUE(s.at(1, 1, 1));
333 EXPECT_FALSE(s.at(0, 0, 0));
334 EXPECT_EQ(s.size(), 8u);
335}
336
338{
339 constexpr ca_size_t max = std::numeric_limits<ca_size_t>::max();
340 EXPECT_THROW((Bit_Cell_Storage<2>({ max, 2 }, false)),
341 std::overflow_error);
342}
Bit-packed row-major storage for N-dimensional binary CAs.
void fill(const bool value)
Set every cell to value.
ca_size_t size() const noexcept
static constexpr std::size_t dimension() noexcept
void swap(Bit_Cell_Storage &other) noexcept
Swap contents with another Bit_Cell_Storage instance.
void set(const coord_type &c, bool v)
Write the cell at coordinate c.
Row-major dense storage for N-dimensional cellular automata.
ca_size_t size() const noexcept
static constexpr std::size_t dimension() noexcept
view_type view() noexcept
Return a mutable Aleph::mdspan view of this storage.
const extents_type & extents() const noexcept
T at(const coord_type &c) const
Read access through a multi-index.
void set(const coord_type &c, const T &v)
Write access through a multi-index.
static constexpr std::size_t rank
Number of axes known at compile time.
#define TEST(name)
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_max_function > > max(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4121
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Definition ca-traits.H:63
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
T & swap(T &t1, T &t2)
Generic swap using object's swap method.
Definition ahTypes.H:121
and
Check uniqueness with explicit hash + equality functors.
void next()
Advance all underlying iterators (bounds-checked).
Definition ah-zip.H:171
Bit-packed dense storage for boolean cellular automata.
C++20 concepts for the Cellular Automata module.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).