From 0bdbf94da0ca005669ba8fd551ebbd9156510673 Mon Sep 17 00:00:00 2001 From: "M. Galib Uludag" Date: Sun, 3 Mar 2024 19:24:20 +0000 Subject: [PATCH] remove flat_map --- include/enum_name.hpp | 794 +++++++++++++++++++++--------------------- 1 file changed, 389 insertions(+), 405 deletions(-) diff --git a/include/enum_name.hpp b/include/enum_name.hpp index 63885b2..c9ee552 100644 --- a/include/enum_name.hpp +++ b/include/enum_name.hpp @@ -68,442 +68,426 @@ #include #endif -namespace mgutility { -namespace detail { +namespace mgutility +{ + namespace detail + { -template -struct is_scoped_enum { - static constexpr auto value = - std::is_enum::value && - !std::is_convertible::type>::value; -}; + template + struct is_scoped_enum + { + static constexpr auto value = + std::is_enum::value && + !std::is_convertible::type>::value; + }; #if MG_ENUM_NAME_CPLUSPLUS < 201703L -template -using enable_if_t = typename std::enable_if::type; - -constexpr auto strlen_constexpr(const char* str, size_t sz = 0) noexcept - -> size_t { - return str[sz] == '\0' ? sz : strlen_constexpr(str, ++sz); -} - -template -class basic_string_view { - public: - constexpr inline basic_string_view() noexcept : data_(""), size_(0) {} - constexpr inline basic_string_view(const Char* str) noexcept - : data_(str), size_(strlen_constexpr(str)) {} - constexpr inline basic_string_view(const Char* str, size_t len) noexcept - : data_(str), size_(len) {} - constexpr inline basic_string_view(const basic_string_view& other) - : data_(other.data_), size_(other.size_) {} - constexpr inline basic_string_view(basic_string_view&& other) noexcept - : data_(std::move(other.data_)), size_(std::move(other.size_)) {} - MG_ENUM_NAME_CNSTXPR inline basic_string_view& operator=( - const basic_string_view& other) noexcept { - data_ = other.data_; - size_ = other.size_; - return *this; - } - MG_ENUM_NAME_CNSTXPR inline basic_string_view& operator=( - basic_string_view&& other) noexcept { - data_ = std::move(other.data_); - size_ = std::move(other.size_); - return *this; - } - constexpr inline const Char operator[](size_t index) const noexcept { - return data_[index]; - } - constexpr inline const Char* begin() const noexcept { return data_; } - constexpr inline const Char* end() const noexcept { - return (data_ + size_); - } - constexpr inline bool empty() const noexcept { return size_ < 1; } - constexpr inline size_t size() const noexcept { return size_; } - constexpr inline const Char* data() const noexcept { return data_; } - constexpr inline basic_string_view substr(size_t begin, - size_t len) const noexcept { - return basic_string_view(data_ + begin, len); - } - constexpr inline size_t rfind(Char c, size_t pos = 0) const noexcept { - return c == data_[pos] ? pos : rfind(c, --pos); - } + template + using enable_if_t = typename std::enable_if::type; - constexpr friend inline bool operator==( - basic_string_view lhs, basic_string_view rhs) noexcept { - return (lhs.size_ == rhs.size_) && - std::strncmp(lhs.data_, rhs.data_, lhs.size_) == 0; - } + constexpr auto strlen_constexpr(const char *str, size_t sz = 0) noexcept + -> size_t + { + return str[sz] == '\0' ? sz : strlen_constexpr(str, ++sz); + } - inline operator std::string() { return std::string(data_, size_); } - inline operator std::string() const { return std::string(data_, size_); } + template + class basic_string_view + { + public: + constexpr inline basic_string_view() noexcept : data_(""), size_(0) {} + constexpr inline basic_string_view(const Char *str) noexcept + : data_(str), size_(strlen_constexpr(str)) {} + constexpr inline basic_string_view(const Char *str, size_t len) noexcept + : data_(str), size_(len) {} + constexpr inline basic_string_view(const basic_string_view &other) + : data_(other.data_), size_(other.size_) {} + constexpr inline basic_string_view(basic_string_view &&other) noexcept + : data_(std::move(other.data_)), size_(std::move(other.size_)) {} + MG_ENUM_NAME_CNSTXPR inline basic_string_view &operator=( + const basic_string_view &other) noexcept + { + data_ = other.data_; + size_ = other.size_; + return *this; + } + MG_ENUM_NAME_CNSTXPR inline basic_string_view &operator=( + basic_string_view &&other) noexcept + { + data_ = std::move(other.data_); + size_ = std::move(other.size_); + return *this; + } + constexpr inline const Char operator[](size_t index) const noexcept + { + return data_[index]; + } + constexpr inline const Char *begin() const noexcept { return data_; } + constexpr inline const Char *end() const noexcept + { + return (data_ + size_); + } + constexpr inline bool empty() const noexcept { return size_ < 1; } + constexpr inline size_t size() const noexcept { return size_; } + constexpr inline const Char *data() const noexcept { return data_; } + constexpr inline basic_string_view substr(size_t begin, + size_t len) const noexcept + { + return basic_string_view(data_ + begin, len); + } + constexpr inline size_t rfind(Char c, size_t pos = 0) const noexcept + { + return c == data_[pos] ? pos : rfind(c, --pos); + } + + constexpr friend inline bool operator==( + basic_string_view lhs, basic_string_view rhs) noexcept + { + return (lhs.size_ == rhs.size_) && + std::strncmp(lhs.data_, rhs.data_, lhs.size_) == 0; + } + + inline operator std::string() { return std::string(data_, size_); } + inline operator std::string() const { return std::string(data_, size_); } + + friend inline std::ostream &operator<<(std::ostream &os, + const basic_string_view &sv) + { + for (auto c : sv) + { + os << c; + } + return os; + } + + private: + size_t size_; + const Char *data_; + }; + + using string_view = basic_string_view; + + struct bad_optional_access : public std::exception + { + const char *what() const noexcept { return "optional has no value"; } + }; - friend inline std::ostream& operator<<(std::ostream& os, - const basic_string_view& sv) { - for (auto c : sv) { - os << c; - } - return os; - } + struct nullopt_t; - private: - size_t size_; - const Char* data_; -}; - -using string_view = basic_string_view; - -struct bad_optional_access : public std::exception { - const char* what() const noexcept { return "optional has no value"; } -}; - -struct nullopt_t; - -template -class optional { - public: - MG_ENUM_NAME_CNSTXPR inline optional(nullopt_t&) - : dummy_{0}, has_value_{false} {} - MG_ENUM_NAME_CNSTXPR inline optional() - : dummy_{0}, has_value_{false} {} - template - MG_ENUM_NAME_CNSTXPR inline optional(Args&&... args) - : value_{T{std::forward(args)...}}, has_value_{true} {} - MG_ENUM_NAME_CNSTXPR inline optional(T&& value) - : value_{value}, has_value_{true} {} - MG_ENUM_NAME_CNSTXPR inline optional(const optional& other) - : value_{other.value_}, has_value_{other.has_value_} {} - MG_ENUM_NAME_CNSTXPR inline optional(optional&& other) - : value_{other.value_}, has_value_{other.has_value_} { - other.reset(); - } - inline ~optional() { has_value_ = false; } - MG_ENUM_NAME_CNSTXPR inline optional& operator=(const optional& other) { - value_ = other.value_; - has_value_ = other.has_value_; - return *this; - } - MG_ENUM_NAME_CNSTXPR inline optional& operator=(optional&& other) { - value_ = other.value_; - has_value_ = other.has_value_; - other.reset(); - return *this; - } - MG_ENUM_NAME_CNSTXPR inline void swap(optional&& other) { - auto val = std::move(other.value_); - other.value_ = std::move(value_); - value_ = std::move(val); - - auto hval = std::move(other.has_value_); - other.has_value_ = std::move(has_value_); - has_value_ = std::move(hval); - } - MG_ENUM_NAME_CNSTXPR inline T& operator*() { - return value_; - } - MG_ENUM_NAME_CNSTXPR inline T& operator*() const { - return value_; - } - MG_ENUM_NAME_CNSTXPR inline T& value() { - if (!has_value_) throw detail::bad_optional_access(); - return value_; - } - MG_ENUM_NAME_CNSTXPR inline T& value() const { - if (!has_value_) throw detail::bad_optional_access(); - return value_; - } - MG_ENUM_NAME_CNSTXPR inline T value_or(T&& value) { - return has_value_ ? value_ : value; - } - MG_ENUM_NAME_CNSTXPR inline T value_or(T&& value) const { - return has_value_ ? value_ : value; - } - MG_ENUM_NAME_CNSTXPR inline T value_or(const T& value) { - return has_value_ ? value_ : value; - } - MG_ENUM_NAME_CNSTXPR inline T value_or(const T& value) const { - return has_value_ ? value_ : value; - } - MG_ENUM_NAME_CNSTXPR inline void emplace(T value) { - value_ = std::move(value); - has_value_ = true; - } - template - MG_ENUM_NAME_CNSTXPR inline void emplace(Args&&... args) { - value_ = std::move(T{std::forward(args)...}); - has_value_ = true; - } - MG_ENUM_NAME_CNSTXPR inline bool has_value() const { return has_value_; } + template + class optional + { + public: + MG_ENUM_NAME_CNSTXPR inline optional(nullopt_t &) + : dummy_{0}, has_value_{false} {} + MG_ENUM_NAME_CNSTXPR inline optional() + : dummy_{0}, has_value_{false} {} + template + MG_ENUM_NAME_CNSTXPR inline optional(Args &&...args) + : value_{T{std::forward(args)...}}, has_value_{true} {} + MG_ENUM_NAME_CNSTXPR inline optional(T &&value) + : value_{value}, has_value_{true} {} + MG_ENUM_NAME_CNSTXPR inline optional(const optional &other) + : value_{other.value_}, has_value_{other.has_value_} {} + MG_ENUM_NAME_CNSTXPR inline optional(optional &&other) + : value_{other.value_}, has_value_{other.has_value_} + { + other.reset(); + } + inline ~optional() { has_value_ = false; } + MG_ENUM_NAME_CNSTXPR inline optional &operator=(const optional &other) + { + value_ = other.value_; + has_value_ = other.has_value_; + return *this; + } + MG_ENUM_NAME_CNSTXPR inline optional &operator=(optional &&other) + { + value_ = other.value_; + has_value_ = other.has_value_; + other.reset(); + return *this; + } + MG_ENUM_NAME_CNSTXPR inline void swap(optional &&other) + { + auto val = std::move(other.value_); + other.value_ = std::move(value_); + value_ = std::move(val); + + auto hval = std::move(other.has_value_); + other.has_value_ = std::move(has_value_); + has_value_ = std::move(hval); + } + MG_ENUM_NAME_CNSTXPR inline T &operator*() + { + return value_; + } + MG_ENUM_NAME_CNSTXPR inline T &operator*() const + { + return value_; + } + MG_ENUM_NAME_CNSTXPR inline T &value() + { + if (!has_value_) + throw detail::bad_optional_access(); + return value_; + } + MG_ENUM_NAME_CNSTXPR inline T &value() const + { + if (!has_value_) + throw detail::bad_optional_access(); + return value_; + } + MG_ENUM_NAME_CNSTXPR inline T value_or(T &&value) + { + return has_value_ ? value_ : value; + } + MG_ENUM_NAME_CNSTXPR inline T value_or(T &&value) const + { + return has_value_ ? value_ : value; + } + MG_ENUM_NAME_CNSTXPR inline T value_or(const T &value) + { + return has_value_ ? value_ : value; + } + MG_ENUM_NAME_CNSTXPR inline T value_or(const T &value) const + { + return has_value_ ? value_ : value; + } + MG_ENUM_NAME_CNSTXPR inline void emplace(T value) + { + value_ = std::move(value); + has_value_ = true; + } + template + MG_ENUM_NAME_CNSTXPR inline void emplace(Args &&...args) + { + value_ = std::move(T{std::forward(args)...}); + has_value_ = true; + } + MG_ENUM_NAME_CNSTXPR inline bool has_value() const { return has_value_; } #if !(defined(__clang__) && __clang_major__ < 11) - template ::value, - bool>::type = true> - MG_ENUM_NAME_CNSTXPR inline void reset() { - T::~T(); - has_value_ = false; - } + template ::value, + bool>::type = true> + MG_ENUM_NAME_CNSTXPR inline void reset() + { + T::~T(); + has_value_ = false; + } #endif - template ::value, - bool>::type = true> - MG_ENUM_NAME_CNSTXPR inline void reset() { - value_ = T{}; - has_value_ = false; - } - - MG_ENUM_NAME_CNSTXPR operator bool() { return has_value_; } - - private: - union { - T value_; - char dummy_[sizeof(T)]; - }; - bool has_value_; -}; - -struct nullopt_t { - template - MG_ENUM_NAME_CNSTXPR operator optional() { - return optional{}; - } -}; + template ::value, + bool>::type = true> + MG_ENUM_NAME_CNSTXPR inline void reset() + { + value_ = T{}; + has_value_ = false; + } + + MG_ENUM_NAME_CNSTXPR operator bool() { return has_value_; } + + private: + union + { + T value_; + char dummy_[sizeof(T)]; + }; + bool has_value_; + }; + + struct nullopt_t + { + template + MG_ENUM_NAME_CNSTXPR operator optional() + { + return optional{}; + } + }; -auto nullopt = nullopt_t{}; + auto nullopt = nullopt_t{}; #else -template -using optional = std::optional; -inline constexpr auto nullopt{std::nullopt}; -using string_view = std::string_view; -template -using enable_if_t = std::enable_if_t; + template + using optional = std::optional; + inline constexpr auto nullopt{std::nullopt}; + using string_view = std::string_view; + template + using enable_if_t = std::enable_if_t; #endif -template -class flat_map { - public: - MG_ENUM_NAME_CNSTXPR_GT_14 flat_map( - std::array, N> values) - : buckets{} { - for (const auto& v : values) { - const std::size_t index = hash(v.key) % bucket_count; - buckets[index].first = v.key; - buckets[index].second = v.value; - } - } - - MG_ENUM_NAME_CNSTXPR_GT_14 flat_map( - std::initializer_list>&& values) - : buckets{} { - for (const auto& v : values) { - const std::size_t index = hash(v.first) % bucket_count; - buckets[index].first = v.first; - buckets[index].second = v.second; - } - } - - MG_ENUM_NAME_CNSTXPR_GT_14 detail::optional operator[]( - const Key& key) const noexcept { - const std::size_t index = hash(key) % bucket_count; - const auto& result = buckets[index]; - return !key.empty() && key == result.first - ? detail::optional{result.second} - : detail::nullopt; - } - - MG_ENUM_NAME_CNSTXPR_GT_14 detail::optional value( - const Key& key) const noexcept { - const std::size_t index = hash(key) % bucket_count; - const auto& result = buckets[index]; - return !key.empty() && key == result.first ? result.second - : detail::nullopt; - } - - private: - static constexpr std::size_t bucket_count = N; - std::array, bucket_count> buckets; - - static constexpr std::size_t hash(const Key& key) noexcept { - return fnv1a(key); - } - - static MG_ENUM_NAME_CNSTXPR std::uint64_t fnv1a( - detail::string_view str, std::uint64_t hash = 14695981039346656037u) noexcept { - for (char c : str) { - hash ^= static_cast(c); - hash *= 1099511628211u; - } - return hash; - } -}; - -template -struct enum_sequence {}; + template + struct enum_sequence + { + }; -template -struct enum_sequence_helper - : enum_sequence_helper {}; + template + struct enum_sequence_helper + : enum_sequence_helper + { + }; -template -struct enum_sequence_helper { - using type = enum_sequence(Next)...>; -}; + template + struct enum_sequence_helper + { + using type = enum_sequence(Next)...>; + }; -template -using make_enum_sequence = typename enum_sequence_helper::type; + template + using make_enum_sequence = typename enum_sequence_helper::type; -struct enum_type { + struct enum_type + { #if defined(_MSC_VER) #define __PRETTY_FUNCTION__ __FUNCSIG__ #endif - template ::value, - bool>::type = true> - MG_ENUM_NAME_CNSTXPR static inline auto name() noexcept - -> detail::string_view { - auto str = detail::string_view(__PRETTY_FUNCTION__); - auto offset{lastidxenumname[0] + lastidxenumname[1]}; - auto index = - std::max(str.rfind(lastidxenumname[2], str.size() - offset), - str.rfind(lastidxenumname[3], str.size() - offset)); - auto result = str.substr(index + 1, str.size() - offset - index); - return result[0] == '(' ? "" : result; - } - - template ::value, - bool>::type = true> - MG_ENUM_NAME_CNSTXPR static inline auto name() noexcept - -> detail::string_view { - auto str = detail::string_view(__PRETTY_FUNCTION__); - auto index = - str.rfind(lastidxenumname[3], str.size() - lastidxenumname[0]) + 1; - auto result = - str.substr(index, str.size() - lastidxenumname[0] - index); - return result.size() > 4 ? result[4] == lastidxenumname[4] ? "" : result - : result; - } - - private: - static constexpr int lastidxenumname[] = + template ::value, + bool>::type = true> + MG_ENUM_NAME_CNSTXPR static inline auto name() noexcept + -> detail::string_view + { + auto str = detail::string_view(__PRETTY_FUNCTION__); + auto offset{lastidxenumname[0] + lastidxenumname[1]}; + auto index = + std::max(str.rfind(lastidxenumname[2], str.size() - offset), + str.rfind(lastidxenumname[3], str.size() - offset)); + auto result = str.substr(index + 1, str.size() - offset - index); + return result[0] == '(' ? "" : result; + } + + template ::value, + bool>::type = true> + MG_ENUM_NAME_CNSTXPR static inline auto name() noexcept + -> detail::string_view + { + auto str = detail::string_view(__PRETTY_FUNCTION__); + auto index = + str.rfind(lastidxenumname[3], str.size() - lastidxenumname[0]) + 1; + auto result = + str.substr(index, str.size() - lastidxenumname[0] - index); + return result.size() > 4 ? result[4] == lastidxenumname[4] ? "" : result + : result; + } + + private: + static constexpr int lastidxenumname[] = #if defined(_MSC_VER) - {22, 0, ',', ':', '<'}; + {22, 0, ',', ':', '<'}; #elif defined(__clang__) - {1, 1, ' ', ':', '('}; + {1, 1, ' ', ':', '('}; #elif defined(__GNUC__) - { + { #if MG_ENUM_NAME_CPLUSPLUS < 201703L - 179, + 179, #else - 165, + 165, #endif - 5, ' ', ':', '('}; + 5, ' ', ':', '('}; #endif -}; - -template = true> -inline auto __for_each_to_enum_impl(detail::string_view str, int Min, - detail::enum_sequence) noexcept - -> detail::optional { - MG_ENUM_NAME_CNSTXPR static std::array - arr{"", enum_type::template name()...}; - const auto index{std::find(arr.begin() + 1, arr.end(), str)}; - return index == arr.end() - ? detail::nullopt - : detail::optional{static_cast( - std::distance(arr.begin(), index) + Min - 1)}; -} - -template = 100000, bool> = true> -inline auto __for_each_to_enum_impl(detail::string_view str, int Min, - detail::enum_sequence) noexcept - -> detail::optional { - MG_ENUM_NAME_CNSTXPR_GT_14 static detail::flat_map - map{{"", static_cast(0)}, - {enum_type::template name(), static_cast(Is)}...}; - return map[str]; -} - -template -inline auto __for_each_enum_impl(Enum e, int Min, int Max, - detail::enum_sequence) noexcept - -> detail::string_view { - MG_ENUM_NAME_CNSTXPR static std::array - arr{"", enum_type::template name()...}; - const auto index{std::abs(Min) + static_cast(e) + (Min < 0 ? 1 : 1)}; - return arr[(index < Min || index > arr.size() - 1) ? 0 : index]; -} -template -inline auto __for_each_enum_vec_impl(int Min, int Max, - detail::enum_sequence) - -> std::vector> { - MG_ENUM_NAME_CNSTXPR static std::array - arr{"", enum_type::template name()...}; - std::vector> vec; - vec.reserve(sizeof...(Is)); - for (auto i{1}; i < arr.size(); ++i) { - if (!arr[i].empty()) { - vec.emplace_back(std::pair{ - arr[i], static_cast(i + Min - 1)}); + }; + + template + inline auto __for_each_to_enum_impl(detail::string_view str, int Min, + detail::enum_sequence) noexcept + -> detail::optional + { + MG_ENUM_NAME_CNSTXPR static std::array + arr{"", enum_type::template name()...}; + const auto index{std::find(arr.begin() + 1, arr.end(), str)}; + return index == arr.end() + ? detail::nullopt + : detail::optional{static_cast( + std::distance(arr.begin(), index) + Min - 1)}; } - } - vec.shrink_to_fit(); - return vec; -} -} // namespace detail -} // namespace mgutility - -namespace mgutility { -template -struct enum_range + + template + inline auto __for_each_enum_impl(Enum e, int Min, int Max, + detail::enum_sequence) noexcept + -> detail::string_view + { + MG_ENUM_NAME_CNSTXPR static std::array + arr{"", enum_type::template name()...}; + const auto index{std::abs(Min) + static_cast(e) + (Min < 0 ? 1 : 1)}; + return arr[(index < Min || index > arr.size() - 1) ? 0 : index]; + } + template + inline auto __for_each_enum_vec_impl(int Min, int Max, + detail::enum_sequence) + -> std::vector> + { + MG_ENUM_NAME_CNSTXPR static std::array + arr{"", enum_type::template name()...}; + std::vector> vec; + vec.reserve(sizeof...(Is)); + for (auto i{1}; i < arr.size(); ++i) + { + if (!arr[i].empty()) + { + vec.emplace_back(std::pair{ + arr[i], static_cast(i + Min - 1)}); + } + } + vec.shrink_to_fit(); + return vec; + } + } // namespace detail +} // namespace mgutility + +namespace mgutility { - static constexpr auto min{-128}; - static constexpr auto max{128}; -}; - -template -MG_ENUM_NAME_CNSTXPR inline auto enum_name(Enum e) noexcept - -> detail::string_view { - static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); - static_assert(std::is_enum::value, "Value is not an Enum type!"); - return __for_each_enum_impl( - e, Min, Max, mgutility::detail::make_enum_sequence()); -} - -template ::min, int Max = enum_range::max> -MG_ENUM_NAME_CNSTXPR inline auto enum_name(Enum e) noexcept - -> detail::string_view { - static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); - static_assert(std::is_enum::value, "Value is not an Enum type!"); - return __for_each_enum_impl( - e, Min, Max, mgutility::detail::make_enum_sequence()); -} - -template ::min, int Max = enum_range::max> -MG_ENUM_NAME_CNSTXPR inline auto to_enum(detail::string_view str) noexcept - -> detail::optional { - static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); - static_assert(std::is_enum::value, "Type is not an Enum type!"); - return __for_each_to_enum_impl( - str, Min, detail::make_enum_sequence()); -} -template ::min, int Max = enum_range::max> -MG_ENUM_NAME_CNSTXPR inline auto enum_vec() noexcept - -> std::vector> { - static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); - static_assert(std::is_enum::value, "Type is not an Enum type!"); - return __for_each_enum_vec_impl( - Min, Max, detail::make_enum_sequence()); -} -} // namespace mgutility -#endif // MGUTILITY_ENUM_NAME_HPP + template + struct enum_range + { + static constexpr auto min{-128}; + static constexpr auto max{128}; + }; + + template + MG_ENUM_NAME_CNSTXPR inline auto enum_name(Enum e) noexcept + -> detail::string_view + { + static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); + static_assert(std::is_enum::value, "Value is not an Enum type!"); + return __for_each_enum_impl( + e, Min, Max, mgutility::detail::make_enum_sequence()); + } + + template ::min, int Max = enum_range::max> + MG_ENUM_NAME_CNSTXPR inline auto enum_name(Enum e) noexcept + -> detail::string_view + { + static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); + static_assert(std::is_enum::value, "Value is not an Enum type!"); + return __for_each_enum_impl( + e, Min, Max, mgutility::detail::make_enum_sequence()); + } + + template ::min, int Max = enum_range::max> + MG_ENUM_NAME_CNSTXPR inline auto to_enum(detail::string_view str) noexcept + -> detail::optional + { + static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); + static_assert(std::is_enum::value, "Type is not an Enum type!"); + return __for_each_to_enum_impl( + str, Min, detail::make_enum_sequence()); + } + template ::min, int Max = enum_range::max> + MG_ENUM_NAME_CNSTXPR inline auto enum_vec() noexcept + -> std::vector> + { + static_assert(Min < Max - 1, "Max must be greater than (Min + 1)!"); + static_assert(std::is_enum::value, "Type is not an Enum type!"); + return __for_each_enum_vec_impl( + Min, Max, detail::make_enum_sequence()); + } +} // namespace mgutility +#endif // MGUTILITY_ENUM_NAME_HPP