Skip to content

Checked and fixed formatting. #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions examples/filter_int_iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
// filtered_int_iterator uses 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> {
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)) {
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);
}

Expand Down Expand Up @@ -58,11 +58,11 @@ struct filtered_int_iterator
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};
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) { // Expected output at STDOUT:
std::cout << *it << " "; // 2 4 10 200 0

while (*it) { // Expected output at STDOUT:
std::cout << *it << " "; // 2 4 10 200 0
++it;
}
std::cout << "\n";
Expand Down
27 changes: 13 additions & 14 deletions examples/repeated_chars_iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,27 @@
// repeated_chars_iterator uses iterator_interface to define a random access iterator
// that iterates over a sequence of characters repeated indefinitely.
class repeated_chars_iterator
: public beman::iterator_interface::ext_iterator_interface_compat<repeated_chars_iterator,
std::random_access_iterator_tag,
char,
char> {
public:
: public beman::iterator_interface::
ext_iterator_interface_compat<repeated_chars_iterator, std::random_access_iterator_tag, char, char> {
public:
// 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 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) {}

// Random access iterator requirements:
constexpr auto operator*() const { return m_it_begin[m_pos % m_fixed_size]; }
constexpr auto operator*() const { return m_it_begin[m_pos % m_fixed_size]; }
constexpr repeated_chars_iterator& operator+=(std::ptrdiff_t i) {
m_pos += i;
return *this;
}
constexpr auto operator-(repeated_chars_iterator other) const { return m_pos - other.m_pos; }

private:
private:
// Start of the sequence of characters.
const char* m_it_begin;
const char* m_it_begin;

// Number of characters in the sequence.
difference_type m_fixed_size;
Expand All @@ -49,17 +47,18 @@ int main() {
// Create a repeated_chars_iterator that iterates over the sequence "foo" repeated indefinitely:
// "foofoofoofoofoofoo...". Will actually extract a prefix of the sequence and insert it into a std::string.
constexpr const std::string_view target = "foo";
constexpr const auto len = 7; // Number of extracted characters from the sequence.
constexpr const auto len = 7; // Number of extracted characters from the sequence.

// Create iterators that go over the sequence "foofoofoofoofoofoo...".
repeated_chars_iterator it_first(target.data(), target.size(), 0); // target.size() == 3 is the length of "foo", 0 is this iterator's position.
repeated_chars_iterator it_last(target.data(), target.size(), len); // Same as above, but now the iterator's position is 7.
repeated_chars_iterator it_first(
target.data(), target.size(), 0); // target.size() == 3 is the length of "foo", 0 is this iterator's position.
repeated_chars_iterator it_last(
target.data(), target.size(), len); // Same as above, but now the iterator's position is 7.

std::string extracted_result;
std::copy(it_first, it_last, std::back_inserter(extracted_result));
assert(extracted_result.size() == len);
std::cout << extracted_result << "\n"; // Expected output at STDOUT: "foofoof"
std::cout << extracted_result << "\n"; // Expected output at STDOUT: "foofoof"

return 0;
}

Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
// multiple vI namespace alternatives exist. For example, some instances of
// the v1 namespace may still be inline, if there is no v2 version of its
// contents.
#if !BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS && !BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#if !BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS && \
!BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 inline namespace v1
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
#elif BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS && !BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#elif BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS && \
!BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 inline namespace v2
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ namespace stl_interfaces {
this template implies a copy or move of the underlying object of type
`T`. */
template <typename T>
#if defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN) || BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS
#if defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN) || \
BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS
// clang-format off
requires std::is_object_v<T>
#endif
Expand Down Expand Up @@ -99,7 +100,9 @@ struct common_eq {
};
template <typename T, typename U>
struct common_eq<T, U, true> {
static constexpr auto call(T lhs, U rhs) { return iterator_interface_access::base(lhs) == iterator_interface_access::base(rhs); }
static constexpr auto call(T lhs, U rhs) {
return iterator_interface_access::base(lhs) == iterator_interface_access::base(rhs);
}
};

template <typename T, typename U>
Expand Down Expand Up @@ -213,7 +216,7 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
template <typename D = Derived>
constexpr auto operator->() const
noexcept(noexcept(detail::make_pointer<pointer, reference>(*std::declval<const D&>())))
-> decltype(detail::make_pointer<pointer, reference>(*std::declval<const D&>())) {
-> decltype(detail::make_pointer<pointer, reference>(*std::declval<const D&>())) {
return detail::make_pointer<pointer, reference>(*derived());
}

Expand Down Expand Up @@ -249,7 +252,8 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
}

template <typename D = Derived>
constexpr auto operator+=(difference_type n) noexcept(noexcept(iterator_interface_access::base(std::declval<D&>()) += n))
constexpr auto
operator+=(difference_type n) noexcept(noexcept(iterator_interface_access::base(std::declval<D&>()) += n))
-> decltype(iterator_interface_access::base(std::declval<D&>()) += n, std::declval<D&>()) {
iterator_interface_access::base(derived()) += n;
return derived();
Expand All @@ -263,8 +267,8 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
retval += i;
return retval;
}
friend BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR Derived operator+(difference_type i,
Derived it) noexcept {
friend BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR Derived
operator+(difference_type i, Derived it) noexcept {
return it + i;
}

Expand Down Expand Up @@ -299,8 +303,10 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 {

template <typename D = Derived>
constexpr auto operator-(D other) const
noexcept(noexcept(iterator_interface_access::base(std::declval<const D&>()) - iterator_interface_access::base(other)))
-> decltype(iterator_interface_access::base(std::declval<const D&>()) - iterator_interface_access::base(other)) {
noexcept(noexcept(iterator_interface_access::base(std::declval<const D&>()) -
iterator_interface_access::base(other)))
-> decltype(iterator_interface_access::base(std::declval<const D&>()) -
iterator_interface_access::base(other)) {
return iterator_interface_access::base(derived()) - iterator_interface_access::base(other);
}

Expand Down Expand Up @@ -402,7 +408,8 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
} // namespace stl_interfaces
} // namespace beman::iterator_interface::detail

#if defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN) || BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS
#if defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN) || \
BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS

namespace beman::iterator_interface::detail {
namespace stl_interfaces {
Expand Down Expand Up @@ -727,7 +734,8 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 {

#endif

#if defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN) || BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS
#if defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN) || \
BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS

namespace beman::iterator_interface::detail {
namespace stl_interfaces {
Expand Down Expand Up @@ -954,15 +962,15 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 {
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(iter, concept_name)
#endif

#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS_IMPL( \
#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS_IMPL( \
iter, category, value_t, ref, ptr, diff_t) \
static_assert(std::is_same<typename std::iterator_traits<iter>::value_type, value_t>::value, ""); \
static_assert(std::is_same<typename std::iterator_traits<iter>::reference, ref>::value, ""); \
static_assert(std::is_same<typename std::iterator_traits<iter>::pointer, ptr>::value, ""); \
static_assert(std::is_same<typename std::iterator_traits<iter>::difference_type, diff_t>::value, "");

#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( \
iter, category, concept, value_type, reference, pointer, difference_type) \
iter, category, concept, value_type, reference, pointer, difference_type) \
BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS_IMPL( \
iter, category, value_type, reference, pointer, difference_type)
#endif
Expand Down
30 changes: 13 additions & 17 deletions include/beman/iterator_interface/iterator_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,31 +142,27 @@ struct iter_cat<IteratorConcept, ReferenceType, false> {};

template <typename IteratorConcept, typename ReferenceType>
struct iter_cat<IteratorConcept, ReferenceType, true> {
using iterator_category =
std::conditional_t<
!std::is_reference_v<ReferenceType>,
std::input_iterator_tag,
std::conditional_t<
std::is_base_of_v<std::random_access_iterator_tag, IteratorConcept>,
std::random_access_iterator_tag,
std::conditional_t<
std::is_base_of_v<std::bidirectional_iterator_tag, IteratorConcept>,
std::bidirectional_iterator_tag,
std::forward_iterator_tag>>>;
using iterator_category = std::conditional_t<
!std::is_reference_v<ReferenceType>,
std::input_iterator_tag,
std::conditional_t<std::is_base_of_v<std::random_access_iterator_tag, IteratorConcept>,
std::random_access_iterator_tag,
std::conditional_t<std::is_base_of_v<std::bidirectional_iterator_tag, IteratorConcept>,
std::bidirectional_iterator_tag,
std::forward_iterator_tag>>>;
};

} // namespace detail

template <class IteratorConcept, class ValueType, class Reference, class Pointer, class DifferenceType>
class iterator_interface
: detail::iter_cat<IteratorConcept, Reference, std::derived_from<IteratorConcept, std::forward_iterator_tag>>
{
: detail::iter_cat<IteratorConcept, Reference, std::derived_from<IteratorConcept, std::forward_iterator_tag>> {
public:
using iterator_concept = IteratorConcept;
using value_type = remove_const_t<ValueType>;
using reference = Reference;
using pointer = conditional_t<is_same_v<iterator_concept, output_iterator_tag>, void, Pointer>;
using difference_type = DifferenceType;
using value_type = remove_const_t<ValueType>;
using reference = Reference;
using pointer = conditional_t<is_same_v<iterator_concept, output_iterator_tag>, void, Pointer>;
using difference_type = DifferenceType;

constexpr decltype(auto) operator*(this auto&& self)
requires requires { *iterator_interface_access::base(self); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ struct iterator_interface_access {
return d.base_reference();
}
};
}
}
} // namespace iterator_interface
} // namespace beman
#endif
52 changes: 24 additions & 28 deletions tests/beman/iterator_interface/iterator_interface.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,25 +60,25 @@ TEST(IteratorTest, TestRepeatedChars) {
TEST(IteratorTest, TestDistance) {
auto lambda = [&] {
repeated_chars_iterator first("foo", 3, 0); // 3 is the length of "foo", 0 is this iterator's position.
repeated_chars_iterator last("foo", 3, 3); // 3 is the length of "foo", 3 is this iterator's position.
repeated_chars_iterator last("foo", 3, 3); // 3 is the length of "foo", 3 is this iterator's position.
std::string result;
std::copy(first, last, std::back_inserter(result));
CONSTEXPR_EXPECT_EQ(std::distance(first, last), 3);
};

static_assert((lambda(), true));
lambda();
lambda();
}

TEST(IteratorTest, TestNext) {
auto lambda = [&] {
repeated_chars_iterator first("foo", 3, 0); // 3 is the length of "foo", 0 is this iterator's position.
repeated_chars_iterator last("foo", 3, 3); // 3 is the length of "foo", 3 is this iterator's position.
repeated_chars_iterator last("foo", 3, 3); // 3 is the length of "foo", 3 is this iterator's position.
CONSTEXPR_EXPECT_EQ(std::next(first, 3), last);
};

static_assert((lambda(), true));
lambda();
lambda();
}

TEST(IteratorTest, TestConcepts) {
Expand Down Expand Up @@ -174,30 +174,26 @@ TEST(IteratorTest, OperatorArrow) {
ASSERT_EQ(ai->f(), 3);
}

struct dummy_input_iterator :
public ext_iterator_interface_compat<
dummy_input_iterator, std::input_iterator_tag, int, int const&, void, std::ptrdiff_t> {
constexpr dummy_input_iterator() { }
dummy_input_iterator(dummy_input_iterator const&) = delete;
dummy_input_iterator& operator=(dummy_input_iterator const&) = delete;
dummy_input_iterator(dummy_input_iterator&&) = default;
dummy_input_iterator& operator=(dummy_input_iterator&&) = default;
constexpr reference operator*() const {
return foo;
}
constexpr dummy_input_iterator& operator++() {
return *this;
}
constexpr void operator++(int) {}

friend constexpr bool operator==(std::default_sentinel_t const&,
dummy_input_iterator const&) {
return true;
}

friend beman::iterator_interface::iterator_interface_access;

int foo = 0;
struct dummy_input_iterator : public ext_iterator_interface_compat<dummy_input_iterator,
std::input_iterator_tag,
int,
const int&,
void,
std::ptrdiff_t> {
constexpr dummy_input_iterator() {}
dummy_input_iterator(const dummy_input_iterator&) = delete;
dummy_input_iterator& operator=(const dummy_input_iterator&) = delete;
dummy_input_iterator(dummy_input_iterator&&) = default;
dummy_input_iterator& operator=(dummy_input_iterator&&) = default;
constexpr reference operator*() const { return foo; }
constexpr dummy_input_iterator& operator++() { return *this; }
constexpr void operator++(int) {}

friend constexpr bool operator==(const std::default_sentinel_t&, const dummy_input_iterator&) { return true; }

friend beman::iterator_interface::iterator_interface_access;

int foo = 0;
};

static_assert(std::input_iterator<dummy_input_iterator>);
Expand Down