软件架构设计之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;
};


需要注意的地方是,在提取所存值之前必须提供值类型。

 

 

posted @ 2013-03-24 20:20  xinyuyuanm  阅读(362)  评论(0编辑  收藏  举报