/* * libfud * Copyright 2024 Dominick Allen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FUD_ALGORITHM_HPP #define FUD_ALGORITHM_HPP #include "fud_span.hpp" #include #include #include #include namespace fud { template class Iota { public: constexpr Iota() noexcept : m_value{}, m_increment{static_cast(1)}, m_limit{std::numeric_limits::max()} { } constexpr Iota(T value) noexcept : m_value{value}, m_increment{static_cast(1)}, m_limit{std::numeric_limits::max()} { } constexpr Iota(T value, T increment) noexcept : m_value{value}, m_increment{increment}, m_limit{std::numeric_limits::max()} { } constexpr Iota(T value, T increment, T limit) noexcept : m_value{value}, m_increment{increment}, m_limit{limit} { } constexpr std::optional operator()() noexcept { auto value = m_value; if (m_increment > 0) { if (m_limit - m_increment < m_value) { return std::nullopt; } } else { if (m_limit + m_increment + 1 >= m_value) { return std::nullopt; } } m_value += m_increment; return value; } void set(T value) { m_value = value; } private: T m_value; const T m_increment; const T m_limit; }; template Span forEach(Span input, Func&& mapFunc) { for (auto& element : input) { element = std::forward(mapFunc)(element); } return input; } template Span mapTo(Span input, Span output, Func&& mapFunc) { for (auto idx = 0; idx < input.size(); ++idx) { output[idx] = std::forward(mapFunc)(input[idx]); } return input; } template auto map(Span input, Func&& mapFunc, Builder&& builder) -> decltype(std::forward(builder)()) { Output output{std::forward(builder)()}; for (auto idx = 0; idx < input.size() && idx < output.size(); ++idx) { output[idx] = std::forward(mapFunc)(input[idx]); } return input; } template auto generate(Builder&& builder, Generator&& generator) -> decltype(std::forward(builder)()) { using Output = decltype(std::forward(builder)()); Output output{std::forward(builder)()}; for (auto idx = 0; idx < output.size(); ++idx) { output[idx] = std::forward(generator)(); } return output; } template bool allOf(Span input, Func&& predicate) { bool result = input.size() > 0; for (size_t idx = 0; result && idx < input.size(); ++idx) { result = result && std::forward(predicate)(input[idx]); } return result; } template bool allOf(Generator&& generator, Func&& predicate) { bool result = true; while (auto val = std::forward(generator)()) { result = result && std::forward(predicate)(*val); } return result; } template bool anyOf(Span input, Func&& predicate) { bool result = !(input.size() > 0); for (size_t idx = 0; result && idx < input.size(); ++idx) { result = result || std::forward(predicate)(input[idx]); } return result; } template bool anyOf(Generator&& generator, Func&& predicate) { bool result = false; while (auto val = std::forward(generator)()) { result = result || std::forward(predicate)(*val); } return result; } } // namespace fud #endif