From 0f902ef2d9723787c99e3a31ba98db8018172a98 Mon Sep 17 00:00:00 2001 From: WiktorNowak Date: Fri, 10 Jan 2025 19:19:43 +0100 Subject: [PATCH] fix: copy of buffered file iterator --- include/rusty_iterators/file_iterator.hpp | 15 ++++----------- tests/file_iterator.test.cpp | 21 +++++++++++++++++++++ tests/iterator.test.cpp | 4 +++- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/include/rusty_iterators/file_iterator.hpp b/include/rusty_iterators/file_iterator.hpp index e4a9649..146a6ff 100644 --- a/include/rusty_iterators/file_iterator.hpp +++ b/include/rusty_iterators/file_iterator.hpp @@ -21,8 +21,6 @@ template class FileIterator : public IterInterface> {}; -// TODO: Perf. -// With the buffered iterator a lot of iterator functions could be optimized. template <> class FileIterator : public IterInterface> @@ -31,38 +29,34 @@ class FileIterator explicit FileIterator(const std::string& filePath) { std::ifstream is{filePath}; - if (!is.is_open()) { throw std::runtime_error{"Could not open the file."}; } - std::string nextLine; - while (std::getline(is, nextLine)) { fileLines.push_back(std::move(nextLine)); } is.close(); - ptr = fileLines.begin(); }; auto next() -> std::optional { - [[unlikely]] if (ptr == fileLines.end()) + [[unlikely]] if (ptr == fileLines.size()) { return std::nullopt; } - auto line = *ptr; + auto line = fileLines.at(ptr); ptr += 1; return std::move(line); } - [[nodiscard]] auto sizeHint() const -> std::optional { return fileLines.end() - ptr; } + [[nodiscard]] auto sizeHint() const -> std::optional { return fileLines.size() - ptr; } private: std::vector fileLines{}; - std::vector::iterator ptr; + size_t ptr = 0; }; template <> @@ -81,7 +75,6 @@ class FileIterator auto next() -> std::optional { std::string nextLine; - [[unlikely]] if (!std::getline(is, nextLine)) { return std::nullopt; diff --git a/tests/file_iterator.test.cpp b/tests/file_iterator.test.cpp index adb2dc4..199ab50 100644 --- a/tests/file_iterator.test.cpp +++ b/tests/file_iterator.test.cpp @@ -69,3 +69,24 @@ TEST(TestBufferedFileIterator, TestSizeHint) ASSERT_EQ(it.sizeHint(), 4); } + +TEST(TestBufferedFileIterator, TestSizeHintAfterConsumption) +{ + auto testFileName = std::string{"./tests/test_data.txt"}; + auto it = FileIterator{testFileName}.advanceBy(2); + + ASSERT_EQ(it.sizeHint(), 2); +} + +TEST(TestBufferedFileIterator, TestCopyBufferedIterator) +{ + auto testFileName = std::string{"./tests/test_data.txt"}; + auto it = FileIterator{testFileName}; + + it.next(); + auto cp = it; + it.next(); + + EXPECT_THAT(it.collect(), ElementsAreArray({"3", "4"})); + EXPECT_THAT(cp.collect(), ElementsAreArray({"2", "3", "4"})); +} diff --git a/tests/iterator.test.cpp b/tests/iterator.test.cpp index 022259a..f669ad2 100644 --- a/tests/iterator.test.cpp +++ b/tests/iterator.test.cpp @@ -22,13 +22,15 @@ TEST(TestIterator, TestCopySavesIteratorState) auto vec = std::vector{1, 2, 3, 4}; auto it = LazyIterator{vec}; + it.next(); auto cp = it; + it.next(); auto x = it.collect(); auto y = cp.collect(); - EXPECT_THAT(x, ElementsAreArray(std::array{2, 3, 4})); + EXPECT_THAT(x, ElementsAreArray(std::array{3, 4})); EXPECT_THAT(y, ElementsAreArray(std::array{2, 3, 4})); }