#pragma once #include "string_literal.h" namespace saw { template struct parameter_pack_index; template struct parameter_pack_index { static constexpr size_t value = 0u; }; template struct parameter_pack_index { static constexpr size_t value = 1u + parameter_pack_index::value; }; template struct parameter_pack_type { static_assert(always_false, "Should've been caught by the specializations"); }; template struct parameter_pack_type<0, TN, T...> { using type = TN; }; template struct parameter_pack_type { static_assert(sizeof...(T) > 0, "Exhausted parameters"); static_assert(N > 0, "Invalid number. Should've been caught"); using type = typename parameter_pack_type::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 struct parameter_key_pack_index_helper { static constexpr size_t value = (V == Key0) ? (0u) : (1u + parameter_key_pack_index_helper::value); }; template struct parameter_key_pack_index_helper { static constexpr size_t value = (V == Key0) ? (0u) : (1u); }; template struct parameter_key_pack_index { static constexpr size_t value = parameter_key_pack_index_helper::value; static_assert(value < sizeof...(Keys), "Provided string_literal doesn't exist in searched list"); }; template struct parameter_key_pack_type_helper { static constexpr string_literal literal = parameter_key_pack_type_helper::literal; }; template struct parameter_key_pack_type_helper { static constexpr string_literal literal = Key0; }; template struct parameter_key_pack_type { static constexpr string_literal literal = parameter_key_pack_type_helper::literal; static_assert(i < sizeof...(Keys), "Provided index is too large in list"); }; }