diff options
Diffstat (limited to 'libdevcore/CommonData.h')
-rw-r--r-- | libdevcore/CommonData.h | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index 1d668f26..98331936 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -263,6 +263,59 @@ void iterateReplacing(std::vector<T>& _vector, const F& _f) _vector = std::move(modifiedVector); } + +namespace detail +{ +template <typename T, typename F, std::size_t... I> +void iterateReplacingWindow(std::vector<T>& _vector, F const& _f, std::index_sequence<I...>) +{ + // Concept: _f must be Callable, must accept sizeof...(I) parameters of type T&, must return optional<vector<T>> + bool useModified = false; + std::vector<T> modifiedVector; + size_t i = 0; + for (; i + sizeof...(I) <= _vector.size(); ++i) + { + if (boost::optional<std::vector<T>> r = _f(_vector[i + I]...)) + { + if (!useModified) + { + std::move(_vector.begin(), _vector.begin() + i, back_inserter(modifiedVector)); + useModified = true; + } + modifiedVector += std::move(*r); + i += sizeof...(I) - 1; + } + else if (useModified) + modifiedVector.emplace_back(std::move(_vector[i])); + } + if (useModified) + { + for (; i < _vector.size(); ++i) + modifiedVector.emplace_back(std::move(_vector[i])); + _vector = std::move(modifiedVector); + } +} + +} + +/// Function that iterates over the vector @param _vector, +/// calling the function @param _f on sequences of @tparam N of its +/// elements. If @param _f returns a vector, these elements are replaced by +/// the returned vector and the iteration continues with the next @tparam N elements. +/// If the function does not return a vector, the iteration continues with an overlapping +/// sequence of @tparam N elements that starts with the second element of the previous +/// iteration. +/// During the iteration, the original vector is only valid +/// on the current element and after that. The actual replacement takes +/// place at the end, but already visited elements might be invalidated. +/// If nothing is replaced, no copy is performed. +template <std::size_t N, typename T, typename F> +void iterateReplacingWindow(std::vector<T>& _vector, F const& _f) +{ + // Concept: _f must be Callable, must accept N parameters of type T&, must return optional<vector<T>> + detail::iterateReplacingWindow(_vector, _f, std::make_index_sequence<N>{}); +} + /// @returns true iff @a _str passess the hex address checksum test. /// @param _strict if false, hex strings with only uppercase or only lowercase letters /// are considered valid. |