Created
August 1, 2021 15:41
-
-
Save Jihadist/eb20227d63f017671bcf8ce5de44c054 to your computer and use it in GitHub Desktop.
Compile time type info iteration
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 <array> | |
#include <iostream> | |
#include <variant> | |
static_assert(__GNUC__, "Unsupported compiler"); | |
using BYTE = uint8_t; | |
using WORD = uint16_t; | |
using DWORD = uint32_t; | |
using INT32 = int32_t; | |
using BYTE_4t = std::array<BYTE, 4>; | |
using WORD_4t = std::array<WORD, 4>; | |
using BYTE_8t = std::array<BYTE, 8>; | |
using WORD_8t = std::array<WORD, 8>; | |
using BYTE_16t = std::array<BYTE, 16>; | |
using WORD_16t = std::array<WORD, 16>; | |
using FLOAT_2t = std::array<float, 2>; | |
using FLOAT_2t_2t = std::array<FLOAT_2t, 2>; | |
using FLOAT_3t = std::array<float, 3>; | |
using FLOAT_6t = std::array<float, 6>; | |
using FLOAT_8t = std::array<float, 8>; | |
class cstring | |
{ | |
public: | |
using iterator = const char *; | |
using const_iteratpr = iterator; | |
template <std::size_t N> constexpr cstring(const char (&str)[N]) : cstring { &str[0], N - 1 } | |
{ | |
} | |
constexpr cstring(const char *begin, std::size_t length) : _str { begin }, _length { length } | |
{ | |
} | |
constexpr cstring(const char *begin, const char *end) : cstring { begin, static_cast<std::size_t>(end - begin) } | |
{ | |
} | |
constexpr cstring(const char *begin) : cstring { begin, length(begin) } | |
{ | |
} | |
static constexpr std::size_t length(const char *str) | |
{ | |
return *str ? 1 + length(str + 1) : 0; | |
} | |
constexpr std::size_t length() const | |
{ | |
return _length; | |
} | |
constexpr std::size_t size() const | |
{ | |
return length(); | |
} | |
constexpr bool empty() const | |
{ | |
return size(); | |
} | |
std::string cppstring() const | |
{ | |
return { begin(), end() }; | |
} | |
std::string str() const | |
{ | |
return cppstring(); | |
} | |
constexpr iterator begin() const | |
{ | |
return _str; | |
} | |
constexpr iterator end() const | |
{ | |
return _str + _length; | |
} | |
constexpr char operator[](std::size_t i) const | |
{ | |
return _str[i]; | |
} | |
constexpr const char *operator()(std::size_t i) const | |
{ | |
return _str + i; | |
} | |
constexpr cstring operator()(std::size_t begin, std::size_t end) const | |
{ | |
return { _str + begin, _str + end }; | |
} | |
constexpr cstring pad(std::size_t begin_offset, std::size_t end_offset) const | |
{ | |
return operator()(begin_offset, size() - end_offset); | |
} | |
friend std::ostream &operator<<(std::ostream &os, const cstring &str) | |
{ | |
for (const char c : str) | |
{ | |
os << c; | |
} | |
return os; | |
} | |
private: | |
const char *_str; | |
std::size_t _length; | |
}; | |
namespace detail | |
{ | |
template <class F, size_t... I> constexpr void for_constexpr_impl(F &&func, std::index_sequence<I...>) | |
{ | |
(func(std::integral_constant<std::size_t, I> {}), ...); | |
} | |
} | |
template <size_t C, class F> constexpr void for_constexpr(F &&func) | |
{ | |
detail::for_constexpr_impl(std::forward<F>(func), std::make_index_sequence<C> {}); | |
} | |
using varVal = std::variant<BYTE, WORD, DWORD, INT32, BYTE_4t, WORD_4t, BYTE_8t, WORD_8t, BYTE_16t, WORD_16t, float, | |
FLOAT_2t, FLOAT_2t_2t, FLOAT_3t, FLOAT_6t, FLOAT_8t>; | |
template <typename T> constexpr cstring nameof() | |
{ | |
return cstring(__PRETTY_FUNCTION__); | |
} | |
template <typename T, typename F> static constexpr cstring test() | |
{ | |
constexpr auto size = std::variant_size_v<F>; | |
cstring str(""); | |
for_constexpr<size>([&](auto index) { | |
if constexpr (std::is_same_v<T, std::variant_alternative_t<index, F>>) | |
{ | |
str = nameof<T>(); | |
} | |
}); | |
return str.empty() ? str.pad(37, 1) : str; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
std::cout << cstring("hello world") << std::endl; | |
std::cout << test<bool, varVal>() << std::endl; | |
std::cout << test<BYTE, varVal>() << std::endl; | |
std::cout << test<WORD, varVal>() << std::endl; | |
std::cout << test<DWORD, varVal>() << std::endl; | |
std::cout << test<INT32, varVal>() << std::endl; | |
std::cout << test<BYTE_4t, varVal>() << std::endl; | |
std::cout << test<WORD_4t, varVal>() << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment