Go2Py/deploy/dds_bridge/include/unitree/common/any.hpp

391 lines
8.4 KiB
C++

#ifndef __UT_ANY_HPP__
#define __UT_ANY_HPP__
#include <unitree/common/exception.hpp>
namespace unitree
{
namespace common
{
class Any
{
public:
Any()
: mContent(0)
{}
template<typename ValueType>
Any(const ValueType& value)
: mContent(new Holder<ValueType>(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<typename ValueType>
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<typename ValueType>
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<typename ValueType>
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<ValueType>*)(operand->mContent))->mValue;
}
UT_THROW(BadCastException, std::string("AnyCast error. target type is ")
+ t1.name() + ", but source type is " + t2.name());
}
template<typename ValueType>
const ValueType& AnyCast(const Any& operand)
{
return AnyCast<ValueType>(&operand);
}
template<typename ValueType>
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<ValueType>*)(operand->mContent))->mValue;
}
else if (IsFloatType(t2))
{
return (ValueType)((Any::Holder<float>*)(operand->mContent))->mValue;
}
else if (IsDoubleType(t2))
{
return (ValueType)((Any::Holder<double>*)(operand->mContent))->mValue;
}
else if (IsLongDoubleType(t2))
{
return (ValueType)((Any::Holder<long double>*)(operand->mContent))->mValue;
}
else if (IsInt8Type(t2))
{
return (ValueType)((Any::Holder<int8_t>*)(operand->mContent))->mValue;
}
else if (IsUint8Type(t2))
{
return (ValueType)((Any::Holder<uint8_t>*)(operand->mContent))->mValue;
}
else if (IsInt16Type(t2))
{
return (ValueType)((Any::Holder<int16_t>*)(operand->mContent))->mValue;
}
else if (IsUint16Type(t2))
{
return (ValueType)((Any::Holder<uint16_t>*)(operand->mContent))->mValue;
}
else if (IsIntType(t2))
{
return (ValueType)((Any::Holder<int32_t>*)(operand->mContent))->mValue;
}
else if (IsUintType(t2))
{
return (ValueType)((Any::Holder<uint32_t>*)(operand->mContent))->mValue;
}
else if (IsInt64Type(t2))
{
return (ValueType)((Any::Holder<int64_t>*)(operand->mContent))->mValue;
}
else if (IsUint64Type(t2))
{
return (ValueType)((Any::Holder<uint64_t>*)(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<typename ValueType>
ValueType AnyNumberCast(const Any& operand)
{
return AnyNumberCast<ValueType>(&operand);
}
static inline const std::string& ToString(const Any& operand)
{
if (operand.Empty())
{
return UT_EMPTY_STR;
}
return AnyCast<std::string>(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__