|
- #pragma once
-
- #include "enum.h"
-
- namespace cppcore
- {
-
- namespace __impl
- {
-
- /* enum_value_traits */
-
- template<typename T_enum, typename T_enable>
- decltype(auto) enum_value_traits<T_enum, T_enable>::get_enum_values()
- {
- static const auto value = enum_value_vector_type();
- return value;
- }
-
- /* enum_conversion_traits */
-
- template<typename T_enum, typename T_traits>
- decltype(auto) enum_conversion_traits<T_enum, T_traits>
- ::get_enum_to_string_map()
- {
- static const auto value = create_enum_to_string_map();
- return value;
- }
-
- template<typename T_enum, typename T_traits>
- decltype(auto) enum_conversion_traits<T_enum, T_traits>
- ::get_string_to_enum_map()
- {
- static const auto value = create_string_to_enum_map();
- return value;
- }
-
- template<typename T_enum, typename T_traits>
- decltype(auto) enum_conversion_traits<T_enum, T_traits>
- ::create_enum_to_string_map()
- {
- auto& values = traits_type::get_enum_values();
- enum_to_string_map_type ret;
- for (auto& p : values)
- {
- ret.emplace(p.first, p.second);
- }
- return ret;
- }
-
- template<typename T_enum, typename T_traits>
- decltype(auto) enum_conversion_traits<T_enum, T_traits>
- ::create_string_to_enum_map()
- {
- auto& values = traits_type::get_enum_values();
- string_to_enum_map_type ret;
- for (auto& p : values)
- {
- ret.emplace(p.second, p.first);
- }
- return ret;
- }
-
- }
-
- /* enum_conversion */
-
- template<typename T_enum, typename T_traits>
- std::string enum_conversion<T_enum, T_traits>
- ::to_string(enum_type value, bool add_numeric_value)
- {
- std::string ret;
- auto& map = traits_type::get_enum_to_string_map();
- auto it = map.find(value);
- if (it != map.end())
- {
- ret = it->second;
- if (add_numeric_value)
- ret += '(' + std::to_string(static_cast<base_type>(value)) + ')'; // TODO
- }
- else
- ret = std::to_string(static_cast<base_type>(value)); // TODO
- return ret;
- }
-
- template<typename T_enum, typename T_traits>
- bool enum_conversion<T_enum, T_traits>
- ::try_to_enum(const std::string& str, enum_type& value, bool accept_numeric_value)
- {
- static const auto& map = traits_type::get_string_to_enum_map();
- auto it = map.find(str);
- if (it != map.end())
- {
- value = it->second;
- return true;
- }
- if (!accept_numeric_value)
- return false;
- char *e = nullptr;
- const char *c = str.c_str();
- value = static_cast<enum_type>(std::strtoull(c, &e, 0));
- return (c != e);
- }
-
- template<typename T_enum, typename T_traits>
- T_enum enum_conversion<T_enum, T_traits>
- ::to_enum(const std::string& str, bool accept_numeric_value)
- {
- using namespace ::std;
- enum_type value;
- if (!try_to_enum(str, value, accept_numeric_value))
- throw convert_exception("unable to convert '"s + str + "' to '"s + type_helper<enum_type>::name() + "'"s);
- return value;
- }
-
- template<typename T_enum, typename T_traits>
- T_enum enum_conversion<T_enum, T_traits>
- ::to_enum_default(const std::string& str, enum_type default_value, bool accept_numeric_value)
- {
- enum_type value;
- return try_to_enum(str, value, accept_numeric_value)
- ? value
- : default_value;
- }
-
- }
|