Skip to content

Commit

Permalink
Add example: filter_int_iterator.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
neatudarius committed Nov 14, 2024
1 parent 16f1069 commit f4f999a
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# cmake-format: on

# List of all buildable examples.
set(EXAMPLES repeated_chars_iterator)
set(EXAMPLES filter_int_iterator repeated_chars_iterator)

foreach(example ${EXAMPLES})
# Add example executable.
Expand Down
69 changes: 69 additions & 0 deletions examples/filter_int_iterator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// examples/filter_int_iterator.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// P2727R4 example: An iterator that allows filtering int elements of a sequence.
#include <beman/iterator_interface/iterator_interface.hpp>

#include <algorithm>
#include <array>
#include <iostream>

// filtered_int_iterator uses std::iterator_interface to define a forward iterator
// that iterates over a sequence of integers, skipping those that do not satisfy a predicate.
template <typename Pred>
struct filtered_int_iterator
: beman::iterator_interface::ext_iterator_interface_compat<filtered_int_iterator<Pred>,
std::forward_iterator_tag,
int> {
// Default constructor creates an end-of-range iterator.
filtered_int_iterator() : m_it_begin(nullptr) {}

// Constructor for the beginning of the sequence.
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)) {
m_it_begin = std::find_if(m_it_begin, m_it_end, m_pred);
}

// A forward iterator based on iterator_interface usually requires
// three user-defined operations. since we are adapting an existing
// iterator (an int *), we only need to define this one. The others are
// implemented by iterator_interface, using the underlying int *.
filtered_int_iterator& operator++() {
m_it_begin = std::find_if(std::next(m_it_begin), m_it_end, m_pred);
return *this;
}

// It is really common for iterator adaptors to have a base() member
// function that returns the adapted iterator.
int* base() const { return m_it_begin; }

private:
// Provide access to base_reference.
friend beman::iterator_interface::iterator_interface_access;

// Provide access to base_reference.
constexpr auto base_reference() noexcept { return m_it_begin; }

// Start of the sequence of integers.
int* m_it_begin;

// End of the sequence of integers.
int* m_it_end;

// Predicate that determines which integers to skip.
Pred m_pred;
};

int main() {
// Create a filtered_int_iterator that iterates over the sequence {1, 2, 3, 4, 10, 11, 101, 200, 0}, skipping odd numbers.
// 0 is not skipped, so it will be the last element in the sequence.
std::array a = {1, 2, 3, 4, 10, 11, 101, 200, 0};
filtered_int_iterator it{std::begin(a), std::end(a), [](int i) { return i % 2 == 0; }};

while (*it) {
std::cout << *it << " ";
++it;
}
std::cout << "\n";

return 0;
}
2 changes: 1 addition & 1 deletion examples/repeated_chars_iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class repeated_chars_iterator
// Default constructor creates an end-of-range iterator.
constexpr repeated_chars_iterator() : m_it_begin(nullptr), m_fixed_size(0), m_pos(0) {}

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

Expand Down

0 comments on commit f4f999a

Please sign in to comment.