Skip to content

Commit 23b455c

Browse files
committed
Removed iterabler, added sized_iterable, added mutable to functions
1 parent dbeb1fb commit 23b455c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+746
-288
lines changed

examples/algorithm.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,9 @@ int main() {
318318
auto distance = lz::distance(v.begin(), pos);
319319
std::cout << *pos << " with distance " << distance << '\n'; // 2 with distance 1
320320
++pos;
321-
auto iterable = lz::to_iterable(pos, v.end());
322-
pos = lz::adjacent_find(iterable);
323-
std::cout << (pos == iterable.end()) << "\n\n"; // true
321+
lz::sized_iterable<decltype(v.begin())> iterable(pos, v.end());
322+
auto new_pos = lz::adjacent_find(iterable);
323+
std::cout << (new_pos == iterable.end()) << "\n\n"; // true
324324
}
325325
{
326326
std::cout << "Count if\n";

examples/basic_iterable.cpp

+23-5
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,54 @@
11
#include <Lz/basic_iterable.hpp>
22
#include <Lz/c_string.hpp>
3+
#include <vector>
34

45
int main() {
56
// - Iterable as template parameter
67
// - Iterable as function argument
78
// - Iterable has a .size() method because arr has a size
89
int arr[] = { 1, 2, 3, 4, 5 };
9-
lz::basic_iterable<int[5]> iterable_iterable = lz::to_iterable(arr);
10+
lz::basic_iterable<int[5]> iterable_iterable(arr);
1011
std::cout << iterable_iterable.size() << '\n'; // Output: 5
1112

1213
// - Iterator as template parameter
1314
// - Iterable as function argument
1415
// - Iterable has size() method because std::begin(arr) and std::end(arr) are random access iterators
15-
lz::basic_iterable<int*> iterator_iterable = lz::to_iterable(arr);
16+
lz::basic_iterable<int*> iterator_iterable(arr);
1617
std::cout << iterator_iterable.size() << '\n'; // Output: 5
1718

1819
// - Iterable as template parameter
1920
// - Iterator as function argument
2021
// - Iterable has size() method because std::begin(arr) and std::end(arr) are random access iterators
21-
lz::basic_iterable<int[5]> iterable_iterator = lz::to_iterable(std::begin(arr), std::end(arr));
22+
lz::basic_iterable<int[5]> iterable_iterator(std::begin(arr), std::end(arr));
2223
std::cout << iterable_iterator.size() << '\n'; // Output: 5
2324

2425
// - Iterator as template parameter
2526
// - Iterator as function argument
2627
// - Iterable has size() method because std::begin(arr) and std::end(arr) are random access iterators
27-
lz::basic_iterable<int*> iterator_iterator = lz::to_iterable(std::begin(arr), std::end(arr));
28+
lz::basic_iterable<int*> iterator_iterator(std::begin(arr), std::end(arr));
2829
std::cout << iterator_iterator.size() << '\n'; // Output: 5
2930

3031
// You can also work with sentinels:
3132
auto cstr = lz::c_string("Hello, world!");
3233
using it = decltype(cstr.begin());
3334
using sentinel = decltype(cstr.end());
34-
lz::basic_iterable<it, sentinel> iterable = lz::to_iterable(cstr.begin(), cstr.end());
35+
lz::basic_iterable<it, sentinel> iterable(cstr.begin(), cstr.end());
36+
std::cout << "c_string iterable does not contain a size() method\n";
3537
// iterable does not contain a size() method because cstr does not have a size and is also not random access
38+
39+
// This also creates a sized iterable
40+
using it = decltype(cstr.begin());
41+
using sentinel = decltype(cstr.end());
42+
// We need to specify that it is a sized iterable
43+
lz::sized_iterable<it, sentinel> sized_cstr_iterable(cstr.begin(), 5);
44+
std::cout << sized_cstr_iterable.size() << '\n'; // Output: 5
45+
// iterable now contains "Hello"
46+
47+
// The following would get an error because cstr is not random access and there's no way to get the size
48+
// lz::sized_iterable<it, sentinel> sized_cstr_iterable(cstr.begin(), cstr.end());
49+
50+
// With STL containers you can use the following:
51+
std::vector<int> vec = { 1, 2, 3, 4, 5 };
52+
lz::basic_iterable<std::vector<int>::iterator> vec_iterable(vec.begin(), vec.end());
53+
std::cout << vec_iterable.size() << '\n'; // Output: 5
3654
}

examples/c_string.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
int main() {
66
const char* my_str = "Hello, World!";
77

8+
#ifdef LZ_HAS_CXX_17
89
for (const char& c : lz::c_string(my_str)) {
910
std::cout << c;
1011
// or use fmt::print("{}\n", c);
@@ -19,4 +20,19 @@ int main() {
1920
}
2021
// Output: Hello, World!
2122
std::cout << '\n';
23+
#else
24+
lz::for_each(lz::c_string(my_str), [](const char& c) {
25+
std::cout << c;
26+
// or use fmt::print("{}\n", c);
27+
});
28+
// Output: Hello, World!
29+
30+
std::cout << '\n';
31+
const char my_str_iterable[] = "Hello, World!";
32+
lz::for_each(my_str_iterable | lz::c_string, [](const char& c) {
33+
std::cout << c;
34+
// or use fmt::print("{}\n", c);
35+
});
36+
// Output: Hello, World!
37+
#endif
2238
}

examples/chunk_if.cpp

+57-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ int main() {
55
std::string s = "hello world; this is a message;";
66
auto chunked = lz::chunk_if(s, [](const char c) { return c == ';'; });
77

8+
#ifdef LZ_HAS_CXX_17
89
for (auto chunk : chunked) {
910
for (char& c : chunk) {
1011
std::cout << c;
@@ -58,4 +59,59 @@ int main() {
5859
// or use fmt::print("\n");
5960
std::cout << '\n';
6061
}
61-
}
62+
#else
63+
using string_iterable = lz::basic_iterable<std::string::const_iterator>;
64+
lz::for_each(chunked, [](string_iterable chunk) {
65+
for (char c : chunk) {
66+
std::cout << c;
67+
// or use fmt::print("{}", c);
68+
}
69+
std::cout << '\n';
70+
});
71+
// Output:
72+
// hello world
73+
// this is a message
74+
75+
lz::for_each(s | lz::chunk_if([](const char c) { return c == ';'; }), [](string_iterable chunk) {
76+
for (char c : chunk) {
77+
std::cout << c;
78+
// or use fmt::print("{}", c);
79+
}
80+
std::cout << '\n';
81+
});
82+
// Output:
83+
// hello world
84+
// this is a message
85+
86+
// With lz::string[_view]
87+
lz::for_each(s | lz::sv_chunk_if([](const char c) { return c == ';'; }), [](const lz::string_view chunk) {
88+
std::cout.write(chunk.data(), chunk.size());
89+
std::cout << '\n';
90+
});
91+
// Output:
92+
// hello world
93+
// this is a message
94+
95+
lz::for_each(s | lz::s_chunk_if([](const char c) { return c == ';'; }), [](const std::string& chunk) {
96+
std::cout << chunk << '\n';
97+
// or use fmt::print("{}\n", chunk);
98+
});
99+
// Output:
100+
// hello world
101+
// this is a message
102+
103+
// with custom types
104+
lz::for_each(s | lz::t_chunk_if<std::vector<char>>([](const char c) { return c == ';'; }),
105+
[](const std::vector<char>& vec_chunk) {
106+
for (char c : vec_chunk) {
107+
std::cout << c;
108+
// or use fmt::print("{}", c);
109+
}
110+
std::cout << '\n';
111+
});
112+
// Output:
113+
// hello world
114+
// this is a message
115+
116+
#endif
117+
}

examples/custom_iterator.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -204,34 +204,34 @@ int main() {
204204

205205
// ---------------- Custom iterator example ----------------
206206
std::cout << "Custom forward iterator example, going forward.\n";
207-
auto view = lz::to_iterable(custom_fwd_iterator{ 0 }, custom_fwd_iterator{ 10 });
207+
lz::basic_iterable<custom_fwd_iterator> view(custom_fwd_iterator{ 0 }, custom_fwd_iterator{ 10 });
208208
for (/* const */ int& i : view) {
209209
std::cout << i << '\n';
210210
}
211211
std::cout << '\n';
212212

213213
std::cout << "Custom bidirectional iterator example, going backward.\n";
214-
auto view2 = lz::to_iterable(custom_bidi_iterator{ 0 }, custom_bidi_iterator{ 10 });
215-
for (/* const */ int& i : lz::reverse(view2)) {
214+
lz::basic_iterable<custom_bidi_iterator> view1(custom_bidi_iterator{ 0 }, custom_bidi_iterator{ 10 });
215+
for (/* const */ int& i : lz::reverse(view1)) {
216216
std::cout << i << '\n';
217217
}
218218
std::cout << '\n';
219219

220220
std::cout << "Custom random access iterator example, going forward.\n";
221-
auto view3 = lz::to_iterable(custom_ra_iterator{ 0 }, custom_ra_iterator{ 10 });
222-
for (/* const */ int& i : view3) {
221+
lz::basic_iterable<custom_ra_iterator> view2(custom_ra_iterator{ 0 }, custom_ra_iterator{ 10 });
222+
for (/* const */ int& i : view2) {
223223
std::cout << i << '\n';
224224
}
225225
std::cout << '\n';
226226

227227
std::cout << "Custom random access iterator example, going backward.\n";
228-
for (/* [const] */ int& i : lz::reverse(view3)) {
228+
for (/* [const] */ int& i : lz::reverse(view2)) {
229229
std::cout << i << '\n';
230230
}
231231
std::cout << '\n';
232232

233233
std::cout << "Custom random access iterator example, going forward with step 2.\n";
234-
auto it_start = view3.begin();
234+
auto it_start = view2.begin();
235235
std::cout << "*it_start = " << *it_start << '\n';
236236
std::cout << "*(it_start + 2) = " << *(it_start + 2) << '\n';
237237
}

examples/exclude.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ int main() {
1010
std::sort(to_except.begin(), to_except.end()); // Always sort values to except before creating except object
1111
const auto except = lz::except(values, to_except);
1212

13+
#ifdef LZ_HAS_CXX_17
1314
for (int& i : except) {
1415
std::cout << i << ' ';
1516
// or use fmt::print("{} ", i);
@@ -25,4 +26,20 @@ int main() {
2526
std::cout << '\n';
2627
// Output:
2728
// 1 5
29+
#else
30+
lz::for_each(except, [](int i) {
31+
std::cout << i << ' ';
32+
// or use fmt::print("{} ", i);
33+
});
34+
std::cout << '\n';
35+
// Output:
36+
// 1 5
37+
38+
lz::for_each(values | lz::except(to_except), [](int i) {
39+
std::cout << i << ' ';
40+
// or use fmt::print("{} ", i);
41+
});
42+
// Output:
43+
// 1 5
44+
#endif
2845
}

examples/exclusive_scan.cpp

+39-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ int main() {
88
// operator+ is required or add a custom operator+ in its third parameter
99
auto scan = lz::exclusive_scan(array, 0);
1010

11+
#ifdef LZ_HAS_CXX_17
1112
for (int& i : scan) {
1213
std::cout << i << ' ';
1314
// Or use fmt::print("{} ", i);
@@ -43,4 +44,41 @@ int main() {
4344
// 0 + 3 + 5 + 2 + 3 + 4 (17)
4445
// 0 + 3 + 5 + 2 + 3 + 4 + 2 (19)
4546
// 0 + 3 + 5 + 2 + 3 + 4 + 2 + 3 (22)
46-
}
47+
#else
48+
lz::for_each(scan, [](int i) {
49+
std::cout << i << ' ';
50+
// Or use fmt::print("{} ", i);
51+
});
52+
// prints 0 3 8 10 13 17 19 22
53+
54+
// essentially it's:
55+
// 0 (0)
56+
// 0 + 3 (3)
57+
// 0 + 3 + 5 (8)
58+
// 0 + 3 + 5 + 2 (10)
59+
// 0 + 3 + 5 + 2 + 3 (13)
60+
// 0 + 3 + 5 + 2 + 3 + 4 (17)
61+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 (19)
62+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 + 3 (22)
63+
64+
std::cout << '\n';
65+
// The 0 here is important. Cannot be left empty otherwise it will lead to compilation errors because the initial value cannot
66+
// be deduced.
67+
// operator+ is required or add a custom operator+ in its second parameter
68+
lz::for_each(array | lz::exclusive_scan(0), [](int i) {
69+
std::cout << i << ' ';
70+
// Or use fmt::print("{} ", i);
71+
});
72+
// prints 0 3 8 10 13 17 19 22
73+
74+
// essentially it's:
75+
// 0 (0)
76+
// 0 + 3 (3)
77+
// 0 + 3 + 5 (8)
78+
// 0 + 3 + 5 + 2 (10)
79+
// 0 + 3 + 5 + 2 + 3 (13)
80+
// 0 + 3 + 5 + 2 + 3 + 4 (17)
81+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 (19)
82+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 + 3 (22)
83+
#endif
84+
}

examples/generate.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,17 @@ int main() {
1414
},
1515
amount);
1616

17+
#ifdef LZ_HAS_CXX_17
1718
for (std::size_t i : gen) {
1819
std::cout << i << ' ';
1920
// Or use fmt::print("{} ", i);
2021
}
21-
// Output: 0 1 2 3
22+
// Output: 0 1 2 3
23+
#else
24+
lz::for_each(gen, [](std::size_t i) {
25+
std::cout << i << ' ';
26+
// Or use fmt::print("{} ", i);
27+
});
28+
// Output: 0 1 2 3
29+
#endif
2230
}

examples/generate_while.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ int main() {
1010
return std::make_pair(copy != 4, copy);
1111
});
1212

13+
#ifdef LZ_HAS_CXX_17
1314
// Iterator returns the same type as the function pair second type. In this case, int.
1415
for (int i : generator) {
1516
std::cout << i << ' ';
1617
// Or use fmt::print("{} ", i);
1718
}
1819
// Output: 0 1 2 3
20+
#else
21+
lz::for_each(generator, [](int i) {
22+
std::cout << i << ' ';
23+
// Or use fmt::print("{} ", i);
24+
});
25+
// Output: 0 1 2 3
26+
#endif
1927
}

examples/inclusive_scan.cpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ int main() {
88

99
auto scan = lz::inclusive_scan(array);
1010

11+
#ifdef LZ_HAS_CXX_17
1112
for (int& i : scan) {
1213
std::cout << i << ' ';
1314
// Or use fmt::print("{} ", i);
@@ -39,4 +40,37 @@ int main() {
3940
// 0 + 3 + 5 + 2 + 3 + 4 = 17
4041
// 0 + 3 + 5 + 2 + 3 + 4 + 2 = 19
4142
// 0 + 3 + 5 + 2 + 3 + 4 + 2 + 3 = 22
42-
}
43+
#else
44+
lz::for_each(scan, [](int i) {
45+
std::cout << i << ' ';
46+
// Or use fmt::print("{} ", i);
47+
});
48+
// prints 3 8 10 13 17 19 22
49+
50+
// essentially it's:
51+
// 0 + 3 = 3
52+
// 0 + 3 + 5 = 8
53+
// 0 + 3 + 5 + 2 = 10
54+
// 0 + 3 + 5 + 2 + 3 = 13
55+
// 0 + 3 + 5 + 2 + 3 + 4 = 17
56+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 = 19
57+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 + 3 = 22
58+
59+
std::cout << '\n';
60+
// The 0 here is important. Cannot be left empty otherwise it will lead to compilation errors because the initial value cannot
61+
// be deduced.
62+
// operator+ is required or add a custom operator+ in its second parameter
63+
lz::for_each(array | lz::inclusive_scan(0), [](int i) {
64+
std::cout << i << ' ';
65+
// Or use fmt::print("{} ", i);
66+
});
67+
// essentially it's:
68+
// 0 + 3 = 3
69+
// 0 + 3 + 5 = 8
70+
// 0 + 3 + 5 + 2 = 10
71+
// 0 + 3 + 5 + 2 + 3 = 13
72+
// 0 + 3 + 5 + 2 + 3 + 4 = 17
73+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 = 19
74+
// 0 + 3 + 5 + 2 + 3 + 4 + 2 + 3 = 22
75+
#endif
76+
}

0 commit comments

Comments
 (0)