Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
type_info.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include "gaia/core/hashing_policy.h"
5#include "gaia/core/span.h"
6
7namespace gaia {
8 namespace meta {
9
10 //----------------------------------------------------------------------
11 // Type meta data
12 //----------------------------------------------------------------------
13
15 struct type_info final {
16 private:
17 constexpr static size_t find_first_of(const char* data, size_t len, char toFind, size_t startPos = 0) {
18 for (size_t i = startPos; i < len; ++i) {
19 if (data[i] == toFind)
20 return i;
21 }
22 return size_t(-1);
23 }
24
25 constexpr static size_t find_last_of(const char* data, size_t len, char c, size_t startPos = size_t(-1)) {
26 const auto minValue = startPos <= len - 1 ? startPos : len - 1;
27 for (int64_t i = (int64_t)minValue; i >= 0; --i) {
28 if (data[i] == c)
29 return (size_t)i;
30 }
31 return size_t(-1);
32 }
33
34 public:
38 template <typename T>
39 GAIA_NODISCARD static constexpr const char* full_name() noexcept {
40 return GAIA_PRETTY_FUNCTION;
41 }
42
46 template <typename T>
47 GAIA_NODISCARD static constexpr auto name() noexcept {
48 // MSVC:
49 // const char* __cdecl ecs::type_info::name<struct ecs::EnfEntity>(void)
50 // -> ecs::EnfEntity
51 // Clang/Clang-cl/GCC:
52 // const ecs::type_info::name() [T = ecs::EnfEntity]
53 // -> ecs::EnfEntity
54
55 // Note:
56 // We don't want to use std::string_view here because it would only make it harder on compile-times.
57 // In fact, even if we did, we need to be afraid of compiler issues.
58 // Clang 8 and older wouldn't compile because their string_view::find_last_of doesn't work
59 // in constexpr context. Tested with and without LIBCPP
60 // https://stackoverflow.com/questions/56484834/constexpr-stdstring-viewfind-last-of-doesnt-work-on-clang-8-with-libstdc
61 // As a workaround find_first_of and find_last_of were implemented
62
63 size_t strLen = 0;
64 while (GAIA_PRETTY_FUNCTION[strLen] != '\0')
65 ++strLen;
66
67 std::span<const char> name{GAIA_PRETTY_FUNCTION, strLen};
68 const auto prefixPos = find_first_of(name.data(), name.size(), GAIA_PRETTY_FUNCTION_PREFIX);
69 const auto start = find_first_of(name.data(), name.size(), ' ', prefixPos + 1);
70 const auto end = find_last_of(name.data(), name.size(), GAIA_PRETTY_FUNCTION_SUFFIX);
71 return name.subspan(start + 1, end - start - 1);
72 }
73
77 template <typename T>
78 GAIA_NODISCARD static constexpr auto hash() noexcept {
79#if GAIA_COMPILER_MSVC && _MSC_VER <= 1916
80 GAIA_MSVC_WARNING_PUSH()
81 GAIA_MSVC_WARNING_DISABLE(4307)
82#endif
83
84 auto n = name<T>();
85 return core::calculate_hash64(n.data(), n.size());
86
87#if GAIA_COMPILER_MSVC && _MSC_VER <= 1916
88 GAIA_MSVC_WARNING_PUSH()
89#endif
90 }
91 };
92
93 } // namespace meta
94} // namespace gaia
Provides compile-time compiler-derived names and hashes for C++ types.
Definition type_info.h:15
static GAIA_NODISCARD constexpr auto name() noexcept
Extracts the unqualified compiler spelling of T from the function signature.
Definition type_info.h:47
static GAIA_NODISCARD constexpr const char * full_name() noexcept
Returns the complete compiler function signature containing T.
Definition type_info.h:39
static GAIA_NODISCARD constexpr auto hash() noexcept
Calculates the stable Gaia-ECS hash of the compiler spelling of T.
Definition type_info.h:78