summaryrefslogtreecommitdiffhomepage
path: root/compat/map.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'compat/map.hpp')
-rw-r--r--compat/map.hpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/compat/map.hpp b/compat/map.hpp
new file mode 100644
index 00000000..def97d0e
--- /dev/null
+++ b/compat/map.hpp
@@ -0,0 +1,40 @@
+#pragma once
+#include "compat/integer-types.hpp"
+#include <type_traits>
+#include <array>
+#include <concepts>
+#include <Corrade/Utility/Macros.h>
+
+namespace floormat::detail::map {
+
+template<typename T, typename F, size_t N, size_t... Indexes>
+CORRADE_ALWAYS_INLINE
+constexpr auto map0(const std::array<T, N>& array, const F& fun, std::index_sequence<Indexes...>)
+{
+ return std::array { fun(array[Indexes])... };
+}
+
+template<typename T, typename F>
+[[deprecated("zero-length array!")]]
+CORRADE_ALWAYS_INLINE
+constexpr auto map0(const std::array<T, 0>&, const F& fun, std::index_sequence<>)
+{
+ return std::array<std::decay_t<decltype( fun(std::declval<const T&>()) )> , 0>{};
+}
+
+} // namespace floormat::detail::map
+
+namespace floormat {
+
+template<typename T, std::invocable<const T&> F, size_t N>
+constexpr auto map(const std::array<T, N>& array, const F& fun)
+{
+ using return_type = std::decay_t<decltype( fun(array[0]) )>;
+ static_assert(!std::is_same_v<return_type, void>);
+ static_assert(std::is_same_v<T, std::decay_t<T>>);
+ static_assert(sizeof(return_type) > 0);
+ using ::floormat::detail::map::map0;
+ return map0(array, fun, std::make_index_sequence<N>{});
+}
+
+} // namespace floormat