diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-07-20 17:02:05 +0200 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-07-20 17:02:05 +0200 |
commit | fac9e8bec1983fa9dff8f447fef106e427dfec26 (patch) | |
tree | 2221d4216873fa8250dd5ff45f00d0d6b46eab26 /c++/core/templates.h | |
parent | 398164432abcf599eaa51ebc4088024b7f46b97f (diff) |
c++: Renamed src to c++
Diffstat (limited to 'c++/core/templates.h')
-rw-r--r-- | c++/core/templates.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/c++/core/templates.h b/c++/core/templates.h new file mode 100644 index 0000000..39befc1 --- /dev/null +++ b/c++/core/templates.h @@ -0,0 +1,76 @@ +#pragma once + +#include "string_literal.h" + +namespace saw { + +template <class T, class... TL> struct parameter_pack_index; + +template <class T, class... TL> struct parameter_pack_index<T, T, TL...> { + static constexpr size_t value = 0u; +}; + +template <class T, class TL0, class... TL> +struct parameter_pack_index<T, TL0, TL...> { + static constexpr size_t value = + 1u + parameter_pack_index<T, TL...>::value; +}; + +template <size_t N, class... T> struct parameter_pack_type { + static_assert(always_false<T...>, "Should've been caught by the specializations"); +}; + +template <class TN, class... T> struct parameter_pack_type<0, TN, T...> { + using type = TN; +}; + +template <size_t N, class TN, class... T> +struct parameter_pack_type<N, TN, T...> { + static_assert(sizeof...(T) > 0, "Exhausted parameters"); + static_assert(N > 0, "Invalid number. Should've been caught"); + using type = typename parameter_pack_type<N - 1, T...>::type; +}; +/* + * Nightmare inducing compiler problems found here. Somehow non-type + * string_literals cannot be resolved as non-type primitive template values can. + * This is the workaround + */ +template <string_literal V, string_literal Key0, string_literal... Keys> +struct parameter_key_pack_index_helper { + static constexpr size_t value = + (V == Key0) + ? (0u) + : (1u + parameter_key_pack_index_helper<V, Keys...>::value); +}; + +template <string_literal V, string_literal Key0> +struct parameter_key_pack_index_helper<V, Key0> { + static constexpr size_t value = (V == Key0) ? (0u) : (1u); +}; + +template <string_literal V, string_literal... Keys> +struct parameter_key_pack_index { + static constexpr size_t value = + parameter_key_pack_index_helper<V, Keys...>::value; + static_assert(value < sizeof...(Keys), + "Provided string_literal doesn't exist in searched list"); +}; + +template <size_t i, size_t s, string_literal Key0, string_literal... Keys> +struct parameter_key_pack_type_helper { + static constexpr string_literal literal = parameter_key_pack_type_helper<i, s+1, Keys...>::literal; +}; + +template <size_t i, string_literal Key0, string_literal... Keys> +struct parameter_key_pack_type_helper<i, i, Key0, Keys...> { + static constexpr string_literal literal = Key0; +}; + +template <size_t i, string_literal... Keys> +struct parameter_key_pack_type { + static constexpr string_literal literal = parameter_key_pack_type_helper<i, 0, Keys...>::literal; + + static_assert(i < sizeof...(Keys), "Provided index is too large in list"); +}; + +} |