Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-dry.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 <map>
41# include <vector>
42# include <ah-zip.H>
43# include <ahFunctional.H>
44# include <ah-string-utils.H>
45# include <ahSort.H>
46# include <htlist.H>
47# include <tpl_arrayHeap.H>
48# include <tpl_dynArrayHeap.H>
49# include <tpl_dynBinHeap.H>
50# include <tpl_dynDlist.H>
51# include <tpl_dynSetTree.H>
52# include <tpl_hash.H>
53# include <tpl_dynSetHash.H>
54# include <tpl_dynArray.H>
55# include <tpl_arrayQueue.H>
56# include <tpl_dynListStack.H>
57# include <tpl_dynarray_set.H>
58# include <tpl_random_queue.H>
59
60using namespace std;
61using namespace testing;
62using namespace Aleph;
63
64template <class Ctype>
65struct Container : public testing::Test
66{
67 static constexpr size_t N = 1000;
71 {
72 for (size_t i = 0; i < N; ++i)
73 {
74 c.append(i);
76 }
78 }
79};
80
82
84{
85 auto N = this->N;
86 TypeParam c = this->c;
87 EXPECT_EQ(c.size(), N);
89 EXPECT_TRUE(c.traverse([&l] (auto & k) { l.append(k); return true; }));
90 EXPECT_TRUE(zip_all([] (auto t) { return get<0>(t) == get<1>(t); },
91 this->item_list, sort(l)));
92}
93
95{
96 auto N = this->N;
97 TypeParam c = this->c;
98 EXPECT_EQ(c.size(), N);
100 c.for_each([&l] (auto & k) { l.append(k); });
101 EXPECT_TRUE(zip_all([] (auto t) { return get<0>(t) == get<1>(t); },
102 this->item_list, sort(l)));
103}
104
106{
107 auto N = this->N;
108 TypeParam c = this->c;
109 EXPECT_EQ(c.size(), N);
110 auto ptr = c.find_ptr([N] (auto & k) { return k == int(N); });
111 EXPECT_EQ(ptr, nullptr);
112 this->item_list.for_each([&c] (auto & k)
113 {
114 auto ptr = c.find_ptr([k] (auto i) { return k == i; });
115 ASSERT_NE(ptr, nullptr);
116 ASSERT_EQ(*ptr, k);
117 });
118}
119
121{
122 auto N = this->N;
123 TypeParam c = this->c;
124 EXPECT_EQ(c.size(), N);
125
126 auto idx = c.find_index([N] (auto & k) { return k == int(N); });
127 ASSERT_EQ(idx, N);
128
129 this->item_list.for_each([&c] (auto & k)
130 {
131 auto idx = c.find_index([k] (auto i) { return k == i; });
132 ASSERT_EQ(c.nth(idx), k);
133 });
134}
135
137{
138 auto N = this->N;
139 TypeParam c = this->c;
140 EXPECT_EQ(c.size(), N);
141
142 auto t = c.find_item([N] (auto & k) { return k == int(N); });
144
145 this->item_list.for_each([&c] (auto & k)
146 {
147 auto t = c.find_item([k] (auto i) { return k == i; });
149 ASSERT_EQ(get<1>(t), k);
150 });
151}
152
154{
155 //auto N = this->N;
156 auto c = this->c;
157 const DynList<int> l = to_dynlist(c); // in the same order than iterator
158 const std::vector<int> v = c.to_vector(); // test to_vector method
159 const DynList<int> l2 = c.to_dynlist(); // test to_dynlist method
160
161 ASSERT_EQ(l.size(), c.size());
162 ASSERT_EQ(v.size(), c.size());
163 ASSERT_EQ(l2.size(), c.size());
164
165 // Verify to_vector and to_dynlist produce same content
166 size_t idx = 0;
167 l2.for_each([&v, &idx](int x) {
168 EXPECT_EQ(x, v[idx++]);
169 });
170
171 auto itl = l.get_it();
172 for (auto & item : c)
173 {
174 ASSERT_EQ(item, itl.get_curr_ne());
175 itl.next_ne();
176 }
177 auto it = c.get_it();
178 EXPECT_EQ(it.get_curr_ne(), l.get_first());
179 it.reset_last();
180 EXPECT_EQ(it.get_curr_ne(), l.get_last());
181 it.reset_first();
182 EXPECT_EQ(it.get_curr_ne(), l.get_first());
183 it.reset_last();
184 EXPECT_EQ(it.get_curr_ne(), l.get_last());
185}
186
188{
189 int N = this->N;
190 auto c = this->c;
191
192 c.nappend(N);
193 auto ptr = c.find_ptr([N] (auto i) { return i == N; });
194 EXPECT_EQ(c.size(), N + 1);
195 ASSERT_NE(ptr, nullptr);
196 EXPECT_EQ(*ptr, N);
197
198 c.nappend(N + 1, N + 2, N + 3);
199 EXPECT_EQ(c.size(), N + 4);
200
201 ptr = c.find_ptr([N] (auto i) { return i == N + 1; });
202 ASSERT_NE(ptr, nullptr);
203 EXPECT_EQ(*ptr, N + 1);
204
205 ptr = c.find_ptr([N] (auto i) { return i == N + 2; });
206 ASSERT_NE(ptr, nullptr);
207 EXPECT_EQ(*ptr, N + 2);
208
209 ptr = c.find_ptr([N] (auto i) { return i == N + 3; });
210 ASSERT_NE(ptr, nullptr);
211 EXPECT_EQ(*ptr, N + 3);
212}
213
215{
216 int N = this->N;
217 auto c = this->c;
218
219 c.ninsert(N);
220 auto ptr = c.find_ptr([N] (auto i) { return i == N; });
221 EXPECT_EQ(c.size(), N + 1);
222 ASSERT_NE(ptr, nullptr);
223 EXPECT_EQ(*ptr, N);
224
225 c.ninsert(N + 1, N + 2, N + 3);
226 EXPECT_EQ(c.size(), N + 4);
227
228 ptr = c.find_ptr([N] (auto i) { return i == N + 1; });
229 ASSERT_NE(ptr, nullptr);
230 EXPECT_EQ(*ptr, N + 1);
231
232 ptr = c.find_ptr([N] (auto i) { return i == N + 2; });
233 ASSERT_NE(ptr, nullptr);
234 EXPECT_EQ(*ptr, N + 2);
235
236 ptr = c.find_ptr([N] (auto i) { return i == N + 3; });
237 ASSERT_NE(ptr, nullptr);
238 EXPECT_EQ(*ptr, N + 3);
239}
240
242{
243 int N = this->N;
244 auto c = this->c;
246 ASSERT_TRUE(c.all([&tbl] (auto i)
247 {
248 const bool ret = tbl.contains(i);
249 tbl.insert(i);
250 return not ret;
251 }));
252 EXPECT_EQ(tbl.size(), N);
253 EXPECT_EQ(sort(to_dynlist(c)), tbl.keys());
254}
255
257{
258 int N = this->N;
259 auto c = this->c;
260 auto & l = this->item_list;
261 EXPECT_TRUE(l.all([&c] (auto & i)
262 { return c.exists([i] (auto k) { return i == k; }); }));
263 EXPECT_FALSE(c.exists([N] (auto i) { return i == N; }));
264}
265
267{
268 auto c = this->c;
269 auto & l = this->item_list;
270 auto fct = [] (int i) { return i + 1; };
272 all([] (auto & p) { return p.first == p.second; }));
273 EXPECT_TRUE(zip(sort(to_dynlist(c.maps_if([] (auto i)
274 { return i < 7; }, fct))),
275 sort(l.maps_if([] (auto i)
276 { return i < 7; }, fct))).
277 all([] (auto & p) { return p.first == p.second; }));
278}
279
281{
282 auto c = this->c;
283 auto & l = this->item_list;
284 auto fct = [] (int i) { return i + 1; };
286 all([] (auto & p) { return p.first == p.second; }));
287 EXPECT_TRUE(zip(sort(to_dynlist(c.map_if([] (auto i)
288 { return i < 7; }, fct))),
289 sort(l.map_if([] (auto i)
290 { return i < 7; }, fct))).
291 all([] (auto & p) { return p.first == p.second; }));
292}
293
295{
296 int N = this->N;
297 auto c = this->c;
298 auto sum = c.foldl(0, [] (auto & a, auto & i) { return a + i; });
299 EXPECT_EQ(sum, N*(N-1)/2);
300}
301
303{
304 auto fct = [] (int a, int i) { return a + i; };
305 auto c = this->c;
306 auto sum = c.filter([] (auto i) { return i < 8; }).foldl(0, fct);
307 EXPECT_EQ(sum, 28);
308
309 auto l = c.ptr_filter([] (auto & i) { return i < 8; });
310 sum = l.foldl(0, [] (auto a, auto ptr) { return a + *ptr; });
311 EXPECT_EQ(sum, 28);
312
313 int N = this->N;
314 auto total = N*(N-1)/2;
315 auto p = c.partition([] (auto & i) { return i < 8; });
316 auto S = p.first.foldl(0, fct) + p.second.foldl(0, fct);
317 EXPECT_EQ(S, total);
318
319 auto t = c.tpartition([] (auto & i) { return i < 8; });
320 S = get<0>(t).foldl(0, fct) + get<1>(t).foldl(0, fct);
321 EXPECT_EQ(S, total);
322
323 auto l1 = c.take(8);
324 auto l2 = c.drop(8);
325 S = l1.foldl(0, fct) + l2.foldl(0, fct);
326 EXPECT_EQ(S, total);
327
328 EXPECT_EQ(sort(c.to_dynlist()).take(8, 12),
329 build_dynlist<int>(8, 9, 10, 11, 12));
330}
331
334 nappend, ninsert, all, exists, maps, map_synonyms,
336
337typedef
348 >
350
352
353template <class C>
354struct CtorContainer : public ::testing::Test
355{
356 static constexpr size_t N = 10;
357 C * ptr_1 = nullptr;
358 C * ptr_2 = nullptr;
359 C * ptr_3 = nullptr;
361 {
362 ptr_1 = new C(range<int>(N));
363 ptr_2 = new C({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 });
364 ptr_3 = new C(ptr_1->begin(), ptr_1->end()); // Use same container for begin/end
365 }
367 {
368 delete ptr_1;
369 delete ptr_2;
370 delete ptr_3;
371 }
372};
373
375
377{
378 auto N = this->N;
379 auto ptr_1 = this->ptr_1;
380 auto ptr_2 = this->ptr_2;
381 auto ptr_3 = this->ptr_3;
382 EXPECT_EQ(ptr_1->size(), N);
383 EXPECT_EQ(ptr_2->size(), 10);
384 EXPECT_EQ(ptr_3->size(), 10);
385
386 auto l1 = to_dynlist(*ptr_1);
387 auto l2 = to_dynlist(*ptr_2);
388 auto l3 = to_dynlist(*ptr_3);
389
390 const auto r1 = range<int>(N);
391 const auto r2 = build_dynlist<int>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
392 const auto & r3 = r1;
393
394 ASSERT_EQ(sort(l1), r1);
395 ASSERT_EQ(sort(l2), r2);
396 ASSERT_EQ(sort(l3), r3);
397}
398
400
402
404{
405 Array<int> a1 = {1, 2, 3, 4, 5};
406 Array<int> a2 = {1, 2, 3, 4, 5};
407 Array<int> a3 = {1, 2, 3, 4};
408 Array<int> a4 = {5, 4, 3, 2, 1};
409 Array<int> a5 = {1, 2, 2, 3, 4, 5};
410
411 // 1. Size mismatch
412 EXPECT_FALSE(a1.equal_to(a3));
413 EXPECT_FALSE(a1 == a3);
414 EXPECT_TRUE(a1 != a3);
415
416 // 2. Self-comparison
417 EXPECT_TRUE(a1.equal_to(a1));
418 EXPECT_TRUE(a1 == a1);
419 EXPECT_FALSE(a1 != a1);
420
421 // 3. Same elements, same order
422 EXPECT_TRUE(a1.equal_to(a2));
423 EXPECT_TRUE(a1 == a2);
424 EXPECT_FALSE(a1 != a2);
425
426 // 4. Same elements, different order
427 EXPECT_FALSE(a1.equal_to(a4));
428 EXPECT_FALSE(a1 == a4);
429 EXPECT_TRUE(a1 != a4);
430
431 // 5. Multiplicity differences
433 EXPECT_FALSE(a1 == a5);
434
435 // DynArray
436 DynArray<int> d1 = {1, 2, 3};
437 DynArray<int> d2 = {1, 2, 3};
438 DynArray<int> d3 = {3, 2, 1};
439
440 EXPECT_TRUE(d1 == d2);
441 EXPECT_FALSE(d1 == d3);
442}
443
445{
446 std::map<int, std::string> std_map;
447 std_map[1] = "one";
448 std_map[2] = "two";
449 std_map[3] = "three";
450
451 DynList<int> aleph_list = {1, 2, 3, 4, 5};
452
453 auto mapped = aleph_list.map([] (int x) { return x * 2; });
454 EXPECT_EQ(mapped.size(), 5);
455
456 EXPECT_EQ(std_map.size(), 3);
457 EXPECT_EQ(std_map[1], "one");
458
459 auto filtered_mapped = aleph_list.map_if(
460 [] (int x) { return x > 2; },
461 [] (int x) { return x * 3; }
462 );
463 EXPECT_EQ(filtered_mapped.size(), 3);
464
465 std::map<std::string, int> another_map;
466 another_map["a"] = 10;
467 another_map["b"] = 20;
468
469 EXPECT_EQ(another_map.size(), 2);
470 EXPECT_EQ(another_map["a"], 10);
471
472 auto result = mapped.foldl(0, [] (int acc, int val) { return acc + val; });
473 EXPECT_EQ(result, 30);
474}
INSTANTIATE_TYPED_TEST_SUITE_P(traverses, Container, Ctypes)
Types< DynList< int >, DynDlist< int >, DynArray< int >, HashSet< int, ODhashTable >, HashSet< int, OLhashTable >, DynHashTable< int, LhashTable >, DynHashTable< int, LinearHashTable >, DynSetHash< int >, DynSetTree< int, Treap >, DynSetTree< int, Treap_Rk >, DynSetTree< int, Rand_Tree >, DynSetTree< int, Splay_Tree >, DynSetTree< int, Avl_Tree >, DynSetTree< int, Rb_Tree >, Array< int >, ArrayQueue< int >, ArrayStack< int >, DynListQueue< int >, DynListStack< int >, DynArrayHeap< int >, DynBinHeap< int >, FixedQueue< int >, FixedStack< int > > Ctypes
Definition ah-dry.cc:349
REGISTER_TYPED_TEST_SUITE_P(Container, traverse, for_each, find_ptr, find_index_nth, find_item, iterator_operations, nappend, ninsert, all, exists, maps, map_synonyms, foldl, filter_ops)
TYPED_TEST_SUITE_P(Container)
TYPED_TEST_P(Container, traverse)
Definition ah-dry.cc:83
String manipulation utilities.
Zip iterators and functional operations for multiple containers.
Functional programming utilities for Aleph-w containers.
High-level sorting functions for Aleph containers.
Queue implemented with a single dynamic array.
Stack implemented with simple dynamic array and with bounds verification.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
Dynamic heap (priority queue) backed by DynArray.
Dynamic heap of elements of type T ordered by a comparison functor.
Dynamic doubly linked list with O(1) size and bidirectional access.
Self-adjusting dynamic hash table.
Dynamic queue of elements of generic type T based on single linked list.
Dynamic stack of elements of generic type T based on a singly linked list.
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
T & get_last() const
Return the last item of the list.
Definition htlist.H:1363
T & get_first() const
Return the first item of the list.
Definition htlist.H:1375
Dynamic set backed by balanced binary search trees with automatic memory management.
Very simple queue implemented with a contiguous array.
Fixed length stack.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1065
Mixin providing equality comparison for sequence containers.
Definition ah-dry.H:1891
bool equal_to(const Container &r) const
Equality test between this and r.
Definition ah-dry.H:1909
Aleph::DynList< __T > maps_if(Prop prop, Operation &op) const
Definition ah-dry.H:1138
Aleph::DynList< T > to_dynlist() const
Convert container to DynList.
Definition ah-dry.H:1239
__T foldl(const __T &init, Op &op) const
Fold the elements of the container to a specific result.
Definition ah-dry.H:1312
Aleph::DynList< T > take(const size_t n) const
Return a list with the first n elements seen in the container during its traversal.
Definition ah-dry.H:1764
Aleph::DynList< const T * > ptr_filter(Operation &operation) const
Filter the elements of a container according to a matching criterion and return a pointer to the matc...
Definition ah-dry.H:1491
Aleph::DynList< __T > map(Operation &op) const
Synonym of maps().
Definition ah-dry.H:1182
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Definition ah-dry.H:1090
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:796
Aleph::DynList< __T > map_if(Prop prop, Operation &op) const
Definition ah-dry.H:1212
bool all(Operation &operation) const
Check if all the elements of the container satisfy a condition.
Definition ah-dry.H:984
Aleph::DynList< T > drop(const size_t n) const
Drop the first n elements seen in the container during its traversal.
Definition ah-dry.H:1812
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:228
#define TEST(name)
#define N
Definition fib.C:294
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
MapOLhash< int, Foo > tbl
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< typename Container::Item_Type > to_dynlist(const Container &c)
Definition htlist.H:1694
bool traverse(Node *root, Op op)
DynList< std::pair< typename Container1::Item_Type, typename Container2::Item_Type > > zip(const Container1 &a, const Container2 &b)
Zip two containers into a list of pairs.
bool all(Container &container, Operation &operation)
Return true if all elements satisfy a predicate.
T foldl(const Container &container, const T &init, Operation operation)
Classic left fold (reduce).
bool exists(Container &container, Operation &operation)
Return true if at least one element satisfies a predicate.
DynArray< T > sort(const DynArray< T > &a, Cmp &&cmp=Cmp())
Returns a sorted copy of a DynArray.
Definition ahSort.H:234
bool zip_all(Op &&op, const Cs &...cs)
Return true if op returns true for all tuples and containers have equal length.
Definition ah-zip.H:416
Operation for_each(Itor beg, const Itor &end, Operation op)
Apply an operation to each element in a range.
Definition ahAlgo.H:76
Container::Item_Type * find_ptr(Container &container, Pred &pred)
Find the first element satisfying pred.
DynList< T > maps(const C &c, Op op)
Classic map operation.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
STL namespace.
Container()
Definition ah-dry.cc:70
static constexpr size_t N
Definition ah-dry.cc:67
DynList< int > item_list
Definition ah-dry.cc:69
Ctype c
Definition ah-dry.cc:68
static constexpr size_t N
Definition ah-dry.cc:356
DynList< char > l3
DynList< int > l1
DynList< int > l2
static int * k
Fixed-capacity binary heap and heapsort algorithms.
Circular queue implementations backed by arrays.
Array-based dynamic binary heap.
Lazy and scalable dynamic array implementation.
Dynamic binary heap with node-based storage.
Dynamic doubly linked list implementation.
Dynamic stack implementation based on linked lists.
Dynamic set implementations based on hash tables.
Dynamic set implementations based on balanced binary search trees.
Array-based dynamic set.
Unified hash table interface.
Random access queue (bag) with O(1) random pop.
DynList< int > l