Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-stl-utils.cc
Go to the documentation of this file.
1
9#include <gtest/gtest.h>
10
11#include <list>
12#include <vector>
13#include <set>
14#include <string>
15#include <tuple>
16
17#include <ah-stl-utils.H>
18#include <ahFunctional.H>
19
20using namespace std;
21using namespace Aleph;
22
23// ============================================================================
24// Test Suite: vector_to_DynList / to_DynList
25// ============================================================================
26
28{
29 vector<int> empty;
30 auto result = vector_to_DynList(empty);
31 EXPECT_TRUE(result.is_empty());
32 EXPECT_EQ(result.size(), 0);
33}
34
36{
37 vector<int> v = {42};
38 auto result = vector_to_DynList(v);
39 EXPECT_EQ(result.size(), 1);
40 EXPECT_EQ(result.get_first(), 42);
41}
42
44{
45 vector<int> v = {1, 2, 3, 4, 5};
46 auto result = vector_to_DynList(v);
47 EXPECT_EQ(result.size(), 5);
48 EXPECT_EQ(result, build_dynlist<int>(1, 2, 3, 4, 5));
49}
50
52{
53 vector<string> v = {"hello", "world", "test"};
54 auto result = vector_to_DynList(v);
55 EXPECT_EQ(result.size(), 3);
56 EXPECT_EQ(result.get_first(), "hello");
57 EXPECT_EQ(result.get_last(), "test");
58}
59
61{
62 vector<double> v = {1.5, 2.5, 3.5};
63 auto result = to_DynList(v);
64 EXPECT_EQ(result.size(), 3);
65 EXPECT_DOUBLE_EQ(result.get_first(), 1.5);
66}
67
68// ============================================================================
69// Test Suite: range_to_DynList
70// ============================================================================
71
73{
74 vector<int> v = {10, 20, 30, 40, 50};
75 auto result = range_to_DynList(v.begin(), v.end());
76 EXPECT_EQ(result.size(), 5);
77 EXPECT_EQ(result, build_dynlist<int>(10, 20, 30, 40, 50));
78}
79
81{
82 vector<int> v = {1, 2, 3, 4, 5};
83 auto result = range_to_DynList(v.begin() + 1, v.begin() + 4);
84 EXPECT_EQ(result.size(), 3);
85 EXPECT_EQ(result, build_dynlist<int>(2, 3, 4));
86}
87
89{
90 vector<int> v = {1, 2, 3};
91 auto result = range_to_DynList(v.begin(), v.begin());
92 EXPECT_TRUE(result.is_empty());
93}
94
96{
97 list<string> l = {"a", "b", "c"};
98 auto result = range_to_DynList(l.begin(), l.end());
99 EXPECT_EQ(result.size(), 3);
100 EXPECT_EQ(result.get_first(), "a");
101}
102
103// ============================================================================
104// Test Suite: to_Array
105// ============================================================================
106
108{
109 vector<int> empty;
110 auto result = to_Array(empty);
111 EXPECT_EQ(result.size(), 0);
112}
113
115{
116 vector<int> v = {10, 20, 30};
117 auto result = to_Array(v);
118 EXPECT_EQ(result.size(), 3);
119 EXPECT_EQ(result(0), 10);
120 EXPECT_EQ(result(1), 20);
121 EXPECT_EQ(result(2), 30);
122}
123
124// ============================================================================
125// Test Suite: to_vector
126// ============================================================================
127
129{
130 DynList<int> l = build_dynlist<int>(5, 10, 15, 20);
131 auto result = to_vector(l);
132 ASSERT_EQ(result.size(), 4);
133 EXPECT_EQ(result[0], 5);
134 EXPECT_EQ(result[1], 10);
135 EXPECT_EQ(result[2], 15);
136 EXPECT_EQ(result[3], 20);
137}
138
140{
141 DynList<int> empty;
142 auto result = to_vector(empty);
143 EXPECT_TRUE(result.empty());
144}
145
147{
148 DynSetTree<int> tree;
149 tree.insert(3);
150 tree.insert(1);
151 tree.insert(2);
152 auto result = to_vector(tree);
153 ASSERT_EQ(result.size(), 3);
154 // DynSetTree keeps elements sorted
155 EXPECT_EQ(result[0], 1);
156 EXPECT_EQ(result[1], 2);
157 EXPECT_EQ(result[2], 3);
158}
159
160// ============================================================================
161// Test Suite: map_vector
162// ============================================================================
163
165{
166 vector<int> v = {1, 2, 3, 4, 5};
167 auto result = map_vector(v, [](int x) { return x * x; });
168 ASSERT_EQ(result.size(), 5);
169 EXPECT_EQ(result[0], 1);
170 EXPECT_EQ(result[1], 4);
171 EXPECT_EQ(result[2], 9);
172 EXPECT_EQ(result[3], 16);
173 EXPECT_EQ(result[4], 25);
174}
175
177{
178 vector<int> v = {1, 2, 3};
179 auto result = map_vector(v, [](int x) { return to_string(x); });
180 ASSERT_EQ(result.size(), 3);
181 EXPECT_EQ(result[0], "1");
182 EXPECT_EQ(result[1], "2");
183 EXPECT_EQ(result[2], "3");
184}
185
187{
188 vector<int> empty;
189 auto result = map_vector(empty, [](int x) { return x * 2; });
190 EXPECT_TRUE(result.empty());
191}
192
193// ============================================================================
194// Test Suite: variadic_to_vector / variadic_to_DynList
195// ============================================================================
196
198{
199 auto result = variadic_to_vector<int>(1, 2, 3, 4, 5);
200 ASSERT_EQ(result.size(), 5);
201 EXPECT_EQ(result[0], 1);
202 EXPECT_EQ(result[4], 5);
203}
204
206{
207 auto result = variadic_to_vector<int>(42);
208 ASSERT_EQ(result.size(), 1);
209 EXPECT_EQ(result[0], 42);
210}
211
213{
214 // All should convert to double
215 auto result = variadic_to_vector<double>(1, 2.5, 3);
216 ASSERT_EQ(result.size(), 3);
217 EXPECT_DOUBLE_EQ(result[0], 1.0);
218 EXPECT_DOUBLE_EQ(result[1], 2.5);
219 EXPECT_DOUBLE_EQ(result[2], 3.0);
220}
221
223{
224 auto result = variadic_to_DynList<int>(10, 20, 30);
225 EXPECT_EQ(result.size(), 3);
226 EXPECT_EQ(result, build_dynlist<int>(10, 20, 30));
227}
228
230{
231 auto result = variadic_to_DynList<string>("a", "b", "c");
232 EXPECT_EQ(result.size(), 3);
233 EXPECT_EQ(result.get_first(), "a");
234}
235
236// ============================================================================
237// Test Suite: tuple_for_each
238// ============================================================================
239
241{
242 auto t = make_tuple(1, 2, 3, 4, 5);
243 int sum = 0;
244 tuple_for_each(t, [&sum](int x) { sum += x; });
245 EXPECT_EQ(sum, 15);
246}
247
249{
250 auto t = make_tuple(string("a"), string("b"), string("c"));
251 string result;
252 tuple_for_each(t, [&result](const string& s) { result += s; });
253 EXPECT_EQ(result, "abc");
254}
255
257{
258 auto t = make_tuple();
259 int count = 0;
260 tuple_for_each(t, [&count](auto) { ++count; });
261 EXPECT_EQ(count, 0);
262}
263
265{
266 auto t = make_tuple(42);
267 int value = 0;
268 tuple_for_each(t, [&value](int x) { value = x; });
269 EXPECT_EQ(value, 42);
270}
271
272// ============================================================================
273// Test Suite: tuple_to_container / tuple_to_dynlist / tuple_to_array
274// ============================================================================
275
277{
278 auto t = make_tuple(1, 2, 3, 4, 5);
279 auto result = tuple_to_dynlist(t);
280 EXPECT_EQ(result.size(), 5);
281 EXPECT_EQ(result, build_dynlist<int>(1, 2, 3, 4, 5));
282}
283
285{
286 auto t = make_tuple(42);
287 auto result = tuple_to_dynlist(t);
288 EXPECT_EQ(result.size(), 1);
289 EXPECT_EQ(result.get_first(), 42);
290}
291
293{
294 auto t = make_tuple(string("hello"), string("world"));
295 auto result = tuple_to_dynlist(t);
296 EXPECT_EQ(result.size(), 2);
297 EXPECT_EQ(result.get_first(), "hello");
298 EXPECT_EQ(result.get_last(), "world");
299}
300
302{
303 auto t = make_tuple(10, 20, 30);
304 auto result = tuple_to_array(t);
305 EXPECT_EQ(result.size(), 3);
306 EXPECT_EQ(result(0), 10);
307 EXPECT_EQ(result(1), 20);
308 EXPECT_EQ(result(2), 30);
309}
310
311// ============================================================================
312// Test Suite: stl_container_to_dynList
313// ============================================================================
314
316{
317 vector<int> v = {1, 2, 3};
318 auto result = stl_container_to_dynList(v);
319 EXPECT_EQ(result.size(), 3);
320 EXPECT_EQ(result, build_dynlist<int>(1, 2, 3));
321}
322
324{
325 list<int> l = {4, 5, 6};
326 auto result = stl_container_to_dynList(l);
327 EXPECT_EQ(result.size(), 3);
328 EXPECT_EQ(result, build_dynlist<int>(4, 5, 6));
329}
330
332{
333 set<int> s = {3, 1, 2}; // Will be sorted
334 auto result = stl_container_to_dynList(s);
335 EXPECT_EQ(result.size(), 3);
336 EXPECT_EQ(result, build_dynlist<int>(1, 2, 3));
337}
338
340{
341 vector<int> empty;
342 auto result = stl_container_to_dynList(empty);
343 EXPECT_TRUE(result.is_empty());
344}
345
346// ============================================================================
347// Test Suite: list_to_DynList / DynList_to_list
348// ============================================================================
349
351{
352 list<int> l = {1, 2, 3, 4};
353 auto result = list_to_DynList(l);
354 EXPECT_EQ(result.size(), 4);
355 EXPECT_EQ(result, build_dynlist<int>(1, 2, 3, 4));
356}
357
359{
361 auto result = DynList_to_list(dl);
362 ASSERT_EQ(result.size(), 3);
363 auto it = result.begin();
364 EXPECT_EQ(*it++, 5);
365 EXPECT_EQ(*it++, 6);
366 EXPECT_EQ(*it++, 7);
367}
368
370{
371 list<string> original = {"a", "b", "c", "d"};
375}
376
378{
380 auto result = list_to_DynList(empty_list);
381 EXPECT_TRUE(result.is_empty());
382
386}
387
388// ============================================================================
389// Test Suite: DynArray_to_vector / vector_to_DynArray
390// ============================================================================
391
393{
394 DynArray<int> arr;
395 arr.append(10);
396 arr.append(20);
397 arr.append(30);
398 arr.append(40);
399 arr.append(50);
400
401 auto result = DynArray_to_vector(arr);
402 ASSERT_EQ(result.size(), 5);
403 EXPECT_EQ(result[0], 10);
404 EXPECT_EQ(result[2], 30);
405 EXPECT_EQ(result[4], 50);
406}
407
409{
410 vector<int> v = {100, 200, 300};
411 auto result = vector_to_DynArray(v);
412 EXPECT_EQ(result.size(), 3);
413 EXPECT_EQ(result(0), 100);
414 EXPECT_EQ(result(1), 200);
415 EXPECT_EQ(result(2), 300);
416}
417
419{
420 vector<double> original = {1.1, 2.2, 3.3, 4.4};
421 auto arr = vector_to_DynArray(original);
422 auto back = DynArray_to_vector(arr);
424}
425
427{
428 vector<int> empty_vec;
429 auto arr = vector_to_DynArray(empty_vec);
430 EXPECT_EQ(arr.size(), 0);
431
432 auto back = DynArray_to_vector(arr);
434}
435
436// ============================================================================
437// Test Suite: index_tuple / make_index_tuple
438// ============================================================================
439
441{
442 // Test that make_index_tuple<N> creates an index_tuple with indices 0..N-1
444 static_assert(std::is_same_v<IT3, index_tuple<0, 1, 2>>,
445 "make_index_tuple<3> should produce index_tuple<0, 1, 2>");
446
448 static_assert(std::is_same_v<IT0, index_tuple<>>,
449 "make_index_tuple<0> should produce index_tuple<>");
450
452 static_assert(std::is_same_v<IT1, index_tuple<0>>,
453 "make_index_tuple<1> should produce index_tuple<0>");
454}
455
457{
459 static_assert(std::is_same_v<IT, index_tuple<0, 1, 2>>,
460 "to_index_tuple with 3 types should produce index_tuple<0, 1, 2>");
461}
462
463// ============================================================================
464// Test Suite: Edge Cases and Stress Tests
465// ============================================================================
466
468{
469 const size_t N = 10000;
470 vector<int> v(N);
471 for (size_t i = 0; i < N; ++i)
472 v[i] = static_cast<int>(i);
473
474 auto result = vector_to_DynList(v);
475 EXPECT_EQ(result.size(), N);
476 EXPECT_EQ(result.get_first(), 0);
477 EXPECT_EQ(result.get_last(), static_cast<int>(N - 1));
478
479 auto back = to_vector(result);
480 EXPECT_EQ(v, back);
481}
482
484{
485 struct Point {
486 double x, y;
487 bool operator==(const Point& other) const {
488 return x == other.x && y == other.y;
489 }
490 };
491
492 vector<Point> v = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
493 auto dynlist = vector_to_DynList(v);
494 EXPECT_EQ(dynlist.size(), 3);
495
496 auto back = to_vector(dynlist);
497 EXPECT_EQ(v, back);
498}
499
501{
502 vector<vector<int>> v = {{1, 2}, {3, 4, 5}, {6}};
503 auto dynlist = vector_to_DynList(v);
504 EXPECT_EQ(dynlist.size(), 3);
505
506 auto back = to_vector(dynlist);
507 EXPECT_EQ(v, back);
508}
509
511{
512 vector<string> v = {"long string that should not be copied",
513 "another long string for testing"};
514
515 // Conversion makes copies, original should be unchanged
516 auto dynlist = vector_to_DynList(v);
517 EXPECT_EQ(dynlist.size(), 2);
518 EXPECT_EQ(dynlist.get_first(), "long string that should not be copied");
519 // Note: v still has its elements (we copied, not moved)
520 EXPECT_EQ(v[0], "long string that should not be copied");
521 EXPECT_EQ(v[1], "another long string for testing");
522}
523
Conversion utilities between Aleph-w containers and STL containers.
Functional programming utilities for Aleph-w containers.
T & append()
Allocate a new entry to the end of array.
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & get_first() const
Return the first item of the list.
Definition htlist.H:1675
void empty() noexcept
empty the list
Definition htlist.H:1689
Dynamic set backed by balanced binary search trees with automatic memory management.
Key * insert(const Key &key)
Inserts a key into the dynamic set.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Rectangular point in the plane.
Definition point.H:156
Geom_Number x
Definition point.H:161
Geom_Number y
Definition point.H:162
bool operator==(const Point &point) const
Definition point.H:185
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
#define TEST(name)
#define N
Definition fib.C:294
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Array< T > tuple_to_array(const std::tuple< T, U... > &t)
Convert a tuple to an Array.
auto range_to_DynList(Iterator begin, Iterator end) -> DynList< std::decay_t< decltype(*begin)> >
Convert an iterator range to a DynList.
DynList< T > to_DynList(const Array< T > &a)
Convert an Array to a DynList.
Definition ah-convert.H:147
DynList< T > list_to_DynList(const std::list< T > &l)
Convert a std::list to a DynList.
typename make_index_tuple< sizeof...(Types)>::type to_index_tuple
Convenience alias to generate an index tuple from a parameter pack.
DynList< T > vector_to_DynList(const std::vector< T > &v)
Convert a std::vector to a DynList.
Definition ah-convert.H:250
DynList< T > tuple_to_dynlist(const std::tuple< T, U... > &t)
Convert a tuple to a DynList.
auto stl_container_to_dynList(const StlContainer &container) -> DynList< typename StlContainer::value_type >
Convert any STL container to a DynList.
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
Definition ah-date.H:140
Array< typename C::Item_Type > to_Array(const C &c)
Convert a container to an Array.
Definition ah-convert.H:167
DynArray< T > vector_to_DynArray(const std::vector< T > &v)
Convert a std::vector to a DynArray.
Definition ah-convert.H:291
std::vector< T > DynArray_to_vector(const DynArray< T > &arr)
Convert a DynArray to a std::vector.
std::list< T > DynList_to_list(const DynList< T > &l)
Convert a DynList to a std::list.
void tuple_for_each(const std::tuple< Ts... > &tuple, F func, std::index_sequence< Is... >)
Apply a function to each element in a tuple (tuple first).
std::vector< typename C::Item_Type > to_vector(const C &c)
Convert a container to a std::vector.
Definition ah-convert.H:228
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
auto map_vector(const std::vector< T > &v, Op op) -> std::vector< std::decay_t< decltype(op(v[0]))> >
Map a function over a std::vector.
STL namespace.
typename make_index_tuple< Size-1 >::type::template append< Size-1 > type
DynList< int > l