Symmetri
Loading...
Searching...
No Matches
colors.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <string.h>
6
7#include <array>
8#include <cassert>
9#include <cstdint>
10#include <limits>
11#include <string_view>
12#include <vector>
13
14#ifndef DOXYGEN_SHOULD_SKIP_THIS
15namespace sym_impl {
16// https://rodusek.com/posts/2021/03/09/getting-an-unmangled-type-name-at-compile-time/
17
18template <std::size_t... Idxs>
19constexpr auto substring_as_array(std::string_view str,
20 std::index_sequence<Idxs...>) {
21 return std::array{str[Idxs]..., '\0'};
22}
23
24template <typename T>
25constexpr auto type_name_array() {
26#if defined(__clang__)
27 constexpr auto prefix = std::string_view{"[T = symmetri::"};
28 constexpr auto suffix = std::string_view{"]"};
29 constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
30#elif defined(__GNUC__)
31 constexpr auto prefix = std::string_view{"with T = symmetri::"};
32 constexpr auto suffix = std::string_view{"]"};
33 constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
34#elif defined(_MSC_VER)
35 constexpr auto prefix = std::string_view{"type_name_array<symmetri::"};
36 constexpr auto suffix = std::string_view{">(void)"};
37 constexpr auto function = std::string_view{__FUNCSIG__};
38#else
39#error Unsupported compiler
40#endif
41
42 constexpr auto start = function.find(prefix) + prefix.size();
43 constexpr auto end = function.rfind(suffix);
44
45 static_assert(start < end);
46
47 constexpr auto name = function.substr(start, (end - start));
48 return substring_as_array(name, std::make_index_sequence<name.size()>{});
49}
50
51template <typename T>
52struct type_name_holder {
53 static inline constexpr auto value = type_name_array<T>();
54};
55
56template <typename T>
57constexpr auto type_name() -> std::string_view {
58 constexpr auto& value = type_name_holder<T>::value;
59 return std::string_view{value.data(), value.size()};
60}
61
62#endif /* DOXYGEN_SHOULD_SKIP_THIS */
63}
64namespace symmetri {
65
74class Token {
75 private:
76 constexpr uint8_t find(const char* key) {
77 uint8_t i = 0;
78 while (i < colors.size()) {
79 if (std::string_view(colors[i].data()) == std::string_view(key)) return i;
80 ++i;
81 }
82 return findSlot();
83 }
84
85 constexpr uint8_t findSlot() {
86 uint8_t i = 0;
87 while (i < colors.size()) {
88 if (std::string_view(colors[i].data()).empty()) return i;
89 ++i;
90 }
91 return i;
92 }
93
94 public:
100 static std::vector<std::string_view> getColors() {
101 std::vector<std::string_view> _colors;
102 _colors.reserve(colors.size());
103 for (const auto& s : colors) {
104 if (strlen(s.data()) > 0) {
105 _colors.emplace_back(s.data());
106 }
107 }
108 return _colors;
109 }
110
111 constexpr std::string_view toString() const {
112 return std::string_view(colors[id].data());
113 }
114
115 template <class T>
116 constexpr bool operator==(const T& t) const {
117 return id == t.id;
118 }
119
120 constexpr bool operator<(const Token& rhs) const {
121 return id < rhs.toIndex();
122 }
123
124 constexpr bool operator>(const Token& rhs) const {
125 return id > rhs.toIndex();
126 }
127
128 constexpr uint8_t toIndex() const { return id; }
129
130 constexpr Token(const char* _id) : id(find(_id)) {
131 assert(id < colors.size() &&
132 "There can only be kMaxTokenColors different token-colors.");
133 if (strlen(colors[id].data()) == 0) {
134 strcpy(colors[id].data(), _id);
135 }
136 }
137
138 protected:
139 inline static std::array<std::array<char, 64>, 128> colors = {};
140 uint8_t id;
141};
142
143} // namespace symmetri
144
145// Custom specialization of std::hash can be injected in namespace std.
146template <>
147struct std::hash<symmetri::Token> {
148 constexpr std::size_t operator()(const symmetri::Token& s) const noexcept {
149 return s.toIndex();
150 }
151};
152
158#define CREATE_CUSTOM_TOKEN(name) \
159 namespace symmetri { \
160 struct name : public Token { \
161 constexpr name() : Token(sym_impl::type_name<name>().data()) {} \
162 }; \
163 static inline name name; \
164 }
165
Tokens are elements that can reside in places. Tokens can have a color which makes them distinguishab...
Definition colors.hpp:74
static std::vector< std::string_view > getColors()
Get a list of all the colors.
Definition colors.hpp:100
#define CREATE_CUSTOM_TOKEN(name)
A macro from which we can create token-colors. Colors ceated this way end up in the symmetri namespac...
Definition colors.hpp:158