Skip to content

Instantly share code, notes, and snippets.

@Jihadist
Created August 1, 2021 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jihadist/eb20227d63f017671bcf8ce5de44c054 to your computer and use it in GitHub Desktop.
Save Jihadist/eb20227d63f017671bcf8ce5de44c054 to your computer and use it in GitHub Desktop.
Compile time type info iteration
#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