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.rev();
190 for (size_t i = 0; i < ascending.size(); ++i)
191 EXPECT_EQ(arr[i], ascending[i]) << "rev() 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
198struct MoveOnlyOp
199{
200 bool *called;
201 explicit MoveOnlyOp(bool *c) : called(c) {}
202 MoveOnlyOp(const MoveOnlyOp &) = delete;
203 MoveOnlyOp & operator=(const MoveOnlyOp &) = delete;
204 MoveOnlyOp(MoveOnlyOp &&) = default;
205 MoveOnlyOp & operator=(MoveOnlyOp &&) = default;
206 bool operator()(int)
207 {
208 *called = true;
209 return true;
210 }
211};
212
214{
215 Array<int> arr = {1, 2, 3, 4};
216
217 int sum = 0;
218 auto accumulate = [&sum](int value)
219 {
220 sum += value;
221 return true;
222 };
224 EXPECT_EQ(sum, 10);
225
226 int visited = 0;
227 auto stop_at_three = [&visited](int value)
228 {
229 ++visited;
230 return value < 3;
231 };
233 EXPECT_EQ(visited, 3);
234
235 bool called = false;
236 EXPECT_TRUE(arr.traverse(MoveOnlyOp(&called)));
237 EXPECT_TRUE(called);
238}
239
241{
242 Array<int> arr = {1, 2, 1, 3, 2, 4, 4};
243
244 in_place_unique(arr);
245
246 ASSERT_EQ(arr.size(), 4u);
247 EXPECT_EQ(arr[0], 1);
248 EXPECT_EQ(arr[1], 2);
249 EXPECT_EQ(arr[2], 3);
250 EXPECT_EQ(arr[3], 4);
251}
252
254{
255 Array<int> arr = {0, 1, 2, 3};
256 Array<int>::Iterator it(arr);
257
258 int expected = 0;
259 for (; it.has_curr(); it.next())
260 {
261 EXPECT_EQ(it.get_curr(), expected);
262 ++expected;
263 }
265}
266
268{
269 auto arr = build_array<int>(5, 4, 3, 2, 1);
270 EXPECT_EQ(arr.size(), 5u);
271 EXPECT_EQ(arr[0], 5);
272 EXPECT_EQ(arr[4], 1);
273
274 const auto vec = to_stdvector(arr);
275 ASSERT_EQ(vec.size(), arr.size());
276 for (size_t i = 0; i < vec.size(); ++i)
277 EXPECT_EQ(vec[i], arr(i));
278}
279
280namespace
281{
282struct DefaultInit
283{
284 int v;
285 DefaultInit() : v(123) {}
286 explicit DefaultInit(int x) : v(x) {}
287 bool operator==(const DefaultInit &o) const { return v == o.v; }
288};
289}
290
292{
293 const size_t n = 8;
294 const int value = 42;
295 Array<int> arr(n, value);
296 ASSERT_EQ(arr.size(), n);
297 for (size_t i = 0; i < n; ++i)
298 EXPECT_EQ(arr[i], value);
299}
300
302{
303 const size_t n = 6;
304 const std::string value = "abc";
305 Array<std::string> arr(n, value);
306 ASSERT_EQ(arr.size(), n);
307 for (size_t i = 0; i < n; ++i)
308 EXPECT_EQ(arr[i], value);
309}
310
312{
313 const size_t n = 10;
314 auto arr = Array<int>::create(n);
315 static_assert(std::is_trivially_default_constructible_v<int>);
316 ASSERT_EQ(arr.size(), n);
317
318 for (size_t i = 0; i < arr.size(); ++i)
319 arr[i] = static_cast<int>(i * 3);
320 for (size_t i = 0; i < arr.size(); ++i)
321 EXPECT_EQ(arr[i], static_cast<int>(i * 3));
322}
323
325{
326 const size_t n = 7;
327 auto arr = Array<DefaultInit>::create(n);
328 static_assert(!std::is_trivially_default_constructible_v<DefaultInit>);
329 ASSERT_EQ(arr.size(), n);
330 for (size_t i = 0; i < n; ++i)
331 EXPECT_EQ(arr[i].v, 123);
332
333 arr[0] = DefaultInit(7);
334 EXPECT_EQ(arr[0].v, 7);
335}
336
338{
340 pod.putn(3);
341 pod[0] = 1;
342 pod[1] = 2;
343 pod[2] = 3;
344 pod.append(4);
345 ASSERT_EQ(pod.size(), 4u);
346 EXPECT_EQ(pod[3], 4);
347
349 nonpod.putn(2);
350 nonpod[0] = "x";
351 nonpod[1] = "y";
352 nonpod.append("z");
353 ASSERT_EQ(nonpod.size(), 3u);
354 EXPECT_EQ(nonpod[2], "z");
355}
356
358{
359 Array<int> arr = {10, 20, 30, 40};
360 EXPECT_TRUE(arr.contains(20));
361 EXPECT_TRUE(arr.contains(40));
362 EXPECT_FALSE(arr.contains(50));
363
364 EXPECT_TRUE(arr.contains_if([](int x) { return x > 25; }));
365 EXPECT_FALSE(arr.contains_if([](int x) { return x > 100; }));
366}
367
369{
370 Array<int> empty;
371 EXPECT_FALSE(empty.contains(10));
372 EXPECT_FALSE(empty.contains_if([](int) { return true; }));
373}
374
375} // namespace
bool operator==(const Time &l, const Time &r)
Definition ah-time.H:133
Deduplicate sequential Aleph containers in-place.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:139
static Array create(size_t n)
Create an array with n logical elements.
Definition tpl_array.H:194
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
Definition tpl_array.H:351
void empty() noexcept
Empties the container.
Definition tpl_array.H:336
constexpr bool is_empty() const noexcept
Checks if the container is empty.
Definition tpl_array.H:348
T & base()
Return a reference to the first element of array.
Definition tpl_array.H:321
T & insert(const T &data)
insert a copy of data at the beginning of the array.
Definition tpl_array.H:281
Array & rev()
Definition tpl_array.H:419
void swap(Array &s) noexcept
Swap this with s
Definition tpl_array.H:227
bool traverse(Operation &operation)
Traverse all the items of the stack from the youngest to the oldest and conditionally performs an ope...
Definition tpl_array.H:431
T & get_first() noexcept
return a modifiable reference to the first element.
Definition tpl_array.H:358
Array & reverse()
Reverse the order of items in array.
Definition tpl_array.H:403
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:245
T & get_last() noexcept
return a modifiable reference to the last element.
Definition tpl_array.H:366
constexpr size_t capacity() const noexcept
Return the internal capacity.
Definition tpl_array.H:354
void reserve(size_t cap)
Reserves cap cells into the array.
Definition tpl_array.H:315
void putn(const size_t n)
Reserve n additional logical slots in the array without value-initializing them.
Definition tpl_array.H:305
Array to_array() const
Copy to Aleph::Array (requires copyable elements).
Definition tpl_array.H:460
bool contains(const Type &item) const
Test if an item is present in the container using equality.
Definition ah-dry.H:563
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:551
#define TEST(name)
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
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
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:488
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:470
Dynamic array container with automatic resizing.