38#include <gtest/gtest.h>
59 SUCCEED() <<
"C++20 ranges support is available";
61 GTEST_SKIP() <<
"std::ranges not fully supported on this platform (libc++ version)";
68 #ifdef ALEPH_HAS_RANGES
71 FAIL() <<
"ALEPH_HAS_RANGES should be defined";
74 #ifdef ALEPH_HAS_STRIDE
77 FAIL() <<
"ALEPH_HAS_STRIDE should be defined";
80 #ifdef ALEPH_HAS_ENUMERATE
83 FAIL() <<
"ALEPH_HAS_ENUMERATE should be defined";
103 auto evens = std::views::iota(1, 11)
104 | std::views::filter([](
int x) {
return x % 2 == 0; })
110 for (
auto x :
evens) {
117 auto squares = std::views::iota(1, 6)
118 | std::views::transform([](
int x) {
return x * x; })
126 while (it1.has_curr() && it2.has_curr()) {
127 EXPECT_EQ(it1.get_curr(), it2.get_curr());
134 std::vector<int>
vec = {10, 20, 30, 40, 50};
140 for (
auto x : list) {
154 for (
int i = 0; i < 5; ++i) {
160 auto odds = std::views::iota(1, 11)
161 | std::views::filter([](
int x) {
return x % 2 == 1; })
174 auto result = std::views::iota(1, 100)
175 | std::views::filter([](
int x) {
return x % 3 == 0; })
176 | std::views::transform([](
int x) {
return x * 2; })
177 | std::views::take(5)
198 for (
auto x : dlist) {
236 for (
auto x : list) {
250 auto set = std::views::iota(1, 11)
251 | std::views::filter([](
int x) {
return x % 2 == 0; })
277 std::vector<int>
no_even = {1, 3, 5, 7, 9};
278 std::vector<int>
has_even = {1, 2, 3, 4, 5};
293 std::vector<int>
vec = {1, 2, 3, 4, 5};
295 auto it = detail::ranges_find_if(
vec, [](
int x) {
return x > 3; });
299 auto not_found = detail::ranges_find_if(
vec, [](
int x) {
return x > 10; });
304 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
314 std::vector<int>
vec = {1, 2, 3, 4, 5};
325 std::vector<std::string>
strs = {
"Hello",
" ",
"World"};
331 std::vector<int>
vec = {1, 2, 3, 4, 5};
333 auto sum = detail::ranges_sum(
vec);
338 std::vector<int>
vec = {1, 2, 3, 4, 5};
340 auto prod = detail::ranges_product(
vec);
352 for (
auto x :
range) {
361 std::vector<int> result;
362 for (
auto x :
range) {
367 for (
int i = 0; i < 5; ++i) {
376 for (
int i = 0; i < 10; ++i) {
392 using IotaView =
decltype(std::views::iota(1, 10));
395 std::vector<int> v = {1, 2, 3};
396 using FilteredView =
decltype(v | std::views::filter([](
int x) {
return x > 0; }));
430 EXPECT_EQ(sum,
static_cast<long long>(
N) * (
N + 1) / 2);
438 std::vector<std::string>
strs = {
"hello",
"world",
"test"};
443 auto it = list.get_it();
452 std::vector<std::string>
strs = {
"a",
"bb",
"ccc"};
454 | std::views::transform([](
const std::string& s) {
return s.length(); })
470 auto result = std::views::iota(1,
N + 1)
471 | std::views::filter([](
int x) {
return x % 2 == 0; })
472 | std::views::transform([](
int x) {
return x * 3; })
473 | std::views::filter([](
int x) {
return x % 6 == 0; })
474 | std::views::take(100)
480 for (
auto x : result) {
491 auto set = std::views::iota(1, 51)
492 | std::views::filter([](
int x) {
return x > 40; })
503 for (
int i = 1; i <= 5; ++i)
507 for (
auto x : list) {
514 for (
int i = 1; i <= 5; ++i)
525 for (
int i = 1; i <= 5; ++i)
556 std::vector<int>
vec = {3, 1, 4, 1, 5, 9, 2, 6};
558 EXPECT_TRUE(std::ranges::any_of(
vec, [](
int x) {
return x > 5; }));
560 EXPECT_TRUE(std::ranges::none_of(
vec, [](
int x) {
return x > 10; }));
562 auto it = std::ranges::find(
vec, 5);
566 auto min_it = std::ranges::min_element(
vec);
570 auto max_it = std::ranges::max_element(
vec);
624 std::vector<int>
vec = {1, 2, 2, 3, 3, 3};
636 std::vector<int>
vec = {1, 2, 3, 4, 5};
638 auto doubled = detail::ranges_transform(
vec, [](
int x) {
return x * 2; });
641 std::vector<int> result;
655 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
657 auto evens = detail::ranges_filter(
vec, [](
int x) {
return x % 2 == 0; });
659 std::vector<int> result;
660 for (
auto x :
evens) {
673 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
677 std::vector<int> result;
689 std::vector<int>
vec = {1, 2, 3, 4, 5};
693 std::vector<int> result;
705 std::vector<int>
vec = {1, 2, 3, 4, 5};
706 auto empty = detail::ranges_take(
vec, 0);
716 std::vector<int>
vec = {1, 2, 3};
717 auto empty = detail::ranges_drop(
vec, 10);
731 std::vector<int>
vec = {1, 2, 3, 4, 5};
735 std::vector<int> result;
749 std::vector<int>
vec = {3, 1, 4, 1, 5, 9, 2, 6};
757 std::vector<int>
vec = {3, 1, 4, 1, 5, 9, 2, 6};
765 std::vector<int>
vec = {42};
773 std::vector<int>
vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
775 detail::ranges_sort(
vec);
778 for (
int i = 0; i < 9; ++i) {
784 std::vector<int>
vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
786 detail::ranges_sort(
vec, std::greater<>{});
789 for (
int i = 0; i < 9; ++i) {
795 std::vector<std::string>
vec = {
"banana",
"apple",
"cherry",
"date"};
797 detail::ranges_sort(
vec);
810 std::vector<std::vector<int>>
nested = {{1, 2}, {3}, {4, 5, 6}};
814 std::vector<int> result;
815 for (
auto x :
flat) {
829 std::vector<std::vector<int>>
nested = {{}, {}, {}};
841 std::vector<std::vector<int>>
nested = {{1}, {}, {2, 3}, {}};
845 std::vector<int> result;
846 for (
auto x :
flat) {
865 for (
auto x : list) {
882 for (
int i = 1; i <= 10; ++i) {
889 std::views::iota(1, 6) | std::views::transform([](
int x) {
return x * x * x; })
897 while (it1.has_curr()) {
898 EXPECT_EQ(it1.get_curr(), it2.get_curr());
909 auto result = std::views::iota(1, 100)
910 | std::views::filter([](
int x) {
return x % 2 == 0; })
911 | std::views::transform([](
int x) {
return x * x; })
912 | std::views::take(5)
919 auto it1 = result.
get_it();
921 while (it1.has_curr()) {
922 EXPECT_EQ(it1.get_curr(), it2.get_curr());
929 auto result = std::views::iota(1, 11)
930 | std::views::transform([](
int x) {
return x * 10; })
931 | std::views::filter([](
int x) {
return x % 30 != 0; })
932 | std::views::drop(2)
943 std::vector<int>
vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
945 auto result = detail::ranges_reverse(
vec);
946 std::vector<int> rev;
947 for (
auto x : result) {
948 if (x % 2 == 1) rev.push_back(x);
965 const int N = 100000;
967 std::views::iota(1,
N + 1),
972 EXPECT_EQ(sum,
static_cast<long long>(
N) * (
N + 1) / 2);
976 std::vector<int> empty;
985 std::vector<int>
single = {42};
996 std::vector<int>
neg = {-5, -3, -1, 0, 1, 3, 5};
1009 std::vector<double>
floats = {1.5, 2.5, 3.5, 4.5};
1031 std::vector<Point> points = {{1, 2}, {3, 4}, {5, 6}};
1033 auto distances = detail::ranges_transform(points, [](
const Point& p) {
1034 return p.
x * p.
x + p.
y * p.
y;
1037 std::vector<int> result;
1039 result.push_back(d);
1049 std::vector<Point> points = {{0, 0}, {1, 1}, {2, 0}, {0, 2}, {3, 3}};
1069 auto fib = std::views::iota(0)
1070 | std::views::transform([](
int n) {
1073 for (
int i = 0; i < n; ++i) {
1080 | std::views::take(10)
1096 if (n < 2)
return false;
1097 if (n == 2)
return true;
1098 if (n % 2 == 0)
return false;
1099 for (
int i = 3; i * i <= n; i += 2)
1100 if (n % i == 0)
return false;
1106 | std::views::take(10)
1114 while (it1.has_curr()) {
1115 EXPECT_EQ(it1.get_curr(), it2.get_curr());
1127 for (
int i = 1; i <= 5; ++i)
1134 EXPECT_TRUE(std::ranges::all_of(
vec, [](
int x) {
return x > 0; }));
1135 EXPECT_TRUE(std::ranges::any_of(
vec, [](
int x) {
return x == 3; }));
1139 | std::views::transform([](
int x) {
return x * 2; })
1147 while (it1.has_curr()) {
1148 EXPECT_EQ(it1.get_curr(), it2.get_curr());
1156 for (
int i = 1; i <= 10; ++i)
1163 | std::views::filter([](
int x) {
return x % 2 == 0; })
1176 const int N = 50000;
1178 auto result = std::views::iota(1,
N + 1)
1179 | std::views::filter([](
int x) {
return x % 3 == 0; })
1180 | std::views::transform([](
int x) {
return x * 2; })
1181 | std::views::filter([](
int x) {
return x % 4 == 0; })
1182 | std::views::take(1000)
1188 for (
auto x : result) {
1201 auto arr =
vec | std::views::filter([](
int x) {
return x > 50; }) |
to_dynarray_v;
1214 const long long N = 100000;
1217 std::views::iota(1LL,
N + 1),
1228 ::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.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Append a new item by copy.
T & get_first() const
Return the first item of the list.
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.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Rectangular point in the plane.
bool operator<(const Point &other) const
bool operator==(const Point &point) const
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
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.
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
std::string concat(const Args &... args)
Concatenate multiple streamable arguments into a single std::string.
Container< T > range(const T start, const T end, const T step=1)
Generate a range of values [start, end] with a given step.
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.
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.