Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ cmake_policy(VERSION ${CMAKE_VERSION})

# ############
# Define Project
project(itertools VERSION 1.3.0 LANGUAGES CXX)
project(itertools VERSION 2.0.0 LANGUAGES CXX)
get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)

# Get the git hash & print status
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ int main(){

for (auto [i, j] : product_range(5, 5)) {
/* (0, 0), (0, 1), .. (0, 4),
(1, 0), (1, 2), .. (1, 4),
(1, 0), (1, 1), .. (1, 4),
...
(4, 0), (4, 2), .. (4, 4) */
(4, 0), (4, 1), .. (4, 4) */
}

// ===== Adapting ranges =====
Expand Down
24 changes: 9 additions & 15 deletions c++/itertools/enumerate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ namespace itertools {
* @ingroup range_iterators
* @brief Iterator for an itertools::enumerated range.
*
* @details It stores an iterator of the original range and an index. Incrementing advances the iterator
* and the index by 1. Dereferencing returns a std::pair consisting of the current index and the current
* dereferenced value of the original iterator.
* @details It stores an iterator of the original range and an index. Incrementing advances the iterator and the index
* by 1. Dereferencing returns a `std::pair` consisting of the current index and the current dereferenced value of the
* original iterator.
*
* See itertools::enumerate(R &&) for more details.
*
Expand Down Expand Up @@ -74,7 +74,7 @@ namespace itertools {
[[nodiscard]] bool operator==(enum_iter const &other) const { return it == other.it; }

/**
* @brief Equal-to operator for a itertools::enum_iter and an itertools::sentinel_t.
* @brief Equal-to operator for an itertools::enum_iter and an itertools::sentinel_t.
*
* @tparam SentinelIter Iterator type of the sentinel.
* @param s itertools::sentinel_t to compare with.
Expand Down Expand Up @@ -139,17 +139,11 @@ namespace itertools {
* @ingroup range_adapting_functions
* @brief Lazy-enumerate a given range (similar to Python's enumerate).
*
* @details Each element in the original range is assigned an index, starting from zero. This function
* returns an iterable lazy object (a itertools::enumerated range), which iterates over tuples consisting
* of the index and the value of the dereferenced iterator of the original range:
* @details Each element in the original range is assigned an index, starting from zero. This function returns an
* iterable lazy object (an itertools::enumerated range), which iterates over tuples consisting of the index and the
* value of the dereferenced iterator of the original range:
*
* @code{.cpp}
* std::vector<char> vec { 'a', 'b', 'c' };
*
* for (auto [idx, val] : enumerate(vec)) {
* std::cout << "(" << idx << ", " << val << ")\n";
* }
* @endcode
* @include doc_enumerate.cpp
*
* Output:
*
Expand All @@ -163,7 +157,7 @@ namespace itertools {
*
* @tparam R Range type.
* @param rg Range to enumerate.
* @return A itertools::enumerated range.
* @return An itertools::enumerated range.
*/
template <typename R> [[nodiscard]] enumerated<R> enumerate(R &&rg) { return {std::forward<R>(rg)}; }

Expand Down
5 changes: 3 additions & 2 deletions c++/itertools/omp_chunk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ namespace itertools {
* @ingroup utilities
* @brief Distribute a range as evenly as possible across all OMP threads.
*
* @details See chunk_range(std::ptrdiff_t, std::ptrdiff_t, long, long) and slice(R &&, std::ptrdiff_t, std::ptrdiff_t) for more details.
* @details See chunk_range(std::ptrdiff_t, std::ptrdiff_t, long, long) and slice(R &&, std::ptrdiff_t,
* std::ptrdiff_t) for more details.
*
* @tparam R Range type.
* @param rg Range to chunk.
* @return A itertools::sliced range, containing the chunk of the original range that belongs to the current thread.
* @return An itertools::sliced range, containing the chunk of the original range that belongs to the current thread.
*/
template <typename R> auto omp_chunk(R &&rg) {
auto total_size = itertools::distance(std::cbegin(rg), std::cend(rg));
Expand Down
41 changes: 19 additions & 22 deletions c++/itertools/product.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ namespace itertools {

/**
* @ingroup range_iterators
* @brief Iterator for a itertools::multiplied (cartesian product) range.
* @brief Iterator for an itertools::multiplied (cartesian product) range.
*
* @details It stores three tuples of iterators of the original ranges:
* - `its_begin` contains the begin iterators of all ranges
* - `its_end` contains the end iterators of all ranges
* - `its` contains the current iterators of all ranges
*
* Incrementing is done from right to left, i.e. the iterator of the last range is incremented first.
* Once an iterator reaches the end of its range, it is reset to the beginning and the iterator of the
* previous range is incremented once.
* Incrementing is done from right to left, i.e. the iterator of the last range is incremented first. Once an iterator
* reaches the end of its range, it is reset to the beginning and the iterator of the previous range is incremented
* once.
*
* Dereferencing returns a tuple containing the results of dereferencing each iterator.
*
Expand Down Expand Up @@ -106,7 +106,7 @@ namespace itertools {
[[nodiscard]] bool operator==(prod_iter const &other) const { return its == other.its; }

/**
* @brief Equal-to operator for a itertools::prod_iter and an itertools::sentinel_t.
* @brief Equal-to operator for an itertools::prod_iter and an itertools::sentinel_t.
*
* @details We reach the end of the product range, when the first iterator, i.e. `std::get<0>(its)`, is at its end.
*
Expand Down Expand Up @@ -145,7 +145,7 @@ namespace itertools {
/// Iterator type of the product range.
using iterator = prod_iter<std::tuple<decltype(std::end(std::declval<Rs &>()))...>, decltype(std::begin(std::declval<Rs &>()))...>;

/// Const iterator type the product range.
/// Const iterator type of the product range.
using const_iterator = prod_iter<std::tuple<decltype(std::cend(std::declval<Rs &>()))...>, decltype(std::cbegin(std::declval<Rs &>()))...>;

/**
Expand All @@ -160,7 +160,7 @@ namespace itertools {
[[nodiscard]] bool operator==(multiplied const &) const = default;

private:
// Helper function to create a itertools::prod_iter representing the beginning of the product range.
// Helper function to create an itertools::prod_iter representing the beginning of the product range.
template <size_t... Is> [[gnu::always_inline]] auto _begin(std::index_sequence<Is...>) {
return iterator{std::make_tuple(std::begin(std::get<Is>(tu))...), std::make_tuple(std::end(std::get<Is>(tu))...)};
}
Expand All @@ -185,7 +185,8 @@ namespace itertools {

/**
* @brief End of the product range.
* @return itertools::sentinel_t containing the end iterator of the first original range, i.e. `std::end(std::get<0>(tu))`.
* @return itertools::sentinel_t containing the end iterator of the first original range, i.e.
* `std::end(std::get<0>(tu))`.
*/
[[nodiscard]] auto end() noexcept { return make_sentinel(std::end(std::get<0>(tu))); }

Expand All @@ -201,7 +202,7 @@ namespace itertools {

/**
* @ingroup range_iterators
* @brief Iterator for a itertools::multiplied_vec (cartesian product of homogeneous ranges) range.
* @brief Iterator for an itertools::multiplied_vec (cartesian product of homogeneous ranges) range.
*
* @details Similar to itertools::prod_iter, but works with a vector of homogeneous ranges
* instead of a tuple of heterogeneous ranges. This allows for a runtime-determined number of ranges.
Expand Down Expand Up @@ -268,7 +269,7 @@ namespace itertools {
[[nodiscard]] bool operator==(prod_iter_vec const &other) const { return its == other.its && done == other.done; }

/**
* @brief Equal-to operator for a itertools::prod_iter_vec and an itertools::sentinel_t.
* @brief Equal-to operator for an itertools::prod_iter_vec and an itertools::sentinel_t.
*
* @details We reach the end of the product range, when the first iterator, i.e. `its[0]`, is at its end,
* or when done=true for empty products.
Expand Down Expand Up @@ -309,7 +310,7 @@ namespace itertools {
/// Iterator type of the product range.
using iterator = prod_iter_vec<decltype(std::begin(std::declval<R &>()))>;

/// Const iterator type the product range.
/// Const iterator type of the product range.
using const_iterator = prod_iter_vec<decltype(std::cbegin(std::declval<R &>()))>;

/**
Expand Down Expand Up @@ -382,19 +383,14 @@ namespace itertools {
/**
* @brief Lazy-multiply a given number of ranges by forming their cartesian product.
*
* @details An arbitrary number of ranges are multiplied together into a cartesian product range.
* They are traversed such that the last range is traversed the fastest (see the example below).
* @details An arbitrary number of ranges are multiplied together into a cartesian product range. They are traversed
* such that the last range is traversed the fastest (see the example below).
*
* The number of elements in a product range is equal to the product of the sizes of the given ranges.
*
* This function returns an iterable lazy object, which can be used in range-based for loops:
*
* @code{.cpp}
* std::vector<int> v1 { 1, 2, 3 };
* std::vector<char> v2 { 'a', 'b' };
*
* for (auto [i, c] : product(v1, v2)) {
* std::cout << "(" << i << ", " << c << ")\n";
* }
* @endcode
* @include doc_product.cpp
*
* Output:
*
Expand All @@ -407,7 +403,8 @@ namespace itertools {
* (3, b)
* ```
*
* See also <a href="https://en.cppreference.com/w/cpp/ranges/cartesian_product_view">std::ranges::views::cartesian_product</a>.
* See also <a href="https://en.cppreference.com/w/cpp/ranges/cartesian_product_view">
* std::ranges::views::cartesian_product</a>.
*
* @tparam Rs Range types.
* @param rgs Ranges to be used.
Expand Down
77 changes: 7 additions & 70 deletions c++/itertools/range.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,7 @@ namespace itertools {
*
* This function returns an iterable lazy object, which can be used in range-based for loops:
*
* @code{.cpp}
* for (auto i : range(5)) {
* std::cout << i << " ";
* }
* std::cout << "\n";
*
* for (auto i : range(-2, 1)) {
* std::cout << i << " ";
* }
* std::cout << "\n";
*
* for (auto i : range(10, 3, -2)) {
* std::cout << i << " ";
* }
* std::cout << "\n";
*
* for (auto i : range(0, 10, -1)) {
* std::cout << i << " "; // empty
* }
* @endcode
* @include doc_range.cpp
*
* Output:
*
Expand Down Expand Up @@ -106,7 +87,8 @@ namespace itertools {

/**
* @brief Default constructor.
* @deprecated Use range::range(long, long) or range::range(long, long, long) instead.
* @deprecated Use range::range(std::integral auto, std::integral auto) or range::range(std::integral auto,
* std::integral auto, std::integral auto) instead.
*/
[[deprecated("range default construction deprecated. Use range::all for full range in slicing operation")]] range() = default;

Expand Down Expand Up @@ -370,11 +352,7 @@ namespace itertools {
* @details The given integers specify the excluded last values of the individual itertools::range objects. Each range
* starts at 0 and has a step size of 1.
*
* @code{.cpp}
* for (auto [i1, i2] : product_range(2, 3)) {
* std::cout << "(" << i1 << ", " << i2 << ")\n";
* }
* @endcode
* @include doc_product_range.cpp
*
* Output:
*
Expand Down Expand Up @@ -407,25 +385,7 @@ namespace itertools {
/**
* @brief Create a cartesian product range of integer ranges from a tuple of integers.
*
* @details The integers in the given tuple specify the excluded last values of the individual itertools::range
* objects. Each range starts at 0 and has a step size of 1.
*
* @code{.cpp}
* for (auto [i1, i2] : product_range(std::make_tuple(2, 3))) {
* std::cout << "(" << i1 << ", " << i2 << ")\n";
* }
* @endcode
*
* Output:
*
* ```
* (0, 0)
* (0, 1)
* (0, 2)
* (1, 0)
* (1, 1)
* (1, 2)
* ```
* @details It simply forwards the integers in the given tuple to itertools::product_range.
*
* @tparam Is Integer types.
* @param idx_tpl Tuple containing the excluded last values of the integer ranges.
Expand All @@ -439,25 +399,7 @@ namespace itertools {
/**
* @brief Create a cartesian product range of integer ranges from an array of integers.
*
* @details The integers in the given array specify the excluded last values of the individual itertools::range
* objects. Each range starts at 0 and has a step size of 1.
*
* @code{.cpp}
* for (auto [i1, i2] : product_range(std::array{2, 3})) {
* std::cout << "(" << i1 << ", " << i2 << ")\n";
* }
* @endcode
*
* Output:
*
* ```
* (0, 0)
* (0, 1)
* (0, 2)
* (1, 0)
* (1, 1)
* (1, 2)
* ```
* @details It simply forwards the integers in the given array to itertools::product_range.
*
* @tparam I Integer type.
* @tparam N Number of elements in the array.
Expand All @@ -472,12 +414,7 @@ namespace itertools {
/**
* @brief Apply a function to every element of an integer itertools::range.
*
* @code{.cpp}
* // print out the first 10 squares
* itertools::foreach(itertools::range(1, 11), [](int i) {
* std::cout << i * i << " ";
* });
* @endcode
* @include doc_for_each.cpp
*
* Output:
*
Expand Down
30 changes: 8 additions & 22 deletions c++/itertools/slice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,30 +96,16 @@ namespace itertools {
* @ingroup range_adapting_functions
* @brief Lazy-slice a given range.
*
* @details Only the part of the given range between the `start_idx` and the `end_idx` is taken into account.
* If `end_idx` is bigger than the size of the original range, the slice ends at the end of the original range.
* If `end_idx` is smaller than `start_idx`, the slice is empty. Note that the behaviour is undefined if
* `start_idx` is smaller than zero.
* @details Only the part of the given range between the `start_idx` and the `end_idx` is taken into account:
*
* - If `end_idx` is bigger than the size of the original range, the slice ends at the end of the original range.
* - If `end_idx` is smaller than `start_idx`, the slice is empty.
*
* @note The behaviour is undefined if `start_idx` is smaller than zero.
*
* This function returns an iterable lazy object, which can be used in range-based for loops:
*
* @code{.cpp}
* std::array<int, 5> arr { 1, 2, 3, 4, 5 };
*
* for (auto i : slice(arr, 1, 3)) {
* std::cout << i << " ";
* }
* std::cout << "\n";
*
* for (auto i : slice(arr, 3, 7)) {
* std::cout << i << " ";
* }
* std::cout << "\n";
*
* for (auto i : slice(arr, 4, 3)) {
* std::cout << i << " "; // empty slice
* }
* @endcode
* @include doc_slice.cpp
*
* Output:
*
Expand All @@ -132,7 +118,7 @@ namespace itertools {
* @param rg Range to be sliced.
* @param start_idx Index where the slice starts.
* @param end_idx Index of the first element past the end of the sliced range (excluded).
* @return A itertools::sliced range.
* @return An itertools::sliced range.
*/
template <typename R> [[nodiscard]] sliced<R> slice(R &&rg, std::ptrdiff_t start_idx, std::ptrdiff_t end_idx) {
return {std::forward<R>(rg), start_idx, std::max(start_idx, end_idx)};
Expand Down
Loading
Loading