#ifndef __UT_ANY_HPP__ #define __UT_ANY_HPP__ #include namespace unitree { namespace common { class Any { public: Any() : mContent(0) {} template Any(const ValueType& value) : mContent(new Holder(value)) {} Any(const char* s) : Any(std::string(s)) {} Any(const char* s, size_t len) : Any(std::string(s, len)) {} Any(const Any& other) : mContent(other.mContent ? other.mContent->Clone() : 0) {} ~Any() { delete mContent; mContent = 0; } Any& Swap(Any& other) { std::swap(mContent, other.mContent); return *this; } bool Empty() const { return mContent == 0; } const std::type_info& GetTypeInfo() const { return mContent ? mContent->GetTypeInfo() : typeid(void); } template Any& operator=(const ValueType& other) { Any(other).Swap(*this); return *this; } Any& operator=(Any other) { other.Swap(*this); return *this; } public: class PlaceHolder { public: virtual ~PlaceHolder() {} public: virtual const std::type_info& GetTypeInfo() const = 0; virtual PlaceHolder* Clone() const = 0; }; template class Holder : public PlaceHolder { public: explicit Holder(const ValueType& value) : mValue(value) {} virtual const std::type_info& GetTypeInfo() const { return typeid(ValueType); } virtual PlaceHolder* Clone() const { return new Holder(mValue); } public: ValueType mValue; }; public: PlaceHolder* mContent; }; /* * static const Any */ static const Any UT_EMPTY_ANY = Any(); static inline bool IsBool(const Any& any) { return any.GetTypeInfo() == typeid(bool); } static inline bool IsString(const Any& any) { return any.GetTypeInfo() == typeid(std::string); } static inline bool IsInt8(const Any& any) { return any.GetTypeInfo() == typeid(int8_t); } static inline bool IsUint8(const Any& any) { return any.GetTypeInfo() == typeid(uint8_t); } static inline bool IsInt16(const Any& any) { return any.GetTypeInfo() == typeid(int16_t); } static inline bool IsUint16(const Any& any) { return any.GetTypeInfo() == typeid(uint16_t); } static inline bool IsInt(const Any& any) { return any.GetTypeInfo() == typeid(int32_t); } static inline bool IsUint(const Any& any) { return any.GetTypeInfo() == typeid(uint32_t); } static inline bool IsInt64(const Any& any) { return any.GetTypeInfo() == typeid(int64_t); } static inline bool IsUint64(const Any& any) { return any.GetTypeInfo() == typeid(uint64_t); } static inline bool IsFloat(const Any& any) { return any.GetTypeInfo() == typeid(float); } static inline bool IsDouble(const Any& any) { return any.GetTypeInfo() == typeid(double); } static inline bool IsLongDouble(const Any& any) { return any.GetTypeInfo() == typeid(long double); } static inline bool IsInteger(const Any& any) { return IsInt(any) || IsUint(any) || IsInt64(any) || IsUint64(any) || IsInt16(any) || IsUint16(any) || IsInt8(any) || IsUint8(any); } static inline bool IsNumber(const Any& any) { return IsBool(any) || IsInteger(any) || IsFloat(any) || IsDouble(any) || IsLongDouble(any); } static inline bool IsBoolType(const std::type_info& t) { return t == typeid(bool); } static inline bool IsInt8Type(const std::type_info& t) { return t == typeid(int8_t); } static inline bool IsUint8Type(const std::type_info& t) { return t == typeid(uint8_t); } static inline bool IsInt16Type(const std::type_info& t) { return t == typeid(int16_t); } static inline bool IsUint16Type(const std::type_info& t) { return t == typeid(uint16_t); } static inline bool IsIntType(const std::type_info& t) { return t == typeid(int32_t); } static inline bool IsUintType(const std::type_info& t) { return t == typeid(uint32_t); } static inline bool IsInt64Type(const std::type_info& t) { return t == typeid(int64_t); } static inline bool IsUint64Type(const std::type_info& t) { return t == typeid(uint64_t); } static inline bool IsIntegerType(const std::type_info& t) { return IsIntType(t) || IsUintType(t) || IsInt64Type(t) || IsUint64Type(t) || IsInt8Type(t) || IsUint8Type(t) || IsInt16Type(t) || IsUint16Type(t); } static inline bool IsFloatType(const std::type_info& t) { return t == typeid(float); } static inline bool IsDoubleType(const std::type_info& t) { return t == typeid(double); } static inline bool IsLongDoubleType(const std::type_info& t) { return t == typeid(long double); } static inline bool IsNumberType(const std::type_info& t) { return IsBoolType(t) || IsIntegerType(t) || IsFloatType(t) || IsDoubleType(t) || IsLongDoubleType(t); } static inline bool IsTypeEqual(const std::type_info& t1, const std::type_info& t2) { return t1 == t2; } template const ValueType& AnyCast(const Any* operand) { const std::type_info& t1 = typeid(ValueType); const std::type_info& t2 = operand->GetTypeInfo(); if (IsTypeEqual(t1, t2)) { return ((Any::Holder*)(operand->mContent))->mValue; } UT_THROW(BadCastException, std::string("AnyCast error. target type is ") + t1.name() + ", but source type is " + t2.name()); } template const ValueType& AnyCast(const Any& operand) { return AnyCast(&operand); } template ValueType AnyNumberCast(const Any* operand) { const std::type_info& t1 = typeid(ValueType); const std::type_info& t2 = operand->GetTypeInfo(); if (IsNumberType(t1) && IsNumberType(t2)) { if (IsTypeEqual(t1, t2)) { return ((Any::Holder*)(operand->mContent))->mValue; } else if (IsFloatType(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsDoubleType(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsLongDoubleType(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsInt8Type(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsUint8Type(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsInt16Type(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsUint16Type(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsIntType(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsUintType(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsInt64Type(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else if (IsUint64Type(t2)) { return (ValueType)((Any::Holder*)(operand->mContent))->mValue; } else { UT_THROW(BadCastException, std::string("AnyNumberCast error. unknown number type:", t2.name())); } } UT_THROW(BadCastException, std::string("AnyNumberCast error. not number type")); } template ValueType AnyNumberCast(const Any& operand) { return AnyNumberCast(&operand); } static inline const std::string& ToString(const Any& operand) { if (operand.Empty()) { return UT_EMPTY_STR; } return AnyCast(operand); } static inline void StringTo(const std::string& s, Any& value) { value = s; } static inline void StringTo(const char* s, Any& value) { value = std::string(s); } static inline void StringTo(const char* s, size_t len, Any& value) { value = std::string(s, len); } static inline void StringTo(const char* s, size_t pos, size_t len, Any& value) { value = std::string(s, pos, len); } } } #endif//__UT_ANY_HPP__