-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #151 from MarcDirven/dev
Inclusive scan
- Loading branch information
Showing
11 changed files
with
372 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ set(examples | |
FunctionTools | ||
Generate | ||
GroupBy | ||
InclusiveScan | ||
Join | ||
JoinWhere | ||
Map | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#include <Lz/InclusiveScan.hpp> | ||
|
||
#include <iostream> | ||
|
||
int main() { | ||
int array[] = {3, 5, 2, 3, 4, 2, 3}; | ||
// start the scan from arr[0] (3) | ||
auto scan = lz::iScan(array); | ||
|
||
for (const int& i : scan) { | ||
fmt::print("{} ", i); | ||
} | ||
// prints 3 8 10 13 17 19 22 | ||
|
||
// essentially it's: | ||
// 3 (3) | ||
// 3 + 5 (8) | ||
// 8 + 2 (10) | ||
// 10 + 3 (13) | ||
// 13 + 4 (17) | ||
// 17 + 2 (19) | ||
// 19 + 3 (22) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
#pragma once | ||
|
||
#ifndef LZ_INCLUSIVE_SCAN_HPP | ||
# define LZ_INCLUSIVE_SCAN_HPP | ||
|
||
# include "detail/BasicIteratorView.hpp" | ||
# include "detail/InclusiveScanIterator.hpp" | ||
|
||
namespace lz { | ||
LZ_MODULE_EXPORT_SCOPE_BEGIN | ||
|
||
template<class Iterator, class T, class BinaryOp> | ||
class InclusiveScan final : public internal::BasicIteratorView<internal::InclusiveScanIterator<Iterator, T, BinaryOp>> { | ||
public: | ||
using iterator = internal::InclusiveScanIterator<Iterator, T, BinaryOp>; | ||
using const_iterator = iterator; | ||
|
||
constexpr InclusiveScan() = default; | ||
|
||
LZ_CONSTEXPR_CXX_14 InclusiveScan(Iterator first, Iterator last, T init, BinaryOp binaryOp) : | ||
internal::BasicIteratorView<iterator>(iterator(std::move(first), init, binaryOp), | ||
iterator(std::move(last), init, binaryOp)) { | ||
} | ||
}; | ||
|
||
/** | ||
* @addtogroup ItFns | ||
* @{ | ||
*/ | ||
|
||
/** | ||
* @brief Returns an inclusive scan iterator. | ||
* @details Returns an inclusive scan iterator. This iterator begins by returning `binOp(std::move(init), *first)`. It then | ||
* proceeds to the next one, which is essentially the previously calculated value + the current iterator element being handled. | ||
* Example: | ||
* @example | ||
* ```cpp | ||
* int array[] = {3, 5, 2, 3, 4, 2, 3}; | ||
* // start the scan from 3 + init (1) = 4 | ||
* auto scan = lz::iScanFrom(std::begin(array), std::end(array), 1); | ||
* | ||
* for (const int& i : scan) { | ||
* fmt::print("{} ", i); | ||
* } | ||
* // prints 4 9 11 14 18 20 23 | ||
* ``` | ||
* | ||
* @param first The iterator denoting the beginning | ||
* @param last The iterator denoting the end | ||
* @param init The value to start with | ||
* @param binOp The fold function. Essentially, it is executed as (`init = binOp(std::move(init), *iterator);`) | ||
* @return An inclusive scan view object. | ||
*/ | ||
template<LZ_CONCEPT_ITERATOR Iterator, class T, class BinaryOp = MAKE_BIN_OP(std::plus, internal::Decay<T>)> | ||
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 InclusiveScan<Iterator, internal::Decay<T>, internal::Decay<BinaryOp>> | ||
iScanFrom(Iterator first, Iterator last, T&& init, BinaryOp&& binOp = {}) { | ||
auto tmp = binOp(std::forward<T>(init), *first); | ||
return { std::move(first), std::move(last), std::move(tmp), std::forward<BinaryOp>(binOp) }; | ||
} | ||
|
||
/** | ||
* @brief Returns an inclusive scan iterator. | ||
* @details Returns an inclusive scan iterator. This iterator begins by returning `binOp(std::move(init), *first)`. It then | ||
* proceeds to the next one, which is essentially the previously calculated value + the current iterator element being handled. | ||
* Example: | ||
* @example | ||
* ```cpp | ||
* int array[] = {3, 5, 2, 3, 4, 2, 3}; | ||
* // start the scan from 3 + init (1) = 4 | ||
* auto scan = lz::iScanFrom(array, 1); | ||
* | ||
* for (const int& i : scan) { | ||
* fmt::print("{} ", i); | ||
* } | ||
* // prints 4 9 11 14 18 20 23 | ||
* ``` | ||
* | ||
* @param iterable The iterable to perform the inclusive scan over | ||
* @param init The value to start with | ||
* @param binOp The fold function. Essentially, it is executed as (`init = binOp(std::move(init), *iterator);`) | ||
* @return An inclusive scan view object. | ||
*/ | ||
// clang-format off | ||
template<LZ_CONCEPT_ITERABLE Iterable, class T, class BinaryOp = MAKE_BIN_OP(std::plus, internal::Decay<T>)> | ||
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 | ||
InclusiveScan<internal::IterTypeFromIterable<Iterable>, internal::Decay<T>, internal::Decay<BinaryOp>> | ||
iScanFrom(Iterable&& iterable, T&& init, BinaryOp&& binOp = {}) { | ||
return iScanFrom(internal::begin(std::forward<Iterable>(iterable)), internal::end(std::forward<Iterable>(iterable)), | ||
std::forward<T>(init), std::forward<BinaryOp>(binOp)); | ||
} | ||
// clang-format on | ||
|
||
/** | ||
* @brief Returns an inclusive scan iterator. | ||
* @details Returns an inclusive scan iterator. This iterator begins by returning `*first`. It then | ||
* proceeds to the next one, which is essentially the previously calculated value (calculated by `binOp(std::move(current), *it)` | ||
* + the current iterator element being handled. Example: | ||
* @example | ||
* ```cpp | ||
* int array[] = {3, 5, 2, 3, 4, 2, 3}; | ||
* // start the scan from 3 | ||
* auto scan = lz::iScan(array); | ||
* | ||
* for (const int& i : scan) { | ||
* fmt::print("{} ", i); | ||
* } | ||
* // prints 3 8 10 13 17 19 22 | ||
* ``` | ||
* | ||
* @param first The iterator denoting the beginning | ||
* @param last The iterator denoting the end | ||
* @param init The value to start with | ||
* @param binOp The fold function. Essentially, it is executed as (`init = binOp(std::move(init), *iterator);`) | ||
* @return An inclusive scan view object. | ||
*/ | ||
template<LZ_CONCEPT_ITERATOR Iterator, class BinaryOp = MAKE_BIN_OP(std::plus, internal::ValueType<Iterator>)> | ||
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 InclusiveScan<Iterator, internal::ValueType<Iterator>, internal::Decay<BinaryOp>> | ||
iScan(Iterator first, Iterator last, BinaryOp&& binOp = {}) { | ||
auto tmp = *first; | ||
return { std::move(first), std::move(last), std::move(tmp), std::forward<BinaryOp>(binOp) }; | ||
} | ||
|
||
/** | ||
* @brief Returns an inclusive scan iterator. | ||
* @details Returns an inclusive scan iterator. This iterator begins by returning `*std::begin(iterable)`. It then | ||
* proceeds to the next one, which is essentially the previously calculated value (calculated by `binOp(std::move(current), *it)` | ||
* + the current iterator element being handled. Example: | ||
* @example | ||
* ```cpp | ||
* int array[] = {3, 5, 2, 3, 4, 2, 3}; | ||
* // start the scan from 3 | ||
* auto scan = lz::iScan(array); | ||
* | ||
* for (const int& i : scan) { | ||
* fmt::print("{} ", i); | ||
* } | ||
* // prints 3 8 10 13 17 19 22 | ||
* ``` | ||
* | ||
* @param iterable The iterable to perform the inclusive scan over | ||
* @param init The value to start with | ||
* @param binOp The fold function. Essentially, it is executed as (`init = binOp(std::move(init), *iterator);`) | ||
* @return An inclusive scan view object. | ||
*/ | ||
// clang-format off | ||
template<LZ_CONCEPT_ITERABLE Iterable, class BinaryOp = MAKE_BIN_OP(std::plus, internal::ValueTypeIterable<Iterable>)> | ||
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 | ||
InclusiveScan<internal::IterTypeFromIterable<Iterable>, internal::ValueTypeIterable<Iterable>, internal::Decay<BinaryOp>> | ||
iScan(Iterable&& iterable, BinaryOp&& binOp = {}) { | ||
return iScan(internal::begin(std::forward<Iterable>(iterable)), internal::end(std::forward<Iterable>(iterable)), std::forward<BinaryOp>(binOp)); | ||
} | ||
// clang-format on | ||
|
||
// End of group | ||
/** | ||
* @} | ||
*/ | ||
|
||
LZ_MODULE_EXPORT_SCOPE_END | ||
} // namespace lz | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#pragma once | ||
|
||
#ifndef LZ_INCLUSIVE_SCAN_ITERATOR_HPP | ||
# define LZ_INCLUSIVE_SCAN_ITERATOR_HPP | ||
|
||
# include "FunctionContainer.hpp" | ||
|
||
namespace lz { | ||
namespace internal { | ||
template<class Iterator, class T, class BinaryOp> | ||
class InclusiveScanIterator { | ||
T _reducer{}; | ||
FunctionContainer<BinaryOp> _binaryOp{}; | ||
Iterator _iterator{}; | ||
|
||
using IterTraits = std::iterator_traits<Iterator>; | ||
|
||
public: | ||
using reference = T&; | ||
using value_type = Decay<reference>; | ||
using pointer = FakePointerProxy<reference>; | ||
using difference_type = typename IterTraits::difference_type; | ||
using iterator_category = std::forward_iterator_tag; | ||
|
||
constexpr InclusiveScanIterator() = default; | ||
|
||
LZ_CONSTEXPR_CXX_14 InclusiveScanIterator(Iterator iterator, T init, BinaryOp binaryOp) : | ||
_reducer(std::move(init)), | ||
_binaryOp(std::move(binaryOp)), | ||
_iterator(std::move(iterator)) { | ||
} | ||
|
||
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 typename std::remove_reference<reference>::type const& operator*() const { | ||
return _reducer; | ||
} | ||
|
||
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 reference operator*() { | ||
return _reducer; | ||
} | ||
|
||
LZ_CONSTEXPR_CXX_20 InclusiveScanIterator& operator++() { | ||
++_iterator; | ||
_reducer = _binaryOp(std::move(_reducer), *_iterator); | ||
return *this; | ||
} | ||
|
||
LZ_CONSTEXPR_CXX_20 InclusiveScanIterator operator++(int) { | ||
InclusiveScanIterator tmp(*this); | ||
++*this; | ||
return tmp; | ||
} | ||
|
||
LZ_NODISCARD constexpr friend bool operator!=(const InclusiveScanIterator& a, const InclusiveScanIterator& b) { | ||
return a._iterator != b._iterator; | ||
} | ||
|
||
LZ_NODISCARD constexpr friend bool operator==(const InclusiveScanIterator& a, const InclusiveScanIterator& b) { | ||
return !(a != b); // NOLINT | ||
} | ||
}; | ||
} // namespace internal | ||
} // namespace lz | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.