分享一个类似于Qt中QVariant类。
目录:
1 类型定义
2 数值操作
3 万能类型包装
4 使用
——————————————————Begain——————————————————
类型定义
typedef.h
#ifndef TYPEDEF_H
#define TYPEDEF_H
#include <stdint.h>
#include <set>
using namespace std;
enum class VariantType : uint16_t
{
vt_empty = 0, //!< 类型为定义
vt_bool = 1, //!< bool类型
vt_i4 = 2, //!< int32_t 类型
vt_ui4 = 3, //!< uint32_t 类型
vt_i8 = 4, //!< int64_t 类型
vt_ui8 = 5, //!< uint64_t 类型
vt_r4 = 6, //!< float 类型
vt_r8 = 7, //!< double 类型
vt_bstr = 8, //!< const char* 类型
vt_set = 0x1000, //!< 集合类型,该类型的值需要用过特定函数获取,不能直接通过成员变量获取
};
struct VariantValue
{
uint16_t m_vt; //!< 值得类型,取值参看枚举VariantType,其中vt_set可以与其他值联合使用
union
{
bool m_bVal;
int32_t m_i4Val;
uint32_t m_ui4Val;
int64_t m_i8Val;
uint64_t m_ui8Val;
float m_r4Val;
double m_r8Val;
char* m_strVal;
void* m_pSetVal;
};
};
template<typename T>
void VariantSetValueDelete(set<T> *pSetValue)
{
if (pSetValue)
{
delete pSetValue;
pSetValue = nullptr;
}
}
template<typename T>
void VariantSetValueCopy(VariantValue &toValue, const set<T> *pFromValue)
{
if (nullptr == pFromValue)
return;
toValue.m_pSetVal = new set<T>(*pFromValue);
}
template<typename T>
uint32_t VariantSetValueSize(set<T> *pSetValue)
{
return pSetValue ? static_cast<uint32_t>(pSetValue->size()) : 0;
}
template<typename T>
bool VariantSetValueAt(set<T> *pSetValue, uint32_t uIndex, T &subValue)
{
if (nullptr == pSetValue)
return false;
auto it = pSetValue->begin();
advance(it, uIndex);
if (it == pSetValue->end())
return false;
subValue = *it;
return true;
}
template<typename T>
bool VariantSetValueAdd(set<T> *pSetValue, T value)
{
if (nullptr == pSetValue)
return false;
auto it = pSetValue->find(value);
if (it == pSetValue->end())
return false;
pSetValue->insert(value);
return true;
}
template<typename T>
bool VariantSetValueRemove(set<T> *pSetValue, T value)
{
if (nullptr == pSetValue)
return false;
auto it = pSetValue->find(value);
if (it == pSetValue->end())
return false;
pSetValue->erase(it);
return true;
}
#endif // TYPEDEF_H
数值操作
valueopt.h
#ifndef VALUEOPT_H
#define VALUEOPT_H
#include "typedef.h"
#include <stdint.h>
void VariantValueInit(VariantValue &value);
void VariantValueClear(VariantValue &value);
void VariantValueCopy(VariantValue &toValue, const VariantValue &from);
uint32_t VariantValueSetSize(const VariantValue &valueSet);
bool VariantValueSetAt(const VariantValue &valueSet, uint32_t uIndex, VariantValue &value);
bool VariantValueSetAdd(VariantValue &valueSet, const VariantValue &value);
#endif // VALUEOPT_H
valueopt.cpp
#include <iostream>
#include "valueopt.h"
#include <string.h>
#include <valueopt.h>
using namespace std;
void VariantValueInit(VariantValue &value)
{
memset(&value, 0, sizeof(value));
value.m_vt = (uint16_t)VariantType::vt_empty;
value.m_pSetVal = nullptr;
}
void VariantValueClear(VariantValue &value)
{
if (value.m_vt & (uint16_t)VariantType::vt_set)
{
uint16_t uType = (uint16_t)value.m_vt & 0xff;
switch ((VariantType)uType)
{
case VariantType::vt_bool:
VariantSetValueDelete(reinterpret_cast<set<bool> *>(value.m_pSetVal));
break;
case VariantType::vt_i4:
VariantSetValueDelete(reinterpret_cast<set<int32_t> *>(value.m_pSetVal));
break;
case VariantType::vt_ui4:
VariantSetValueDelete(reinterpret_cast<set<uint32_t> *>(value.m_pSetVal));
break;
case VariantType::vt_i8:
VariantSetValueDelete(reinterpret_cast<set<int64_t> *>(value.m_pSetVal));
break;
case VariantType::vt_ui8:
VariantSetValueDelete(reinterpret_cast<set<uint64_t> *>(value.m_pSetVal));
break;
case VariantType::vt_r4:
VariantSetValueDelete(reinterpret_cast<set<float> *>(value.m_pSetVal));
break;
case VariantType::vt_r8:
VariantSetValueDelete(reinterpret_cast<set<double> *>(value.m_pSetVal));
break;
case VariantType::vt_bstr:
VariantSetValueDelete(reinterpret_cast<set<string> *>(value.m_pSetVal));
break;
default:
break;
}
}
else
{
if (((uint16_t)VariantType::vt_bstr == value.m_vt) && value.m_strVal)
delete[]value.m_strVal;
}
memset(&value, 0, sizeof(value));
value.m_vt = (uint16_t)VariantType::vt_empty;
}
void VariantValueCopy(VariantValue &toValue, const VariantValue &from)
{
VariantValueClear(toValue);
if (from.m_vt & (uint16_t)VariantType::vt_set)
{
uint16_t uType = (uint16_t)from.m_vt & 0xff;
switch ((VariantType)uType)
{
case VariantType::vt_bool:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<bool> *>(from.m_pSetVal));
break;
case VariantType::vt_i4:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<int32_t> *>(from.m_pSetVal));
break;
case VariantType::vt_ui4:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<uint32_t> *>(from.m_pSetVal));
break;
case VariantType::vt_i8:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<int64_t> *>(from.m_pSetVal));
break;
case VariantType::vt_ui8:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<uint64_t> *>(from.m_pSetVal));
break;
case VariantType::vt_r4:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<float> *>(from.m_pSetVal));
break;
case VariantType::vt_r8:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<double> *>(from.m_pSetVal));
break;
case VariantType::vt_bstr:
toValue.m_vt = from.m_vt;
VariantSetValueCopy(toValue, reinterpret_cast<set<string> *>(from.m_pSetVal));
break;
default:
break;
}
}
else
{
if ((uint16_t)VariantType::vt_bstr == from.m_vt)
{
toValue.m_vt = from.m_vt;
if (nullptr != from.m_strVal)
{
uint32_t uLen = strlen(from.m_strVal);
toValue.m_strVal = new char[uLen + 1];
memcpy(toValue.m_strVal, from.m_strVal, uLen);
toValue.m_strVal[uLen] = '