summaryrefslogtreecommitdiff
path: root/modules/core/c++
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/c++')
-rw-r--r--modules/core/c++/reduce_templates.hpp41
-rw-r--r--modules/core/c++/templates.hpp14
2 files changed, 55 insertions, 0 deletions
diff --git a/modules/core/c++/reduce_templates.hpp b/modules/core/c++/reduce_templates.hpp
new file mode 100644
index 0000000..ef5fa4c
--- /dev/null
+++ b/modules/core/c++/reduce_templates.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "templates.hpp"
+
+namespace saw {
+
+namespace impl {
+template<typename C, typename T>
+struct tmpl_group_reduce_match {
+ static constexpr bool has_type = false;
+ using type = saw::tmpl_group<C>;
+};
+
+template<typename T0, typename TL0, typename... TL>
+struct tmpl_group_reduce_match<T0, tmpl_group<TL0,TL...>> {
+ static constexpr bool has_type = std::is_same_v<T0,TL0> or tmpl_group_reduce_match<T0, tmpl_group<TL...>>::has_type;
+
+ using type = typename std::conditional<has_type, tmpl_group<TL0,TL...>, tmpl_group<T0, TL0, TL...>>::type;
+};
+
+template<typename T>
+struct tmpl_group_reduce {
+ using reduced_type = T;
+};
+
+/**
+ * Reducing in outer loop
+ */
+template<typename... TL, typename T0>
+struct tmpl_group_reduce<tmpl_group<T0,TL...>> {
+ using reduced_inner_list = typename tmpl_group_reduce<tmpl_group<TL...>>::reduced_type;
+
+ using reduced_type = typename tmpl_group_reduce_match<T0,reduced_inner_list>::type;
+};
+}
+
+template<typename T>
+struct tmpl_reduce {
+ using type = typename impl::tmpl_group_reduce<T>::reduced_type;
+};
+}
diff --git a/modules/core/c++/templates.hpp b/modules/core/c++/templates.hpp
index acbaeb0..70836ae 100644
--- a/modules/core/c++/templates.hpp
+++ b/modules/core/c++/templates.hpp
@@ -5,6 +5,20 @@
namespace saw {
+/**
+ * This type is meant for grouping of template types
+ */
+template <class... T>
+struct tmpl_group {};
+
+template<typename T, typename U>
+struct tmpl_concat;
+
+template<typename... T, typename... U>
+struct tmpl_concat<tmpl_group<T...>, tmpl_group<U...>> {
+ using type = tmpl_group<T..., U...>;
+};
+
template <class T, class... TL> struct parameter_pack_index;
template <class T, class... TL> struct parameter_pack_index<T, T, TL...> {