Skip to content

Commit f4f999a

Browse files
committed
Add example: filter_int_iterator.cpp
1 parent 16f1069 commit f4f999a

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

examples/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# cmake-format: on
55

66
# List of all buildable examples.
7-
set(EXAMPLES repeated_chars_iterator)
7+
set(EXAMPLES filter_int_iterator repeated_chars_iterator)
88

99
foreach(example ${EXAMPLES})
1010
# Add example executable.

examples/filter_int_iterator.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// examples/filter_int_iterator.cpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
// P2727R4 example: An iterator that allows filtering int elements of a sequence.
5+
#include <beman/iterator_interface/iterator_interface.hpp>
6+
7+
#include <algorithm>
8+
#include <array>
9+
#include <iostream>
10+
11+
// filtered_int_iterator uses std::iterator_interface to define a forward iterator
12+
// that iterates over a sequence of integers, skipping those that do not satisfy a predicate.
13+
template <typename Pred>
14+
struct filtered_int_iterator
15+
: beman::iterator_interface::ext_iterator_interface_compat<filtered_int_iterator<Pred>,
16+
std::forward_iterator_tag,
17+
int> {
18+
// Default constructor creates an end-of-range iterator.
19+
filtered_int_iterator() : m_it_begin(nullptr) {}
20+
21+
// Constructor for the beginning of the sequence.
22+
filtered_int_iterator(int* it_begin, int* it_end, Pred pred) : m_it_begin(it_begin), m_it_end(it_end), m_pred(std::move(pred)) {
23+
m_it_begin = std::find_if(m_it_begin, m_it_end, m_pred);
24+
}
25+
26+
// A forward iterator based on iterator_interface usually requires
27+
// three user-defined operations. since we are adapting an existing
28+
// iterator (an int *), we only need to define this one. The others are
29+
// implemented by iterator_interface, using the underlying int *.
30+
filtered_int_iterator& operator++() {
31+
m_it_begin = std::find_if(std::next(m_it_begin), m_it_end, m_pred);
32+
return *this;
33+
}
34+
35+
// It is really common for iterator adaptors to have a base() member
36+
// function that returns the adapted iterator.
37+
int* base() const { return m_it_begin; }
38+
39+
private:
40+
// Provide access to base_reference.
41+
friend beman::iterator_interface::iterator_interface_access;
42+
43+
// Provide access to base_reference.
44+
constexpr auto base_reference() noexcept { return m_it_begin; }
45+
46+
// Start of the sequence of integers.
47+
int* m_it_begin;
48+
49+
// End of the sequence of integers.
50+
int* m_it_end;
51+
52+
// Predicate that determines which integers to skip.
53+
Pred m_pred;
54+
};
55+
56+
int main() {
57+
// Create a filtered_int_iterator that iterates over the sequence {1, 2, 3, 4, 10, 11, 101, 200, 0}, skipping odd numbers.
58+
// 0 is not skipped, so it will be the last element in the sequence.
59+
std::array a = {1, 2, 3, 4, 10, 11, 101, 200, 0};
60+
filtered_int_iterator it{std::begin(a), std::end(a), [](int i) { return i % 2 == 0; }};
61+
62+
while (*it) {
63+
std::cout << *it << " ";
64+
++it;
65+
}
66+
std::cout << "\n";
67+
68+
return 0;
69+
}

examples/repeated_chars_iterator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class repeated_chars_iterator
2020
// Default constructor creates an end-of-range iterator.
2121
constexpr repeated_chars_iterator() : m_it_begin(nullptr), m_fixed_size(0), m_pos(0) {}
2222

23-
// Constructor for the beginning of the range.
23+
// Constructor for the beginning of the sequence.
2424
constexpr repeated_chars_iterator(const char* it_begin, difference_type size, difference_type n)
2525
: m_it_begin(it_begin), m_fixed_size(size), m_pos(n) {}
2626

0 commit comments

Comments
 (0)