支持在枚举编码与字符串形式间转换的c++的枚举模板类(c++17)

工作中经常遇到在枚举编码与字符串形式转换的需求,写一个模板类来实现该功能。

理想情况下,字符串的类型最好自动推导,但尝试用auto function() ->decltype()的方法实现总是提示语法错误无法编译,留待将来解决,现暂用模板参数实现。

  1 #ifndef DEFINITIONWRAP_H
  2 #define DEFINITIONWRAP_H
  3 
  4 #include <string>
  5 #include <vector>
  6 #include <map>
  7 #include <optional>
  8 #include <algorithm>
  9 #include <cassert>
 10 
 11 namespace Framework::Core{
 12 //The template class is used to wrap a enumeration class to help it convert between characters and encoding forms.
 13 //You can define the enumeration class as a struct or class forms, but it must be conform the following conditions:
 14 //The enumeration class must be has a static map class member variable named codeStrings to store the mapping relationship of coding to the string.
 15 //The enumeration class example:
 16 /*
 17 //define:
 18 struct ExampleDefiniation
 19 {
 20     enum Code{
 21         Code1
 22         , Code2
 23     };
 24 
 25     static const std::map<Code, std::wstring> codeStrings;
 26 };
 27 
 28 const std::map<Code, std::wstring> Example::codeStrings{
 29     {Exmaple::Code1, L"CodeString1"}
 30     ,{Example::Code2, L"CodeString2"}
 31 };
 32 using Example = DefinitionWrap<ExampleDefinition, ExampleDefiniation::Code1>;
 33 
 34 //using
 35 auto code1{L"CodeString1"};
 36 auto code2{Example::Definition::Code2};
 37 Exmaple::Definition code1Val{code1};
 38 std::wstring codeStr2{code2};
 39 */
 40 template <typename T, typename T::Code defCode, typename StringType=std::wstring>
 41 class DefinitionWrap
 42 {
 43 public:
 44     using Definition = typename T::Code;
 45 
 46     static std::optional<StringType> toString(const Definition& code) {
 47         const auto it{ T::codeStrings.find(code) };
 48         if (it != T::codeStrings.cend()) {
 49             return it->second;
 50         }
 51         return {};
 52     }
 53 
 54     static std::optional<Definition> toCode(const StringType& str) {
 55         const auto it = std::find_if(T::codeStrings.cbegin(), T::codeStrings.cend(), [str](auto &val) {return val.second == str;});
 56         if (it != T::codeStrings.cend()) {
 57             return it->first;
 58         }
 59         return {};
 60     }
 61     static std::vector<StringType> getDefinitionStrings(void) {
 62         std::vector<StringType> strings;
 63         std::for_each(T::codeStrings.cbegin(), T::codeStrings.cend(), [&](const auto &item){strings.emplace_back(item.second);});
 64         return strings;
 65     }
 66     static std::vector<Definition> getDefinitionCodes(void){
 67         std::vector<Definition> codes;
 68         std::for_each(T::codeStrings.cbegin(), T::codeStrings.cend(), [&](const auto &item){codes.emplace_back(item.first);});
 69         return codes;
 70     }
 71     static bool isValidDefinitionCode(const int code){
 72         auto codes{getDefinitionCodes()};
 73         return std::find_if(codes.begin(), codes.end(), [code](auto i){return static_cast<int>(i)==code;})!=codes.end();
 74     }
 75     static bool isValidDefinitionString(const StringType str){
 76         return static_cast<bool>(toCode(str));
 77     }
 78 
 79     explicit DefinitionWrap(const int& code) {
 80         operator=(code);
 81     }
 82     DefinitionWrap(const Definition& code = defCode) : codeValue(code) {}
 83     DefinitionWrap(const StringType& str) {
 84         operator=(str);
 85     }
 86     DefinitionWrap(const DefinitionWrap& ins) : codeValue(ins.codeValue) {}
 87 
 88     bool operator ==(const DefinitionWrap& ins) const {
 89         return codeValue == ins.codeValue;
 90     }
 91     bool operator ==(const Definition& code) const {
 92         return codeValue == code;
 93     }
 94     bool operator !=(const DefinitionWrap& ins) const {
 95         return codeValue != ins.codeValue;
 96     }
 97     bool operator !=(const Definition& code) const {
 98         return codeValue != code;
 99     }
100     bool operator <(const DefinitionWrap& ins) const {
101         return codeValue<ins.codeValue;
102     }
103 
104     DefinitionWrap &operator=(const Definition& code) {
105         codeValue = code;
106         return *this;
107     }
108     DefinitionWrap &operator=(const StringType &str) {
109         codeValue = toCode(str);
110         assert(codeValue);
111         return *this;
112     }
113     DefinitionWrap &operator=(const int value) {
114         if (isValidDefinitionCode(value))
115         {
116             codeValue = static_cast<Definition>(value);
117         }
118         else
119         {
120             assert(false);
121             codeValue.reset();
122         }
123         return *this;
124     }
125 
126     operator StringType() const {
127         assert(codeValue);
128         return toString(*codeValue).value();
129     }
130     operator Definition() const {
131         assert(codeValue);
132         return codeValue.value();
133     }
134 
135 protected:
136     std::optional<Definition> codeValue{ defCode };
137 };
138 
139 //template <typename T, typename StringType>
140 //decltype(DefinitionWrap::DefinitionStrings) DefinitionWrap<T, StringType>::DefinitionStrings{ T::codeStrings };
141 }
142 
143 #endif // DEFINITIONWRAP_H

 

转载于:https://www.cnblogs.com/thinkway/p/6773382.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值