Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
array-it.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
33
38# include <gtest/gtest.h>
39
40# include <array_it.H>
41
42using namespace std;
43using namespace testing;
44using namespace Aleph;
45
47{
48 Array_Container<int> a(nullptr, 0);
50 EXPECT_EQ(a.size(), 0);
51 EXPECT_THROW(a.get_first(), std::underflow_error);
52 EXPECT_THROW(a.get_last(), std::underflow_error);
53}
54
64
66{
67 int ptr[4] = {0, 1, 2, 3};
68 auto c = make_array_container(ptr, 4);
69
70 EXPECT_FALSE(c.is_empty());
71 EXPECT_EQ(c.size(), 4);
72 EXPECT_EQ(c.get_first(), 0);
73 EXPECT_EQ(c.get_last(), 3);
74
75 auto it = c.get_it();
76 for (int i = 0; it.has_curr(); it.next(), ++i)
77 EXPECT_EQ(it.get_curr(), i);
78}
79
80// Constness of an Array_Container is shallow, like std::span: a const view
81// still writes through. A read-only view is obtained with a const element type.
83{
84 int data[4] = {1, 2, 3, 4};
85 const Array_Container<int> shallow(data, 4);
86 shallow.get_first() = 10; // a const view of int still writes through
87 EXPECT_EQ(data[0], 10);
88
89 const int values[4] = {1, 2, 3, 4};
90 Array_Container<const int> view(values, 4);
91 static_assert(std::is_const_v<std::remove_reference_t<decltype(view.get_first())>>);
92 static_assert(std::is_const_v<std::remove_reference_t<decltype(view.get_last())>>);
93 static_assert(std::is_const_v<std::remove_pointer_t<decltype(view.get_base())>>);
94 static_assert(std::is_const_v<std::remove_reference_t<decltype(view.get_it().get_curr())>>);
95 static_assert(not std::is_assignable_v<decltype(view.get_first()), int>);
96
97 EXPECT_EQ(view.get_first(), 1);
98 EXPECT_EQ(view.get_last(), 4);
99 int sum = 0;
100 for (auto it = view.get_it(); it.has_curr(); it.next_ne())
101 sum += it.get_curr();
102 EXPECT_EQ(sum, 10);
103 EXPECT_EQ(view.foldl(0, [](const int &acc, const int &x) { return acc + x; }), 10);
104}
105
107{
108 int ptr[20];
109 Array_Iterator<int> it(ptr, 10, 0);
111 EXPECT_THROW(it.get_curr(), std::overflow_error);
112 EXPECT_THROW(it.next(), std::overflow_error);
113 EXPECT_THROW(it.prev(), std::underflow_error);
114
115 it.reset();
117 EXPECT_THROW(it.get_curr(), std::overflow_error);
118 EXPECT_THROW(it.next(), std::overflow_error);
119 EXPECT_THROW(it.prev(), std::underflow_error);
120
121 it.reset_last();
123 EXPECT_THROW(it.get_curr(), std::underflow_error);
124 EXPECT_THROW(it.next(), std::overflow_error);
125 EXPECT_THROW(it.prev(), std::underflow_error);
126}
127
129{
132 EXPECT_FALSE(singular.has_curr());
133 EXPECT_FALSE(singular.is_last());
134
135 int values[2] = {1, 2};
136 Array_Iterator<int> it(values, 2, 0);
137 it.reset_last();
139 EXPECT_FALSE(it.is_last());
140
141 Array_Iterator<int> nonempty(values, 2, 2);
142 EXPECT_FALSE(nonempty.is_last());
143 nonempty.reset_last();
144 EXPECT_TRUE(nonempty.is_last());
145 nonempty.end();
146 EXPECT_FALSE(nonempty.is_last());
147}
148
150{
151 int ptr[10];
152
153 EXPECT_THROW(Array_Iterator<int>(nullptr, 5, 1), std::invalid_argument);
154 EXPECT_THROW(Array_Iterator<int>(ptr, 5, 6), std::domain_error);
155 EXPECT_THROW(Array_Iterator<int>(ptr, 0, 1), std::domain_error);
156 EXPECT_THROW(Array_Iterator<int>(ptr, 5, 3, 4, 5), std::domain_error);
157
158 EXPECT_NO_THROW(Array_Iterator<int>(ptr, 5, 3, 1, 2));
159}
160
161constexpr size_t N = 29;
162
163struct Array_of_n_items : public testing::Test
164{
165 size_t n = 0;
166 int * a = nullptr;
168 {
169 for (size_t i = 0; i < N; ++i, ++n)
170 a[i] = i;
171 }
172 ~Array_of_n_items() { delete [] a; }
173};
174
176{
177 Array_Iterator<int> it = { a, n, n };
178
179 EXPECT_TRUE(it.has_curr());
181 for (size_t i = 0; it.has_curr(); it.next(), ++i)
182 ASSERT_EQ(it.get_curr(), i);
183 EXPECT_THROW(it.get_curr(), std::overflow_error);
184 EXPECT_THROW(it.next(), std::overflow_error);
185
186 it.reset();
187 EXPECT_TRUE(it.has_curr());
189 for (size_t i = 0; it.has_curr(); it.next(), ++i)
190 ASSERT_EQ(it.get_curr(), i);
191 EXPECT_THROW(it.get_curr(), std::overflow_error);
192 EXPECT_THROW(it.next(), std::overflow_error);
193 EXPECT_NO_THROW(it.prev());
194 EXPECT_EQ(it.get_curr(), n - 1);
195
196 it.reset_last();
197 EXPECT_TRUE(it.has_curr());
199 for (size_t i = n - 1; it.has_curr(); it.prev(), --i)
200 ASSERT_EQ(it.get_curr(), i);
201 EXPECT_THROW(it.get_curr(), std::underflow_error);
202 EXPECT_THROW(it.prev(), std::underflow_error);
203 EXPECT_NO_THROW(it.next());
204 EXPECT_EQ(it.get_curr(), 0);
205}
206
208{
209 Array_Container<int> c(a, n);
210 auto it = c.get_it();
211
212 EXPECT_TRUE(it.has_curr());
213 EXPECT_NO_THROW(it.get_curr());
214 for (size_t i = 0; it.has_curr(); it.next(), ++i)
215 ASSERT_EQ(it.get_curr(), i);
216 EXPECT_THROW(it.get_curr(), std::overflow_error);
217 EXPECT_THROW(it.next(), std::overflow_error);
218
219 it.reset();
220 EXPECT_TRUE(it.has_curr());
221 EXPECT_NO_THROW(it.get_curr());
222 for (size_t i = 0; it.has_curr(); it.next(), ++i)
223 ASSERT_EQ(it.get_curr(), i);
224 EXPECT_THROW(it.get_curr(), std::overflow_error);
225 EXPECT_THROW(it.next(), std::overflow_error);
226 EXPECT_NO_THROW(it.prev());
227 EXPECT_EQ(it.get_curr(), n - 1);
228
229 it.reset_last();
230 EXPECT_TRUE(it.has_curr());
231 EXPECT_NO_THROW(it.get_curr());
232 for (size_t i = n - 1; it.has_curr(); it.prev(), --i)
233 ASSERT_EQ(it.get_curr(), i);
234 EXPECT_THROW(it.get_curr(), std::underflow_error);
235 EXPECT_THROW(it.prev(), std::underflow_error);
236 EXPECT_NO_THROW(it.next());
237 EXPECT_EQ(it.get_curr(), 0);
238
239 it.end();
240 EXPECT_FALSE(it.has_curr());
241 EXPECT_THROW(it.get_curr(), std::overflow_error);
242 EXPECT_THROW(it.next(), std::overflow_error);
243 EXPECT_NO_THROW(it.prev());
244 EXPECT_NO_THROW(it.get_curr());
245 EXPECT_EQ(it.get_curr(), n - 1);
246}
247
248struct Array100 : public testing::Test
249{
250 const size_t dim = 100;
251 int * ptr = new int [dim];
253 {
254 for (size_t i = 0; i < dim; ++i)
255 ptr[i] = i;
256 }
257 ~Array100() { delete [] ptr; }
258};
259
261{
262 Array_Iterator<int> it(ptr + 23, 0, 0);
264 ASSERT_THROW(it.get_curr(), std::overflow_error);
265 ASSERT_THROW(it.next(), std::overflow_error);
266 ASSERT_THROW(it.prev(), std::underflow_error);
267}
268
270{
271 // Iterate on [23, 47]
272 Array_Iterator<int> it(ptr + 23, dim - 23 + 1, 47 - 23 + 1);
273
274 ASSERT_TRUE(it.has_curr());
275
276 int i = 23;
277 for (; it.has_curr(); it.next(), ++i)
278 ASSERT_EQ(it.get_curr(), i);
279 ASSERT_EQ(i, 48);
280
281 it.reset_first();
282 i = 23;
283 for (; it.has_curr(); it.next(), ++i)
284 ASSERT_EQ(it.get_curr(), i);
285 ASSERT_EQ(i, 48);
286
287 it.reset_last();
288 ASSERT_TRUE(it.has_curr());
289 for (i = 47; it.has_curr(); --i, it.prev())
290 ASSERT_EQ(it.get_curr(), i);
291 ASSERT_EQ(i, 22);
292}
293
295{
296 // iterate on [47, 7]
297 Array_Iterator<int> it(ptr, dim, dim - 47 + 1 + 7, 47, 7);
298
299 ASSERT_TRUE(it.has_curr());
300 int i = 47;
301 for (; it.has_curr(); it.next(), i = (i + 1) % dim)
302 ASSERT_EQ(it.get_curr(), i);
303 ASSERT_EQ(i, 8);
304
305 it.reset_last();
306 i = 7;
307 for (; it.has_curr(); it.prev(), --i)
308 {
309 ASSERT_EQ(it.get_curr(), i);
310 if (i == 0)
311 i = dim;
312 }
313}
314
316{
317 Array_Iterator<int> it(ptr, dim, dim, 47, 47);
318 ASSERT_TRUE(it.has_curr());
319
320 int i = 47, k = 0;
321 for (; it.has_curr(); it.next(), i = (i + 1) % dim, ++k)
322 ASSERT_EQ(it.get_curr(), i);
323 ASSERT_EQ(k, dim);
324
325 it.reset_last();
326 i = 47, k = 0;
327 for (; it.has_curr(); it.prev(), --i, ++k)
328 {
329 ASSERT_EQ(it.get_curr(), i);
330 if (i == 0)
331 i = dim;
332 }
333 ASSERT_EQ(k, dim);
334}
TEST_F(Array_of_n_items, Iterator_with_simple_bounds)
Definition array-it.cc:175
constexpr size_t N
Definition array-it.cc:161
Iterator wrapper for C++ raw arrays and circular buffers.
Lightweight wrapper that provides Aleph-w container interface for raw arrays.
Definition array_it.H:425
T * get_base() const noexcept
Get the base pointer.
Definition array_it.H:436
T & get_last() const
Get the last element.
Definition array_it.H:489
T & get_first() const
Get the first element.
Definition array_it.H:479
Iterator get_it() const
Get an iterator to the beginning.
Definition array_it.H:505
constexpr size_t size() const noexcept
Get the number of elements.
Definition array_it.H:462
constexpr bool is_empty() const noexcept
Check if the container is empty.
Definition array_it.H:454
Iterator wrapper for C++ raw arrays.
Definition array_it.H:85
T & get_curr() const
Get the current item with bounds checking.
Definition array_it.H:268
void reset_last() noexcept
Reset the iterator to the last item.
Definition array_it.H:330
void reset() noexcept
Reset the iterator to the first item.
Definition array_it.H:317
void prev()
Move to the previous item with bounds checking.
Definition array_it.H:310
void next()
Advance to the next item with bounds checking.
Definition array_it.H:290
void reset_first() noexcept
Reset the iterator to the first item (alias for reset()).
Definition array_it.H:324
bool has_curr() const noexcept
Check if there is a current valid item.
Definition array_it.H:231
bool is_last() const noexcept
Check if positioned at the last item.
Definition array_it.H:241
__T foldl(const __T &init, Op &op) const
Fold the elements of the container to a specific result.
Definition ah-dry.H:1312
#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_dim_function > > dim(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4063
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
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Array_Container< T > make_array_container(T *array, size_t n)
Create an Array_Container from a raw array.
Definition array_it.H:394
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
STL namespace.
int * ptr
Definition array-it.cc:251
const size_t dim
Definition array-it.cc:250
static int * k