diff --git a/include/seqan3/utility/views/chunk.hpp b/include/seqan3/utility/views/chunk.hpp index 1f86d27e79..91628eb786 100644 --- a/include/seqan3/utility/views/chunk.hpp +++ b/include/seqan3/utility/views/chunk.hpp @@ -45,7 +45,7 @@ class chunk_view : public std::ranges::view_interface> urng_t urange; //!\brief The chunk size to use. - uint16_t chunk_size; + std::ranges::range_difference_t chunk_size; // The iterator type if `urng_t` is a pure input range. See class definition for details. template @@ -69,11 +69,11 @@ class chunk_view : public std::ranges::view_interface> ~chunk_view() = default; //!< Defaulted. /*!\brief Construct from a view and the chunk size. - * \param[in] underlying_range The underlying range to divide into chunks. + * \param[in] urng The underlying range to divide into chunks. * \param[in] size_of_chunk The size of the chunks, e.g., the length of the subrange returned at each position. */ - constexpr explicit chunk_view(urng_t underlying_range, uint16_t const size_of_chunk) : - urange{std::move(underlying_range)}, + constexpr explicit chunk_view(urng_t urng, std::ranges::range_difference_t const size_of_chunk) : + urange{std::move(urng)}, chunk_size{size_of_chunk} {} //!\} @@ -161,7 +161,7 @@ class chunk_view : public std::ranges::view_interface> //!\brief A deduction guide for the view class template. template -chunk_view(rng_t &&, uint16_t const &) -> chunk_view>; +chunk_view(rng_t &&, std::ranges::range_difference_t const &) -> chunk_view>; // --------------------------------------------------------------------------------------------------------------------- // chunk_view iterators (basic_input_iterator and basic_iterator) @@ -319,7 +319,9 @@ class chunk_view::basic_input_iterator : * * Constant. */ - constexpr explicit basic_input_iterator(urng_it_t it_begin, sentinel_t it_end, uint16_t const size_of_chunk) : + constexpr explicit basic_input_iterator(urng_it_t it_begin, + sentinel_t it_end, + std::ranges::range_difference_t const size_of_chunk) : chunk_size{size_of_chunk}, remaining{size_of_chunk}, urng_begin{std::move(it_begin)}, @@ -374,10 +376,10 @@ class chunk_view::basic_input_iterator : private: //!\brief The chunk size, e.g., the length of the subrange returned by this iterator. - uint16_t chunk_size; + std::ranges::range_difference_t chunk_size; //!\brief The remaining elements in the chunk. - uint16_t remaining; + std::ranges::range_difference_t remaining; //!\brief Points to the start of the underlying range. urng_it_t urng_begin; @@ -469,7 +471,9 @@ class chunk_view::basic_iterator : public maybe_iterator_category const size_of_chunk) : chunk_size{size_of_chunk}, urng_begin{std::move(it_start)}, urng_end{std::move(it_end)} @@ -675,7 +679,7 @@ class chunk_view::basic_iterator : public maybe_iterator_category chunk_size; //!\brief Points to the start of the underlying range. it_t urng_begin; @@ -709,8 +713,12 @@ class chunk_view::basic_iterator : public maybe_iterator_category increments{}; + increments != chunk_size && start_of_chunk != urng_end; + ++increments) + { ++start_of_chunk; + } return start_of_chunk; } @@ -739,8 +747,12 @@ class chunk_view::basic_iterator : public maybe_iterator_category decrements{}; + decrements != chunk_size && end_of_chunk != urng_begin; + ++decrements) + { --end_of_chunk; + } return end_of_chunk; } @@ -756,7 +768,7 @@ class chunk_view::basic_iterator : public maybe_iterator_category - constexpr auto operator()(underlying_range_t && urange, uint16_t const chunk_size) const + template + constexpr auto operator()(urng_t && urange, std::ranges::range_difference_t const chunk_size) const { - static_assert(std::ranges::input_range, + static_assert(std::ranges::input_range, "The range parameter to views::chunk must model std::ranges::input_range."); - return chunk_view{std::forward(urange), chunk_size}; + return chunk_view{std::forward(urange), chunk_size}; } }; diff --git a/test/unit/utility/views/chunk_test.cpp b/test/unit/utility/views/chunk_test.cpp index e111ed8886..9b8c12baa7 100644 --- a/test/unit/utility/views/chunk_test.cpp +++ b/test/unit/utility/views/chunk_test.cpp @@ -184,3 +184,11 @@ TYPED_TEST(chunk_view_test, use_on_temporaries) EXPECT_EQ(i, 4u); } } + +TYPED_TEST(chunk_view_test, big_chunk) +{ + // Check that a very big number (1ULL<<42) can be stored as chunk_size inside the chunk_view. + // error: conversion from ‘long long unsigned int’ to ‘uint16_t’ {aka ‘short unsigned int’} changes value + // from ‘4398046511104’ to ‘0’ [-Werror=overflow] + [[maybe_unused]] auto v = this->text | seqan3::views::chunk(1ULL << 42); +}