软件架构设计之Utility模块——Any
YKAny类用于保存任意类型的变量类似于variant_t。这里采用的是boost库中的Any实现原理,增加了两个Any之间比较的功能。看代码吧:
class UTIL_API YKAny
{
class PlaceHolder
{
public:
PlaceHolder() {}
virtual ~PlaceHolder() {}
virtual const std::type_info& type() const = 0;
virtual PlaceHolder* Clone() const = 0;
virtual YK_BOOL operator== (PlaceHolder* pHolder) = 0;
virtual YK_BOOL operator!= (PlaceHolder* pHolder) = 0;
virtual YK_BOOL operator< (PlaceHolder* pHolder) = 0;
virtual YK_BOOL operator> (PlaceHolder* pHolder) = 0;
virtual YK_BOOL operator<= (PlaceHolder* pHolder) = 0;
virtual YK_BOOL operator>= (PlaceHolder* pHolder) = 0;
};
template <typename T>
class Holder : public PlaceHolder
{
typedef T value_type;
public:
Holder(value_type value)
: m_value(value)
{}
virtual const std::type_info& type() const {
return typeid(value_type);
}
virtual PlaceHolder* Clone() const {
return new Holder(m_value);
}
virtual YK_BOOL operator== (PlaceHolder* pHolder) {
Holder* pRhs = dynamic_cast<Holder*>(pHolder);
assert(pRhs);
return m_value == pRhs->m_value;
}
virtual YK_BOOL operator!= (PlaceHolder* pHolder)
{ return !(*this == pHolder); }
virtual YK_BOOL operator< (PlaceHolder* pHolder) {
Holder* pRhs = dynamic_cast<Holder*>(pHolder);
assert(pRhs);
return m_value < pRhs->m_value;
}
virtual YK_BOOL operator> (PlaceHolder* pHolder) {
Holder* pRhs = dynamic_cast<Holder*>(pHolder);
assert(pRhs);
return m_value > pRhs->m_value;
}
virtual YK_BOOL operator<= (PlaceHolder* pHolder)
{ return !(*this > pHolder); }
virtual YK_BOOL operator>= (PlaceHolder* pHolder)
{ return !(*this < pHolder); }
value_type m_value;
};
public:
YKAny(void) : m_pValue(YK_NULL) {}
template <typename T>
YKAny(T value)
: m_pValue(new Holder<T>(value))
{}
YKAny(const YKAny& rhs)
: m_pValue(rhs.m_pValue ? rhs.m_pValue->Clone() : YK_NULL)
{}
~YKAny(void) { delete m_pValue; }
template <typename T>
YKAny& operator=(typename YKTypeTraits<T>::ParmType value) {
YKAny(value).Swap(*this);
return *this;
}
YKAny& operator=(const YKAny& rhs)
{ YKAny(rhs).Swap(*this); return *this; }
YKAny& Swap(YKAny& rhs)
{ std::swap(m_pValue, rhs.m_pValue); return *this; }
YK_BOOL Empty() const { return m_pValue == YK_NULL; }
const std::type_info& type() const
{ return m_pValue ? m_pValue->type() : typeid(void); }
// 提取所存值前必须提供值类型
template <typename T>
T& Cast() {
if (type() != typeid(T))
{
std::string str = "Failed to convert the value of YKAny to ";
str += typeid(T).name();
throw YKException(str, YKException::Exc_BadCast);
}
return static_cast<Holder<T>*>(m_pValue)->m_value;
}
YK_BOOL operator== (const YKAny& rhs) {
assert(m_pValue && type() == rhs.type());
return m_pValue->operator==(rhs.m_pValue);
}
YK_BOOL operator!= (const YKAny& rhs) {
assert(m_pValue && type() == rhs.type());
return m_pValue->operator!=(rhs.m_pValue);
}
YK_BOOL operator< (const YKAny& rhs) {
assert(m_pValue && type() == rhs.type());
return m_pValue->operator<(rhs.m_pValue);
}
YK_BOOL operator> (const YKAny& rhs) {
assert(m_pValue && type() == rhs.type());
return m_pValue->operator>(rhs.m_pValue);
}
YK_BOOL operator<= (const YKAny& rhs) {
assert(m_pValue && type() == rhs.type());
return m_pValue->operator<=(rhs.m_pValue);
}
YK_BOOL operator>= (const YKAny& rhs) {
assert(m_pValue && type() == rhs.type());
return m_pValue->operator>=(rhs.m_pValue);
}
private:
PlaceHolder* m_pValue;
};
需要注意的地方是,在提取所存值之前必须提供值类型。