Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
array.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
38#include <gtest/gtest.h>
39
40#include <tpl_array.H>
41#include <ah-unique.H>
42
43#include <array>
44#include <numeric>
45#include <string>
46#include <type_traits>
47#include <vector>
48
49using namespace Aleph;
50
51namespace {
52
54{
55 Array<int> arr;
56 EXPECT_TRUE(arr.is_empty());
57 EXPECT_EQ(arr.size(), 0u);
58 EXPECT_THROW(arr.base(), std::underflow_error);
59
61 EXPECT_THROW(empty_const.base(), std::underflow_error);
62
63 arr.append(10);
64 arr.append(20);
66 EXPECT_EQ(arr.size(), 2u);
67 EXPECT_EQ(arr.base(), 10);
68 EXPECT_EQ(arr.get_first(), 10);
69 EXPECT_EQ(arr.get_last(), 20);
70
71 const auto & carr = arr;
72 EXPECT_EQ(carr.get_first(), 10);
73 EXPECT_EQ(carr.get_last(), 20);
74}
75
77{
78 Array<int> src = {5, 7, 9, 11};
79
80 auto copy = src.to_array();
81
82 ASSERT_EQ(copy.size(), src.size());
83 for (size_t i = 0; i < copy.size(); ++i)
84 EXPECT_EQ(copy(i), src(i));
85
86 // original remains unchanged
87 EXPECT_EQ(src.size(), 4u);
88}
89
91{
92 Array<int> arr;
93 arr.append(1);
94 arr.append(2);
95 arr.insert(-1);
96
97 ASSERT_EQ(arr.size(), 3u);
98 EXPECT_EQ(arr.get_first(), -1);
99 EXPECT_EQ(arr.get_last(), 2);
100
101 EXPECT_EQ(arr.remove_first(), -1);
102 EXPECT_EQ(arr.remove_last(), 2);
103 EXPECT_EQ(arr.size(), 1u);
104 EXPECT_EQ(arr.base(), 1);
105
106 arr.empty();
107 EXPECT_TRUE(arr.is_empty());
108}
109
111{
112 Array<int> original = {1, 2, 3, 4};
114 ASSERT_EQ(copy.size(), original.size());
115 copy[0] = 100;
116 EXPECT_EQ(original[0], 1);
117
119 assigned = copy;
120 EXPECT_EQ(assigned.size(), copy.size());
121 EXPECT_EQ(assigned[0], 100);
122
123 Array<int> moved(std::move(copy));
124 EXPECT_EQ(moved.size(), 4u);
125 EXPECT_EQ(moved[0], 100);
126
129 move_assigned = std::move(moved);
130 EXPECT_EQ(move_assigned.size(), 4u);
132}
133
135{
136 Array<int> arr;
137 const auto initial_cap = arr.capacity();
138 arr.reserve(initial_cap + 50);
139 EXPECT_GE(arr.capacity(), initial_cap + 50);
140
141 arr.putn(5);
142 ASSERT_EQ(arr.size(), 5u);
143 for (size_t i = 0; i < arr.size(); ++i)
144 arr[i] = static_cast<int>(i * 10);
145
147 other.append(-1);
148 arr.swap(other);
149 EXPECT_EQ(arr.size(), 1u);
150 EXPECT_EQ(arr[0], -1);
151 EXPECT_EQ(other.size(), 5u);
152 EXPECT_EQ(other[2], 20);
153}
154
156{
158 arr.append("hello");
159 arr.append("world");
160
161 EXPECT_EQ(arr[0], "hello");
162 EXPECT_EQ(arr(1), "world");
163 EXPECT_THROW(arr[2], std::out_of_range);
164
165 const Array<std::string> carr = arr;
166 EXPECT_EQ(carr[0], "hello");
167 EXPECT_EQ(carr(1), "world");
168 EXPECT_THROW(carr[3], std::out_of_range);
169}
170
172{
173 Array<int> arr;
174 for (int i = 1; i <= 5; ++i)
175 arr.append(i);
176
177 const std::array<int, 5> ascending = {1, 2, 3, 4, 5};
178 const std::array<int, 5> descending = {5, 4, 3, 2, 1};
179
180 arr.reverse();
181 for (size_t i = 0; i < descending.size(); ++i)
182 EXPECT_EQ(arr[i], descending[i]) << "reverse() should mutate in place";
183
184 const Array<int> &carr = arr;
185 const auto copy = carr.reverse();
186 for (size_t i = 0; i < ascending.size(); ++i)
187 EXPECT_EQ(copy[i], ascending[i]) << "const reverse() should return new copy";
188
189 arr.reverse_in_place();
190 for (size_t i = 0; i < ascending.size(); ++i)
191 EXPECT_EQ(arr[i], ascending[i]) << "reverse_in_place() alias should behave like reverse()";
192
193 const auto copy_rev = carr.rev();
194 for (size_t i = 0; i < descending.size(); ++i)
195 EXPECT_EQ(copy_rev[i], descending[i]) << "const rev() should return reversed copy";
196}
197
199{
200 Array<int> arr = {1, 2, 3};
201
202 Array<int> &alias = arr.rev();
203
204 EXPECT_EQ(&alias, &arr);
205 EXPECT_EQ(arr[0], 3);
206 EXPECT_EQ(arr[1], 2);
207 EXPECT_EQ(arr[2], 1);
208}
209
210struct MoveOnlyOp
211{
212 bool *called;
213 explicit MoveOnlyOp(bool *c) : called(c) {}
214 MoveOnlyOp(const MoveOnlyOp &) = delete;
215 MoveOnlyOp & operator=(const MoveOnlyOp &) = delete;
216 MoveOnlyOp(MoveOnlyOp &&) = default;
217 MoveOnlyOp & operator=(MoveOnlyOp &&) = default;
218 bool operator()(int)
219 {
220 *called = true;
221 return true;
222 }
223};
224
226{
227 Array<int> arr = {1, 2, 3, 4};
228
229 int sum = 0;
230 auto accumulate = [&sum](int value)
231 {
232 sum += value;
233 return true;
234 };
236 EXPECT_EQ(sum, 10);
237
238 int visited = 0;
239 auto stop_at_three = [&visited](int value)
240 {
241 ++visited;
242 return value < 3;
243 };
245 EXPECT_EQ(visited, 3);
246
247 bool called = false;
248 EXPECT_TRUE(arr.traverse(MoveOnlyOp(&called)));
249 EXPECT_TRUE(called);
250}
251
253{
254 Array<int> arr = {1, 2, 3};
255 const Array<int> &const_arr = arr;
256
257 auto increment = [](int &value)
258 {
259 ++value;
260 return true;
261 };
262 int sum = 0;
263 auto accumulate_const = [&sum](const int &value)
264 {
265 sum += value;
266 return true;
267 };
268
270 EXPECT_EQ(arr[0], 2);
271 EXPECT_EQ(arr[1], 3);
272 EXPECT_EQ(arr[2], 4);
274 EXPECT_EQ(sum, 9);
275 EXPECT_TRUE(const_arr.traverse([](const int &value) { return value > 0; }));
276 EXPECT_EQ(arr[0], 2);
277 EXPECT_EQ(arr[1], 3);
278 EXPECT_EQ(arr[2], 4);
279}
280
281template <class Container, class Operation>
282concept CanTraverse = requires(Container &container, Operation &operation)
283{
284 container.traverse(operation);
285};
286
287struct MutableArrayOperation
288{
289 bool operator () (int &) const { return true; }
290};
291
292static_assert(CanTraverse<Array<int>, MutableArrayOperation>);
293static_assert(not CanTraverse<const Array<int>, MutableArrayOperation>);
294
296{
297 Array<int> arr = {1, 2, 1, 3, 2, 4, 4};
298
299 in_place_unique(arr);
300
301 ASSERT_EQ(arr.size(), 4u);
302 EXPECT_EQ(arr[0], 1);
303 EXPECT_EQ(arr[1], 2);
304 EXPECT_EQ(arr[2], 3);
305 EXPECT_EQ(arr[3], 4);
306}
307
309{
310 Array<int> arr = {0, 1, 2, 3};
311 Array<int>::Iterator it(arr);
312
313 int expected = 0;
314 for (; it.has_curr(); it.next())
315 {
316 EXPECT_EQ(it.get_curr(), expected);
317 ++expected;
318 }
320}
321
323{
324 auto arr = build_array<int>(5, 4, 3, 2, 1);
325 EXPECT_EQ(arr.size(), 5u);
326 EXPECT_EQ(arr[0], 5);
327 EXPECT_EQ(arr[4], 1);
328
329 const auto vec = to_stdvector(arr);
330 ASSERT_EQ(vec.size(), arr.size());
331 for (size_t i = 0; i < vec.size(); ++i)
332 EXPECT_EQ(vec[i], arr(i));
333}
334
335namespace
336{
337struct DefaultInit
338{
339 int v;
340 DefaultInit() : v(123) {}
341 explicit DefaultInit(int x) : v(x) {}
342 bool operator==(const DefaultInit &o) const { return v == o.v; }
343};
344}
345
347{
348 const size_t n = 8;
349 const int value = 42;
350 Array<int> arr(n, value);
351 ASSERT_EQ(arr.size(), n);
352 for (size_t i = 0; i < n; ++i)
353 EXPECT_EQ(arr[i], value);
354}
355
357{
358 const size_t n = 6;
359 const std::string value = "abc";
361 ASSERT_EQ(arr.size(), n);
362 for (size_t i = 0; i < n; ++i)
363 EXPECT_EQ(arr[i], value);
364}
365
367{
368 const size_t n = 10;
369 auto arr = Array<int>::create(n);
370 static_assert(std::is_trivially_default_constructible_v<int>);
371 ASSERT_EQ(arr.size(), n);
372
373 for (size_t i = 0; i < arr.size(); ++i)
374 arr[i] = static_cast<int>(i * 3);
375 for (size_t i = 0; i < arr.size(); ++i)
376 EXPECT_EQ(arr[i], static_cast<int>(i * 3));
377}
378
380{
381 const size_t n = 7;
382 auto arr = Array<DefaultInit>::create(n);
383 static_assert(!std::is_trivially_default_constructible_v<DefaultInit>);
384 ASSERT_EQ(arr.size(), n);
385 for (size_t i = 0; i < n; ++i)
386 EXPECT_EQ(arr[i].v, 123);
387
388 arr[0] = DefaultInit(7);
389 EXPECT_EQ(arr[0].v, 7);
390}
391
393{
395 pod.putn(3);
396 pod[0] = 1;
397 pod[1] = 2;
398 pod[2] = 3;
399 pod.append(4);
400 ASSERT_EQ(pod.size(), 4u);
401 EXPECT_EQ(pod[3], 4);
402
404 nonpod.putn(2);
405 nonpod[0] = "x";
406 nonpod[1] = "y";
407 nonpod.append("z");
408 ASSERT_EQ(nonpod.size(), 3u);
409 EXPECT_EQ(nonpod[2], "z");
410}
411
413{
414 Array<int> arr = {10, 20, 30, 40};
415 EXPECT_TRUE(arr.contains(20));
416 EXPECT_TRUE(arr.contains(40));
417 EXPECT_FALSE(arr.contains(50));
418
419 EXPECT_TRUE(arr.contains_if([](int x) { return x > 25; }));
420 EXPECT_FALSE(arr.contains_if([](int x) { return x > 100; }));
421}
422
424{
425 Array<int> empty;
426 EXPECT_FALSE(empty.contains(10));
427 EXPECT_FALSE(empty.contains_if([](int) { return true; }));
428}
429
430} // namespace
bool operator==(const Time &l, const Time &r)
Definition ah-time.H:133
Deduplicate sequential Aleph containers in-place.
size_t size_t int32_t value
Definition ca-c-api.h:116
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
static Array create(size_t n)
Create an array with n logical elements.
Definition tpl_array.H:196
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
Definition tpl_array.H:365
void empty() noexcept
Empties the container.
Definition tpl_array.H:341
constexpr bool is_empty() const noexcept
Checks if the container is empty.
Definition tpl_array.H:359
T & base()
Return a reference to the first element of array.
Definition tpl_array.H:326
T & insert(const T &data)
insert a copy of data at the beginning of the array.
Definition tpl_array.H:286
Array & rev()
Reverse this array in place.
Definition tpl_array.H:492
void swap(Array &s) noexcept
Swap this with s
Definition tpl_array.H:232
Array & reverse_in_place()
Alias for reverse().
Definition tpl_array.H:479
bool traverse(Op &op)
Traverse mutable elements from first to last.
Definition tpl_array.H:524
T & get_first() noexcept
return a modifiable reference to the first element.
Definition tpl_array.H:378
Array & reverse()
Reverse the order of items in this array, in place.
Definition tpl_array.H:447
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:250
T & get_last() noexcept
return a modifiable reference to the last element.
Definition tpl_array.H:392
constexpr size_t capacity() const noexcept
Return the internal capacity.
Definition tpl_array.H:371
void reserve(size_t cap)
Reserves cap cells into the array.
Definition tpl_array.H:320
void putn(const size_t n)
Reserve n additional logical slots in the array without value-initializing them.
Definition tpl_array.H:310
Array to_array() const
Copy to Aleph::Array (requires copyable elements).
Definition tpl_array.H:597
Minimal std::expected-style result type for C++20.
bool contains(const Type &item) const
Test if an item is present in the container using equality.
Definition ah-dry.H:574
bool contains_if(Operation &&operation) const noexcept(operation_is_noexcept< Operation >())
Test if an item satisfying a criterion is present in the container.
Definition ah-dry.H:563
#define TEST(name)
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
void in_place_unique(Container &c, Compare cmp={})
Remove duplicates in-place preserving first occurrence order.
Definition ah-unique.H:74
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
Definition ahAlgo.H:584
T accumulate(Itor beg, Itor end, T initValue)
Accumulate values in a range.
Definition ahAlgo.H:1493
std::vector< typename Container::Item_Type > to_stdvector(const Container &c)
Definition tpl_array.H:630
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Iterator on the items of an array.
Definition tpl_array.H:608
Dynamic array container with automatic resizing.