38#include <gtest/gtest.h>
58 "ALEPH_NO_RANGES must force ALEPH_HAS_RANGES to 0");
69 SUCCEED() <<
"C++20 ranges support is available";
71 GTEST_SKIP() <<
"std::ranges not fully supported on this platform (libc++ version)";
78 #ifdef ALEPH_HAS_RANGES
81 FAIL() <<
"ALEPH_HAS_RANGES should be defined";
84 #ifdef ALEPH_HAS_STRIDE
87 FAIL() <<
"ALEPH_HAS_STRIDE should be defined";
90 #ifdef ALEPH_HAS_ENUMERATE
93 FAIL() <<
"ALEPH_HAS_ENUMERATE should be defined";
107 for (
auto x : list) {
113 auto evens = std::views::iota(1, 11)
114 | std::views::filter([](
int x) {
return x % 2 == 0; })
120 for (
auto x :
evens) {
127 auto squares = std::views::iota(1, 6)
128 | std::views::transform([](
int x) {
return x * x; })
136 while (it1.has_curr() && it2.has_curr()) {
137 EXPECT_EQ(it1.get_curr(), it2.get_curr());
144 std::vector<int>
vec = {10, 20, 30, 40, 50};
150 for (
auto x : list) {
164 for (
int i = 0; i < 5; ++i) {
170 auto odds = std::views::iota(1, 11)
171 | std::views::filter([](
int x) {
return x % 2 == 1; })
184 auto result = std::views::iota(1, 100)
185 | std::views::filter([](
int x) {
return x % 3 == 0; })
186 | std::views::transform([](
int x) {
return x * 2; })
187 | std::views::take(5)
208 for (
auto x : dlist) {
246 for (
auto x : list) {
260 auto set = std::views::iota(1, 11)
261 | std::views::filter([](
int x) {
return x % 2 == 0; })
287 std::vector<int>
no_even = {1, 3, 5, 7, 9};
288 std::vector<int>
has_even = {1, 2, 3, 4, 5};
303 std::vector<int>
vec = {1, 2, 3, 4, 5};
305 auto it = detail::ranges_find_if(
vec, [](
int x) {
return x > 3; });
309 auto not_found = detail::ranges_find_if(
vec, [](
int x) {
return x > 10; });
314 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
324 std::vector<int>
vec = {1, 2, 3, 4, 5};
335 std::vector<std::string>
strs = {
"Hello",
" ",
"World"};
341 std::vector<int>
vec = {1, 2, 3, 4, 5};
343 auto sum = detail::ranges_sum(
vec);
348 std::vector<int>
vec = {1, 2, 3, 4, 5};
350 auto prod = detail::ranges_product(
vec);
362 for (
auto x :
range) {
371 std::vector<int> result;
372 for (
auto x :
range) {
377 for (
int i = 0; i < 5; ++i) {
386 for (
int i = 0; i < 10; ++i) {
398# if !(defined(_MSC_VER) && defined(__clang__))
406 using IotaView =
decltype(std::views::iota(1, 10));
409 std::vector<int> v = {1, 2, 3};
410 using FilteredView =
decltype(v | std::views::filter([](
int x) {
return x > 0; }));
444 EXPECT_EQ(sum,
static_cast<long long>(
N) * (
N + 1) / 2);
452 std::vector<std::string>
strs = {
"hello",
"world",
"test"};
457 auto it = list.get_it();
466 std::vector<std::string>
strs = {
"a",
"bb",
"ccc"};
468 | std::views::transform([](
const std::string& s) {
return s.length(); })
484 auto result = std::views::iota(1,
N + 1)
485 | std::views::filter([](
int x) {
return x % 2 == 0; })
486 | std::views::transform([](
int x) {
return x * 3; })
487 | std::views::filter([](
int x) {
return x % 6 == 0; })
488 | std::views::take(100)
494 for (
auto x : result) {
505 auto set = std::views::iota(1, 51)
506 | std::views::filter([](
int x) {
return x > 40; })
517 for (
int i = 1; i <= 5; ++i)
521 for (
auto x : list) {
528 for (
int i = 1; i <= 5; ++i)
539 for (
int i = 1; i <= 5; ++i)
570 std::vector<int>
vec = {3, 1, 4, 1, 5, 9, 2, 6};
572 EXPECT_TRUE(std::ranges::any_of(
vec, [](
int x) {
return x > 5; }));
574 EXPECT_TRUE(std::ranges::none_of(
vec, [](
int x) {
return x > 10; }));
576 auto it = std::ranges::find(
vec, 5);
580 auto min_it = std::ranges::min_element(
vec);
584 auto max_it = std::ranges::max_element(
vec);
638 std::vector<int>
vec = {1, 2, 2, 3, 3, 3};
650 std::vector<int>
vec = {1, 2, 3, 4, 5};
652 auto doubled = detail::ranges_transform(
vec, [](
int x) {
return x * 2; });
655 std::vector<int> result;
669 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
671 auto evens = detail::ranges_filter(
vec, [](
int x) {
return x % 2 == 0; });
673 std::vector<int> result;
674 for (
auto x :
evens) {
687 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
691 std::vector<int> result;
703 std::vector<int>
vec = {1, 2, 3, 4, 5};
707 std::vector<int> result;
719 std::vector<int>
vec = {1, 2, 3, 4, 5};
720 auto empty = detail::ranges_take(
vec, 0);
730 std::vector<int>
vec = {1, 2, 3};
731 auto empty = detail::ranges_drop(
vec, 10);
745 std::vector<int>
vec = {1, 2, 3, 4, 5};
747 auto reversed = detail::ranges_reverse(
vec);
749 std::vector<int> result;
750 for (
auto x : reversed) {
763 std::vector<int>
vec = {3, 1, 4, 1, 5, 9, 2, 6};
771 std::vector<int>
vec = {3, 1, 4, 1, 5, 9, 2, 6};
779 std::vector<int>
vec = {42};
787 std::vector<int>
vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
789 detail::ranges_sort(
vec);
792 for (
int i = 0; i < 9; ++i) {
798 std::vector<int>
vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
800 detail::ranges_sort(
vec, std::greater<>{});
803 for (
int i = 0; i < 9; ++i) {
809 std::vector<std::string>
vec = {
"banana",
"apple",
"cherry",
"date"};
811 detail::ranges_sort(
vec);
824 std::vector<std::vector<int>>
nested = {{1, 2}, {3}, {4, 5, 6}};
828 std::vector<int> result;
829 for (
auto x :
flat) {
843 std::vector<std::vector<int>>
nested = {{}, {}, {}};
855 std::vector<std::vector<int>>
nested = {{1}, {}, {2, 3}, {}};
859 std::vector<int> result;
860 for (
auto x :
flat) {
879 for (
auto x : list) {
896 for (
int i = 1; i <= 10; ++i) {
903 std::views::iota(1, 6) | std::views::transform([](
int x) {
return x * x * x; })
909 auto it1 =
cubes.get_it();
911 while (it1.has_curr()) {
912 EXPECT_EQ(it1.get_curr(), it2.get_curr());
923 auto result = std::views::iota(1, 100)
924 | std::views::filter([](
int x) {
return x % 2 == 0; })
925 | std::views::transform([](
int x) {
return x * x; })
926 | std::views::take(5)
933 auto it1 = result.get_it();
935 while (it1.has_curr()) {
936 EXPECT_EQ(it1.get_curr(), it2.get_curr());
943 auto result = std::views::iota(1, 11)
944 | std::views::transform([](
int x) {
return x * 10; })
945 | std::views::filter([](
int x) {
return x % 30 != 0; })
946 | std::views::drop(2)
957 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
959 auto result = detail::ranges_reverse(
vec);
960 std::vector<int> rev;
961 for (
auto x : result) {
962 if (x % 2 == 1) rev.push_back(x);
979 const int N = 100000;
981 std::views::iota(1,
N + 1),
986 EXPECT_EQ(sum,
static_cast<long long>(
N) * (
N + 1) / 2);
990 std::vector<int> empty;
999 std::vector<int>
single = {42};
1010 std::vector<int>
neg = {-5, -3, -1, 0, 1, 3, 5};
1023 std::vector<double>
floats = {1.5, 2.5, 3.5, 4.5};
1045 std::vector<Point> points = {{1, 2}, {3, 4}, {5, 6}};
1047 auto distances = detail::ranges_transform(points, [](
const Point& p) {
1048 return p.x * p.x + p.y * p.y;
1051 std::vector<int> result;
1053 result.push_back(d);
1063 std::vector<Point> points = {{0, 0}, {1, 1}, {2, 0}, {0, 2}, {3, 3}};
1083 auto fib = std::views::iota(0)
1084 | std::views::transform([](
int n) {
1087 for (
int i = 0; i < n; ++i) {
1094 | std::views::take(10)
1110 if (n < 2)
return false;
1111 if (n == 2)
return true;
1112 if (n % 2 == 0)
return false;
1113 for (
int i = 3; i * i <= n; i += 2)
1114 if (n % i == 0)
return false;
1120 | std::views::take(10)
1126 auto it1 =
primes.get_it();
1128 while (it1.has_curr()) {
1129 EXPECT_EQ(it1.get_curr(), it2.get_curr());
1141 for (
int i = 1; i <= 5; ++i)
1148 EXPECT_TRUE(std::ranges::all_of(
vec, [](
int x) {
return x > 0; }));
1149 EXPECT_TRUE(std::ranges::any_of(
vec, [](
int x) {
return x == 3; }));
1153 | std::views::transform([](
int x) {
return x * 2; })
1161 while (it1.has_curr()) {
1162 EXPECT_EQ(it1.get_curr(), it2.get_curr());
1170 for (
int i = 1; i <= 10; ++i)
1177 | std::views::filter([](
int x) {
return x % 2 == 0; })
1190 const int N = 50000;
1192 auto result = std::views::iota(1,
N + 1)
1193 | std::views::filter([](
int x) {
return x % 3 == 0; })
1194 | std::views::transform([](
int x) {
return x * 2; })
1195 | std::views::filter([](
int x) {
return x % 4 == 0; })
1196 | std::views::take(1000)
1202 for (
auto x : result) {
1215 auto arr =
vec | std::views::filter([](
int x) {
return x > 50; }) |
to_dynarray_v;
1228 const long long N = 100000;
1231 std::views::iota(1LL,
N + 1),
1242 ::testing::InitGoogleTest(&
argc,
argv);
C++20 Ranges support and adaptors for Aleph-w containers.
size_t size() const noexcept
Return the current dimension of array.
T & append()
Allocate a new entry to the end of array.
Doubly-linked list (defined in tpl_dynList.H).
T & append(const T &item)
Dynamic set implemented using Red-Black binary search trees of type Rb_Tree<Key> (bottom-up implement...
const size_t & size() const
Returns the cardinality of the set.
Key * insert(const Key &key)
Inserts a key into the dynamic set.
bool has(const Key &key) const
size_t size() const noexcept
Count the number of elements of the list.
Represents a point with rectangular coordinates in a 2D plane.
bool operator==(const Point &point) const noexcept
Checks for exact equality between two points.
bool operator<(const Point &point) const noexcept
Defines a strict lexicographical ordering for points.
Minimal std::expected-style result type for C++20.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Singly linked list implementations with head-tail access.
auto ranges_count_if(const Container &c, Pred &&pred)
Fallback count_if using range-based for loop.
constexpr T ranges_fold_left(Container &&c, T init, BinaryOp &&op)
Fallback fold_left using range-based for loop.
bool ranges_none_of(const Container &c, Pred &&pred)
Fallback none_of using range-based for loop.
bool ranges_any_of(const Container &c, Pred &&pred)
Fallback any_of using range-based for loop.
bool ranges_all_of(const Container &c, Pred &&pred)
Fallback all_of using range-based for loop.
Main namespace for Aleph-w library functions.
std::string concat(const Args &...args)
Concatenate multiple arguments into a single std::string.
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
Container< T > range(const T start, const T end, const T step=1)
Generate a range of values [start, end] with a given step.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Circular queue implementations backed by arrays.
Stack implementations backed by dynamic or fixed arrays.
Lazy and scalable dynamic array implementation.
Dynamic doubly linked list implementation.
Dynamic queue implementation based on linked lists.
Dynamic stack implementation based on linked lists.
Dynamic set implementations based on balanced binary search trees.
Random access queue (bag) with O(1) random pop.