summaryrefslogtreecommitdiff
path: root/include/fud_algorithm.hpp
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2024-10-20 10:48:19 -0500
committerDominick Allen <djallen@librehumanitas.org>2024-10-20 10:48:19 -0500
commit6a27a2a4032e88fa9154ef0f0741edc584f7a701 (patch)
tree92ca58cbcdd2c1d11b7d69deb0d4925d0f979a3f /include/fud_algorithm.hpp
parente94db4695e236b42ae1be44b2605075161d5144f (diff)
Lots of work.
Diffstat (limited to 'include/fud_algorithm.hpp')
-rw-r--r--include/fud_algorithm.hpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/include/fud_algorithm.hpp b/include/fud_algorithm.hpp
new file mode 100644
index 0000000..e3d5d3b
--- /dev/null
+++ b/include/fud_algorithm.hpp
@@ -0,0 +1,162 @@
+/*
+ * 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 <concepts>
+#include <limits>
+#include <optional>
+#include <type_traits>
+
+namespace fud {
+
+template <std::integral T>
+class Iota {
+ public:
+ constexpr Iota() noexcept : m_value{}, m_increment{static_cast<T>(1)}, m_limit{std::numeric_limits<T>::max()}
+ {
+ }
+
+ constexpr Iota(T value) noexcept :
+ m_value{value}, m_increment{static_cast<T>(1)}, m_limit{std::numeric_limits<T>::max()}
+ {
+ }
+
+ constexpr Iota(T value, T increment) noexcept :
+ m_value{value}, m_increment{increment}, m_limit{std::numeric_limits<T>::max()}
+ {
+ }
+
+ constexpr Iota(T value, T increment, T limit) noexcept : m_value{value}, m_increment{increment}, m_limit{limit}
+ {
+ }
+
+ constexpr std::optional<T> 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 <typename T, size_t Size, typename Func>
+Span<T, Size> forEach(Span<T, Size> input, Func&& mapFunc)
+{
+ for (auto& element : input) {
+ element = std::forward<Func>(mapFunc)(element);
+ }
+
+ return input;
+}
+
+template <typename T, typename U, size_t Size, typename Func>
+Span<T, Size> mapTo(Span<T, Size> input, Span<U, Size> output, Func&& mapFunc)
+{
+ for (auto idx = 0; idx < input.size(); ++idx) {
+ output[idx] = std::forward<Func>(mapFunc)(input[idx]);
+ }
+
+ return input;
+}
+
+template <typename T, size_t Size, typename Func, typename Builder, typename Output>
+auto map(Span<T, Size> input, Func&& mapFunc, Builder&& builder) -> decltype(std::forward<Builder>(builder)())
+{
+ Output output{std::forward<Builder>(builder)()};
+ for (auto idx = 0; idx < input.size() && idx < output.size(); ++idx) {
+ output[idx] = std::forward<Func>(mapFunc)(input[idx]);
+ }
+
+ return input;
+}
+
+template <typename Generator, typename Builder>
+auto generate(Builder&& builder, Generator&& generator) -> decltype(std::forward<Builder>(builder)())
+{
+ using Output = decltype(std::forward<Builder>(builder)());
+ Output output{std::forward<Builder>(builder)()};
+ for (auto idx = 0; idx < output.size(); ++idx) {
+ output[idx] = std::forward<Generator>(generator)();
+ }
+
+ return output;
+}
+
+template <typename T, size_t Size, typename Func>
+bool allOf(Span<T, Size> input, Func&& predicate)
+{
+ bool result = input.size() > 0;
+ for (size_t idx = 0; result && idx < input.size(); ++idx) {
+ result = result && std::forward<Func>(predicate)(input[idx]);
+ }
+ return result;
+}
+
+template <typename Generator, typename Func>
+bool allOf(Generator&& generator, Func&& predicate)
+{
+ bool result = true;
+ while (auto val = std::forward<Generator>(generator)()) {
+ result = result && std::forward<Func>(predicate)(*val);
+ }
+ return result;
+}
+
+template <typename T, size_t Size, typename Func>
+bool anyOf(Span<T, Size> input, Func&& predicate)
+{
+ bool result = !(input.size() > 0);
+ for (size_t idx = 0; result && idx < input.size(); ++idx) {
+ result = result || std::forward<Func>(predicate)(input[idx]);
+ }
+ return result;
+}
+
+template <typename Generator, typename Func>
+bool anyOf(Generator&& generator, Func&& predicate)
+{
+ bool result = false;
+ while (auto val = std::forward<Generator>(generator)()) {
+ result = result || std::forward<Func>(predicate)(*val);
+ }
+ return result;
+}
+
+} // namespace fud
+
+#endif