diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-04-29 19:07:11 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-04-29 19:07:11 +0100 |
commit | 5a0b3927a33807cca4c77c40eb873f8a3b51b0b0 (patch) | |
tree | 4af0585ee8f8f468ab10c0a4fe9994fb30b79599 /lib/enumDetails.hpp | |
parent | Dunno how, but some DOS new lines got in here! (diff) | |
download | ilt-5a0b3927a33807cca4c77c40eb873f8a3b51b0b0.tar.bz2 ilt-5a0b3927a33807cca4c77c40eb873f8a3b51b0b0.tar.xz ilt-5a0b3927a33807cca4c77c40eb873f8a3b51b0b0.zip |
Drop .hpp for header only things
Half of them acquired a .cpp part anyway
Diffstat (limited to 'lib/enumDetails.hpp')
-rw-r--r-- | lib/enumDetails.hpp | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/lib/enumDetails.hpp b/lib/enumDetails.hpp deleted file mode 100644 index 5966be2..0000000 --- a/lib/enumDetails.hpp +++ /dev/null @@ -1,143 +0,0 @@ -#pragma once - -#include <algorithm> -#include <array> -#include <limits> -#include <optional> -#include <string_view> - -/// EnumDetailsBase -// Shared helpers -struct EnumDetailsBase { - template<size_t len> - constexpr static auto - strArr(auto input, auto start, auto end) - { - std::array<char, len> out; - input.copy(out.begin(), end - start, start); - return out; - } -}; - -/// EnumTypeDetails -// Extracts the fully qualified name of the enumeration -template<typename E> struct EnumTypeDetails : EnumDetailsBase { -#ifndef ENUM_PROBE -protected: -#endif - constexpr static std::string_view SEARCH_TYPE {"E = "}; - constexpr static auto - typeraw() - { - return std::string_view {__PRETTY_FUNCTION__}; - }; - constexpr static auto typeNameStart {typeraw().find(SEARCH_TYPE) + SEARCH_TYPE.length()}; - constexpr static auto typeNameEnd {typeraw().find_first_of("];", typeNameStart)}; - constexpr static auto typeNameLen {typeNameEnd - typeNameStart}; - constexpr static auto typeNameArr {strArr<typeNameLen>(typeraw(), typeNameStart, typeNameEnd)}; - -public: - constexpr static std::string_view typeName {typeNameArr.data(), typeNameArr.size()}; -}; - -/// EnumValueDetails -// Extracts the value name and constructs string_views of the parts -template<auto value> struct EnumValueDetails : public EnumTypeDetails<decltype(value)> { -#ifndef ENUM_PROBE -private: -#endif - using T = EnumTypeDetails<decltype(value)>; - constexpr static auto - raw() - { - return std::string_view {__PRETTY_FUNCTION__}; - }; - constexpr static auto nameStart {raw().find_last_of(": ") + 1}; - constexpr static auto nameEnd {raw().find_first_of("];", nameStart)}; - constexpr static auto nameLen {nameEnd - nameStart}; - constexpr static auto nameArr {EnumValueDetails::template strArr<nameLen>(raw(), nameStart, nameEnd)}; - -public: - constexpr static std::string_view valueName {nameArr.data(), nameArr.size()}; - constexpr static auto valid {valueName.back() < '0' || valueName.back() > '9'}; - constexpr static auto raw_value {value}; -}; - -/// EnumValueCollection -// Customisation point for specifying the range of underlying values your enum can have -template<typename E> struct EnumValueCollection { - using Vs = std::make_integer_sequence<int, 256>; -}; - -/// EnumDetails -// Interface for lookups/checks/etc at runtime -template<typename E> struct EnumDetails { -#ifndef ENUM_PROBE -private: -#endif - template<auto... n> - constexpr static auto - get_valids(std::integer_sequence<int, n...>) - { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" - return std::array {EnumValueDetails<static_cast<E>(n)>::valid...}; -#pragma GCC diagnostic pop - } - template<auto... n> - constexpr static auto - get_values(std::integer_sequence<int, n...>) - { - return std::array {EnumValueDetails<static_cast<E>(n)>::raw_value...}; - } - template<auto... n> - constexpr static auto - get_valueNames(std::integer_sequence<int, n...>) - { - return std::array {EnumValueDetails<values[n]>::valueName...}; - } - - using EVC = EnumValueCollection<E>; - constexpr static auto valid_flags {get_valids(typename EVC::Vs {})}; - constexpr static auto valid_count {std::count_if(valid_flags.begin(), valid_flags.end(), std::identity {})}; - - constexpr static auto - lookup(const auto key, const auto & search, const auto & out) - -> std::optional<typename std::decay_t<decltype(out)>::value_type> - { - if (const auto itr = std::find(search.begin(), search.end(), key); itr != search.end()) { - return out[static_cast<std::size_t>(std::distance(search.begin(), itr))]; - } - return std::nullopt; - } - -public: - constexpr static auto values {[]() { - constexpr auto values {get_values(typename EVC::Vs {})}; - static_assert(std::is_sorted(values.begin(), values.end()), "Candidate values must be sorted"); - std::array<E, valid_count> out; - std::copy_if(values.begin(), values.end(), out.begin(), [valid = valid_flags.begin()](auto) mutable { - return *valid++; - }); - return out; - }()}; - constexpr static auto names {get_valueNames(std::make_integer_sequence<int, valid_count> {})}; - - constexpr static bool - is_valid(E value) noexcept - { - return std::binary_search(values.begin(), values.end(), value); - } - - constexpr static std::optional<E> - parse(std::string_view name) noexcept - { - return lookup(name, names, values); - } - - constexpr static std::optional<std::string_view> - to_string(E value) noexcept - { - return lookup(value, values, names); - } -}; |