From b3b17722fa79320bd17018cd61c6637296634c53 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 18 Aug 2023 14:27:13 -0700 Subject: [PATCH] Remove IndexRangePredicateIterator --- BUILD.bazel | 22 - CMakeLists.txt | 2 - .../index_range_predicate_iterator.hpp | 267 ------------ test/index_range_predicate_iterator_test.cpp | 392 ------------------ 4 files changed, 683 deletions(-) delete mode 100644 include/fixed_containers/index_range_predicate_iterator.hpp delete mode 100644 test/index_range_predicate_iterator_test.cpp diff --git a/BUILD.bazel b/BUILD.bazel index efd994ee..5079b06b 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -260,17 +260,6 @@ cc_library( copts = ["-std=c++20"], ) -cc_library( - name = "index_range_predicate_iterator", - hdrs = ["include/fixed_containers/index_range_predicate_iterator.hpp"], - includes = ["include"], - deps = [ - ":arrow_proxy", - ":iterator_utils", - ], - copts = ["-std=c++20"], -) - cc_library( name = "integer_range", hdrs = ["include/fixed_containers/integer_range.hpp"], @@ -664,17 +653,6 @@ cc_test( copts = ["-std=c++20"], ) -cc_test( - name = "index_range_predicate_iterator_test", - srcs = ["test/index_range_predicate_iterator_test.cpp"], - deps = [ - ":index_range_predicate_iterator", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], - copts = ["-std=c++20"], -) - cc_test( name = "integer_range_test", srcs = ["test/integer_range_test.cpp"], diff --git a/CMakeLists.txt b/CMakeLists.txt index 28c55297..943e74f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,8 +167,6 @@ if(BUILD_TESTS) add_test_dependencies(fixed_vector_test) add_executable(in_out_test test/in_out_test.cpp) add_test_dependencies(in_out_test) - add_executable(index_range_predicate_iterator_test test/index_range_predicate_iterator_test.cpp) - add_test_dependencies(index_range_predicate_iterator_test) add_executable(instance_counter_test test/instance_counter_test.cpp) add_test_dependencies(instance_counter_test) add_executable(integer_range_test test/integer_range_test.cpp) diff --git a/include/fixed_containers/index_range_predicate_iterator.hpp b/include/fixed_containers/index_range_predicate_iterator.hpp deleted file mode 100644 index e27a63b8..00000000 --- a/include/fixed_containers/index_range_predicate_iterator.hpp +++ /dev/null @@ -1,267 +0,0 @@ -#pragma once - -#include "fixed_containers/arrow_proxy.hpp" -#include "fixed_containers/iterator_utils.hpp" - -#include -#include -#include -#include - -namespace fixed_containers -{ -template -concept IndexBasedProvider = requires(P p, std::size_t i) { - p.update_to_index(i); - p.get(); -}; - -// This class is a simple iterator that allows filtered iteration over a collection. -// We are using this class to iterate over collections where we would otherwise -// have made copies as the result of applying a filter. -// -// Const/MutableReferenceProvider is the type of a function that takes an index and returns a -// reference to an element. -// -// IndexPredicate is the type of a function that takes an index and -// returns true if the object at that index in the collection matches the condition of the -// predicate. -template -class IndexRangePredicateIterator -{ - static constexpr IteratorConstness NEGATED_CONSTNESS = IteratorConstness(!bool(CONSTNESS)); - - using Self = IndexRangePredicateIterator; - - // Sibling has the same parameters, but different const-ness - using Sibling = IndexRangePredicateIterator; - - // Give Sibling access to private members - friend class IndexRangePredicateIterator; - - using ReverseBase = IndexRangePredicateIterator; - - using ReferenceProvider = std::conditional_t; - - using ReturnedType = decltype(std::declval().get()); - static constexpr bool SAFE_LIFETIME = std::is_reference_v; - -public: - using reference = ReturnedType; - using value_type = std::remove_cvref_t; - using pointer = - std::conditional_t, ArrowProxy>; - using iterator = Self; - using iterator_category = std::bidirectional_iterator_tag; - using difference_type = std::ptrdiff_t; - -private: - IndexPredicate predicate_; - ReferenceProvider reference_provider_; - std::size_t current_index_; - std::size_t end_index_; - -public: - constexpr IndexRangePredicateIterator() noexcept - : IndexRangePredicateIterator{{}, {}, {}, {}} - { - } - - constexpr IndexRangePredicateIterator(const IndexPredicate& predicate, - const ReferenceProvider& reference_provider, - const std::size_t start_index, - const std::size_t end_index) noexcept - : predicate_(predicate) - , reference_provider_(reference_provider) - , current_index_(start_index) - , end_index_(end_index) - { - assert(start_index <= end_index); - - if constexpr (DIRECTION == IteratorDirection::FORWARD) - { - if (start_index < end_index && !predicate(current_index_)) - { - advance(); - } - } - else - { - advance(); - } - - update_reference(); - } - - // Mutable iterator needs to be convertible to const iterator - constexpr IndexRangePredicateIterator(const Sibling& other) noexcept - requires(CONSTNESS == IteratorConstness::CONSTANT_ITERATOR) - : IndexRangePredicateIterator{ - other.predicate_, other.reference_provider_, other.current_index_, other.end_index_} - { - update_reference(); - } - - constexpr reference operator*() const noexcept { return reference_provider_.get(); } - - constexpr pointer operator->() const noexcept - { - if constexpr (SAFE_LIFETIME) - { - return &reference_provider_.get(); - } - else - { - return {reference_provider_.get()}; - } - } - - constexpr Self& operator++() noexcept - { - advance(); - update_reference(); - return *this; - } - - constexpr Self operator++(int) & noexcept - { - Self tmp = *this; - advance(); - update_reference(); - return tmp; - } - - constexpr Self& operator--() noexcept - { - recede(); - update_reference(); - return *this; - } - - constexpr Self operator--(int) & noexcept - { - Self tmp = *this; - recede(); - update_reference(); - return tmp; - } - - constexpr bool operator==(const Self& other) const noexcept - { - return current_index_ == other.current_index_ && end_index_ == other.end_index_; - } - - constexpr bool operator==(const Sibling& other) const noexcept - { - return current_index_ == other.current_index_ && end_index_ == other.end_index_; - } - - constexpr ReverseBase base() const noexcept - requires(DIRECTION == IteratorDirection::REVERSE) - { - ReverseBase out{predicate_, reference_provider_, current_index_, end_index_}; - ++out; - return out; - } - -private: - constexpr void update_reference() - { - if (current_index_ >= end_index_) - { - return; - } - - reference_provider_.update_to_index(this->current_index_); - } - - constexpr void advance() noexcept - { - if constexpr (DIRECTION == IteratorDirection::FORWARD) - { - advance_left(); - } - else - { - recede_left(); - } - } - constexpr void recede() noexcept - { - if constexpr (DIRECTION == IteratorDirection::FORWARD) - { - recede_left(); - } - else - { - advance_left(); - } - } - - constexpr void advance_left() noexcept - { - for (std::size_t i = current_index_ + 1; i < end_index_; i++) - { - if (predicate_(i)) - { - current_index_ = i; - return; - } - } - - current_index_ = end_index_; - } - constexpr void recede_left() noexcept - { - // Reverse unsigned iteration terminates when i underflows - for (std::size_t i = current_index_ - 1; i <= current_index_; i--) - { - if (predicate_(i)) - { - current_index_ = i; - return; - } - } - - current_index_ = current_index_ - 1; - } -}; - -struct IndexPredicateAlwaysTrue -{ - constexpr bool operator()(const std::size_t /*i*/) const { return true; } -}; - -template -using IndexRangeIterator = IndexRangePredicateIterator; - -} // namespace fixed_containers diff --git a/test/index_range_predicate_iterator_test.cpp b/test/index_range_predicate_iterator_test.cpp deleted file mode 100644 index 74f47e44..00000000 --- a/test/index_range_predicate_iterator_test.cpp +++ /dev/null @@ -1,392 +0,0 @@ -#include "fixed_containers/index_range_predicate_iterator.hpp" - -#include - -#include - -namespace fixed_containers -{ -namespace -{ -struct EvenValuesOnly -{ - constexpr bool operator()(const std::size_t i) const { return i % 2 == 0; } -}; - -struct AlwaysFalsePredicate -{ - constexpr bool operator()(const std::size_t i) const { return i % 2 == 0; } -}; - -struct IdentityIndexProvider -{ - std::size_t current_index_; - constexpr void update_to_index(const std::size_t i) noexcept { current_index_ = i; } - [[nodiscard]] constexpr std::size_t get() const noexcept { return current_index_; } -}; - -} // namespace - -TEST(IndexRangeIterator, Forward_StartingConditions) -{ - using ItType = IndexRangeIterator; - { - constexpr ItType it{{}, {}, 0, 3}; - static_assert(0 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 1, 3}; - static_assert(1 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 2, 3}; - static_assert(2 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 3, 3}; - // Not formally dereference-able - static_assert(0 == std::integral_constant{}); - } - - { - constexpr ItType it{{}, {}, 3, 6}; - static_assert(3 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 4, 6}; - static_assert(4 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 5, 6}; - static_assert(5 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 6, 6}; - // Not formally dereference-able - static_assert(0 == std::integral_constant{}); - } -} - -TEST(IndexRangePredicateIterator, Forward_StartingConditions) -{ - using ItType = IndexRangePredicateIterator; - { - constexpr ItType it{{}, {}, 0, 3}; - static_assert(0 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 1, 3}; - static_assert(2 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 2, 3}; - static_assert(2 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 3, 3}; - // Not formally dereference-able - static_assert(0 == std::integral_constant{}); - } - - { - constexpr ItType it{{}, {}, 3, 6}; - static_assert(4 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 4, 6}; - static_assert(4 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 5, 6}; - // Not formally dereference-able - static_assert(0 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 6, 6}; - // Not formally dereference-able - static_assert(0 == std::integral_constant{}); - } -} - -TEST(IndexRangeIterator, Forward_EmptyIterator) -{ - using ItType = IndexRangePredicateIterator; - { - constexpr ItType it{{}, {}, 0, 3}; - static_assert(0 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 3, 3}; - static_assert(0 == std::integral_constant{}); - } -} - -TEST(IndexRangeIterator, Reverse_EmptyIterator) -{ - using ItType = IndexRangePredicateIterator; - { - constexpr ItType it{{}, {}, 3, 3}; - static_assert(2 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 0, 3}; - static_assert(0 == std::integral_constant{}); - } -} - -TEST(IndexRangeIterator, Reverse_StartingConditions) -{ - using ItType = IndexRangeIterator; - { - constexpr ItType it{{}, {}, 3, 3}; - static_assert(2 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 2, 3}; - static_assert(1 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 1, 3}; - static_assert(0 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 0, 3}; - // Not formally dereference-able - static_assert(0 == std::integral_constant{}); - } -} - -TEST(IndexRangePredicateIterator, Reverse_StartingConditions) -{ - using ItType = IndexRangePredicateIterator; - { - constexpr ItType it{{}, {}, 3, 3}; - static_assert(2 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 2, 3}; - static_assert(0 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 1, 3}; - static_assert(0 == std::integral_constant{}); - } - { - constexpr ItType it{{}, {}, 0, 3}; - // Not formally dereference-able - static_assert(0 == std::integral_constant{}); - } -} - -TEST(IndexRangeIterator, ForwardIncrement) -{ - using ItType = IndexRangeIterator; - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 0, 3}, ItType{{}, {}, 3, 3}); - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType end{{}, {}, 3, 3}; - std::size_t counter = 0; - std::array output{}; - for (ItType it{{}, {}, 0, 3}; it != end; ++it) - { - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == std::array{0, 1, 2}); - } - - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 3, 6}, ItType{{}, {}, 6, 6}); - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType end{{}, {}, 6, 6}; - std::size_t counter = 0; - std::array output{}; - for (ItType it{{}, {}, 3, 6}; it != end; ++it) - { - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == std::array{3, 4, 5}); - } -} - -TEST(IndexRangeIterator, ForwardDecrement) -{ - using ItType = IndexRangeIterator; - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 0, 3}, ItType{{}, {}, 3, 3}); - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType start{{}, {}, 0, 3}; - std::size_t counter = 0; - std::array output{}; - ItType it{{}, {}, 3, 3}; - while (it != start) - { - --it; - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == std::array{2, 1, 0}); - } - - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 3, 6}, ItType{{}, {}, 6, 6}); - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType start{{}, {}, 3, 6}; - std::size_t counter = 0; - std::array output{}; - ItType it{{}, {}, 6, 6}; - while (it != start) - { - --it; - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == std::array{5, 4, 3}); - } -} - -TEST(IndexRangeIterator, ReverseIncrement) -{ - using ItType = IndexRangeIterator; - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 3, 3}, ItType{{}, {}, 0, 3}); - - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType end{{}, {}, 0, 3}; - std::size_t counter = 0; - std::array output{}; - for (ItType it{{}, {}, 3, 3}; it != end; ++it) - { - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == (std::array{2, 1, 0})); - } - - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 6, 6}, ItType{{}, {}, 3, 6}); - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType end{{}, {}, 3, 6}; - std::size_t counter = 0; - std::array output{}; - for (ItType it{{}, {}, 6, 6}; it != end; ++it) - { - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == std::array{5, 4, 3}); - } -} - -TEST(IndexRangeIterator, ReverseDecrement) -{ - using ItType = IndexRangeIterator; - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 3, 3}, ItType{{}, {}, 0, 3}); - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType end{{}, {}, 3, 3}; - std::size_t counter = 0; - std::array output{}; - ItType it{{}, {}, 0, 3}; - while (it != end) - { - --it; - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == std::array{0, 1, 2}); - } - - { - constexpr std::size_t DISTANCE = std::distance(ItType{{}, {}, 6, 6}, ItType{{}, {}, 3, 6}); - static_assert(3 == std::integral_constant{}); - constexpr std::array ret = []() - { - const ItType end{{}, {}, 6, 6}; - std::size_t counter = 0; - std::array output{}; - ItType it{{}, {}, 3, 6}; - while (it != end) - { - --it; - output[counter] = *it; - counter++; - } - - return output; - }(); - static_assert(ret == std::array{3, 4, 5}); - } -} - -} // namespace fixed_containers