Last active
June 10, 2022 20:35
-
-
Save stevemk14ebr/41e811fb59828b778e5d13ab0442f7cb to your computer and use it in GitHub Desktop.
C++ typedef args to typeid list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <typeinfo> | |
#include <typeindex> | |
#include <span> | |
typedef int (*tExample) (int a, bool b, char* c, long long d); | |
template<typename T> | |
struct arg_types {}; | |
template<typename R, typename... A> | |
struct arg_types<R(*)(A...)> { | |
inline static const std::type_index value[] = {typeid(A)...}; | |
}; | |
template<typename T> | |
static constexpr std::span<const std::type_index> arg_types_v = arg_types<T>::value; | |
int main() | |
{ | |
auto vec = arg_types_v<tExample>; | |
for (const auto& t : vec) | |
{ | |
std::cout << t.hash_code() << std::endl; | |
} | |
} | |
// ALTERNATIVE (free standing, no typeid). Also fixes bug with function types with 0 args by using std::array | |
using hash_t = std::uint64_t; | |
// FNV-1a 64 bit hash | |
consteval hash_t fnv1a_hash(std::size_t n, const char* str, hash_t hash = 14695981039346656037ull) | |
{ | |
return n > 0 ? fnv1a_hash(n - 1, str + 1, (hash ^ *str) * 1099511628211ull) : hash; | |
} | |
template<std::size_t N> | |
consteval hash_t fnv1a_hash(const char(&array)[N]) | |
{ | |
return fnv1a_hash(N - 1, &array[0]); | |
} | |
struct string_view | |
{ | |
char const* data; | |
std::size_t size; | |
consteval uint64_t hash() { | |
return fnv1a_hash(size, data); | |
} | |
}; | |
template<size_t N> | |
consteval size_t length(char const (&)[N]) | |
{ | |
return N - 1; | |
} | |
template<class T> | |
consteval string_view get_unique_name_for_type() | |
{ | |
return { __FUNCSIG__, length(__FUNCSIG__)}; | |
} | |
template<typename T> | |
consteval uint64_t get_type_id() { | |
return get_unique_name_for_type<T>().hash(); | |
} | |
template<typename T> | |
struct arg_types {}; | |
template<typename R, typename... A> | |
struct arg_types<R(*)(A...)> { | |
static constexpr std::array<uint64_t, sizeof...(A)> value = {get_type_id<A>()...}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment