HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
string_tag.hpp
1// Copyright 2019 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/Foundation/assert.hpp"
8#include "TTauri/Foundation/strings.hpp"
9#include <string>
10#include <string_view>
11#include <exception>
12#include <cstdint>
13#include <typeinfo>
14#include <typeindex>
15
16namespace tt {
17
18using string_tag = tt5_64;
19using string_ltag = tt5_128;
20
23constexpr string_tag operator""_tag(char const *str, size_t) noexcept
24{
25 return tt5_encode<string_tag>(str);
26}
27
30constexpr string_ltag operator""_ltag(char const *str, size_t) noexcept
31{
32 return tt5_encode<string_ltag>(str);
33}
34
35inline std::string tag_name(std::type_index tag) noexcept
36{
37 ttlet long_name = std::string{tag.name()};
38 ttlet split_name = split(long_name, "::"s);
39 if (ssize(split_name) != 0) {
40 ttlet &last_name = split_name.back();
41 if (ends_with(last_name, "_tag"s)) {
42 return last_name.substr(0, ssize(last_name) - 4);
43 } else {
44 return last_name;
45 }
46 } else {
47 return long_name;
48 }
49}
50
51template<typename Tag>
52std::string tag_name()
53{
54 return tag_name(std::type_index(typeid(Tag)));
55}
56
57template<typename Head, typename... Tail>
58std::type_index tag_at_index_impl(size_t index) noexcept
59{
60 if constexpr (sizeof...(Tail) > 0) {
61 return index == 0 ? std::type_index(typeid(Head)) : tag_at_index_impl<Tail...>(index - 1);
62 } else {
63 return index == 0 ? std::type_index(typeid(Head)) : std::type_index(typeid(void));
64 }
65}
66
70template<typename... Tags>
71std::type_index tag_at_index(size_t index) noexcept
72{
73 if constexpr (sizeof...(Tags) > 0) {
74 return tag_at_index_impl<Tags...>(index);
75 } else {
76 return std::type_index(typeid(void));
77 }
78}
79
80template<typename Head, typename... Tail>
81size_t index_of_tag_impl(std::type_index tag, size_t index) noexcept
82{
83 if constexpr (sizeof...(Tail) > 0) {
84 return tag == std::type_index(typeid(Head)) ? index : index_of_tag_impl<Tail...>(tag, index + 1);
85 } else {
86 return tag == std::type_index(typeid(Head)) ? index : index + 1;
87 }
88}
89
93template<typename... Tags>
94size_t index_of_tag(std::type_index tag) noexcept
95{
96 if constexpr (sizeof...(Tags) > 0) {
97 return index_of_tag_impl<Tags...>(tag, 0);
98 } else {
99 return 1;
100 }
101}
102
103template<typename Needle, typename Head, typename... Tail>
104constexpr size_t index_of_tag_impl(size_t index) noexcept
105{
106 if constexpr (sizeof...(Tail) > 0) {
107 return std::is_same_v<Needle,Head> ? index : index_of_tag_impl<Needle,Tail...>(index + 1);
108 } else {
109 return std::is_same_v<Needle,Head> ? index : index + 1;
110 }
111}
112
116template<typename Needle, typename... Haystack>
117constexpr size_t index_of_tag() noexcept
118{
119 if constexpr (sizeof...(Haystack) > 0) {
120 return index_of_tag_impl<Needle, Haystack...>(0);
121 } else {
122 return 1;
123 }
124}
125
126template<typename Needle, typename... Haystack>
127constexpr bool has_tag() noexcept {
128 return index_of_tag<Needle, Haystack...>() < sizeof...(Haystack);
129}
130
131template<typename... Haystack>
132bool has_tag(std::type_index needle) noexcept {
133 return index_of_tag<Haystack...>(needle) < sizeof...(Haystack);
134}
135
136
137}
TT5 A 5 bit code designed for encoding identifiers.
STL namespace.