Arithmetic operators for DynamicAny

This commit is contained in:
Aleksandar Fabijanic 2007-09-05 23:38:12 +00:00
parent 0a65eefd9a
commit d9c5b827a5
6 changed files with 1072 additions and 46 deletions

View File

@ -71,6 +71,16 @@ class Foundation_API DynamicAny
/// Integer 0 values are false, everything else is true. /// Integer 0 values are false, everything else is true.
/// Floating point values equal to the minimal FP representation on a given platform are false, everything else is true. /// Floating point values equal to the minimal FP representation on a given platform are false, everything else is true.
/// ///
/// Arithmetic operations with POD types as well as between DynamicAny's are supported, subject to following
/// limitations:
///
/// - for std::string and const char* values, only '+' and '+=' operations are supported
///
/// - for integral and floating point numeric values, following operations are supported:
/// '+', '+=', '-', '-=', '*', '*=' , '/' and '/='
///
/// - for all other types, InvalidArgumentException is thrown upon attempt of an arithmetic operation
///
/// A DynamicAny can be created from and converted to a value of any type for which a specialization of /// A DynamicAny can be created from and converted to a value of any type for which a specialization of
/// DynamicAnyHolderImpl is available. For supported types, see DynamicAnyHolder documentation. /// DynamicAnyHolderImpl is available. For supported types, see DynamicAnyHolder documentation.
{ {
@ -133,7 +143,7 @@ public:
} }
template <typename T> template <typename T>
operator T() const operator T () const
/// Safe conversion operator for implicit type /// Safe conversion operator for implicit type
/// conversions. /// conversions.
/// ///
@ -146,7 +156,7 @@ public:
_pHolder->convert(result); _pHolder->convert(result);
return result; return result;
} }
template <typename T> template <typename T>
const T& extract() const const T& extract() const
/// Returns a const reference to the actual value. /// Returns a const reference to the actual value.
@ -162,14 +172,6 @@ public:
throw BadCastException(); throw BadCastException();
} }
DynamicAny& operator = (const DynamicAny& other)
/// Assignment operator
{
DynamicAny tmp(other);
swap(tmp);
return *this;
}
template <typename T> template <typename T>
DynamicAny& operator = (const T& other) DynamicAny& operator = (const T& other)
/// Assignment operator /// Assignment operator
@ -179,39 +181,114 @@ public:
return *this; return *this;
} }
DynamicAny& operator = (const DynamicAny& other);
/// Assignment operator specialization for DynamicAny
template <typename T>
DynamicAny operator + (const T& other) const
/// Addition operator
{
return convert<T>() + other;
}
DynamicAny operator + (const DynamicAny& other) const;
/// Addition operator specialization for DynamicAny
DynamicAny operator + (const char* other) const;
/// Addition operator specialization for const char*
template <typename T>
DynamicAny& operator += (const T& other)
/// Addition asignment operator
{
return *this = convert<T>() + other;
}
DynamicAny& operator += (const DynamicAny& other);
/// Addition asignment operator specialization for DynamicAny
DynamicAny& operator += (const char* other);
/// Addition asignment operator specialization for const char*
template <typename T>
DynamicAny operator - (const T& other) const
/// Subtraction operator
{
return convert<T>() - other;
}
DynamicAny operator - (const DynamicAny& other) const;
/// Subtraction operator specialization for DynamicAny
template <typename T>
DynamicAny& operator -= (const T& other)
/// Subtraction asignment operator
{
return *this = convert<T>() - other;
}
DynamicAny& operator -= (const DynamicAny& other);
/// Subtraction asignment specialization operator for DynamicAny
template <typename T>
DynamicAny operator * (const T& other) const
/// Multiplication operator
{
return convert<T>() * other;
}
DynamicAny operator * (const DynamicAny& other) const;
/// Multiplication operator specialization for DynamicAny
template <typename T>
DynamicAny& operator *= (const T& other)
/// Multiplication asignment operator
{
return *this = convert<T>() * other;
}
DynamicAny& operator *= (const DynamicAny& other);
/// Multiplication asignment operator specialization for DynamicAny
template <typename T>
DynamicAny operator / (const T& other) const
/// Division operator
{
return convert<T>() / other;
}
DynamicAny operator / (const DynamicAny& other) const;
/// Division operator specialization for DynamicAny
template <typename T>
DynamicAny& operator /= (const T& other)
/// Division asignment operator
{
return *this = convert<T>() / other;
}
DynamicAny& operator /= (const DynamicAny& other);
/// Division asignment operator specialization for DynamicAny
template <typename T> template <typename T>
bool operator == (const T& other) const bool operator == (const T& other) const
/// Equality operator /// Equality operator
{ {
T value; return convert<T>() == other;
_pHolder->convert(value);
return value == other;
} }
bool operator == (const char* other) const bool operator == (const char* other) const;
/// Equality operator /// Equality operator specialization for const char*
{
std::string value;
_pHolder->convert(value);
return value == other;
}
template <typename T> template <typename T>
bool operator != (const T& other) const bool operator != (const T& other) const
/// Inequality operator /// Inequality operator
{ {
T value; return convert<T>() != other;
_pHolder->convert(value);
return value != other;
} }
bool operator != (const char* other) const bool operator != (const char* other) const;
/// Inequality operator /// Inequality operator specialization for const char*
{
std::string value;
_pHolder->convert(value);
return value != other;
}
bool isArray() const; bool isArray() const;
/// Returns true if DynamicAny represents a vector /// Returns true if DynamicAny represents a vector
@ -219,25 +296,38 @@ public:
bool isStruct() const; bool isStruct() const;
/// Returns true if DynamicAny represents a struct /// Returns true if DynamicAny represents a struct
DynamicAny& operator[](std::vector<DynamicAny>::size_type n); DynamicAny& operator [] (std::vector<DynamicAny>::size_type n);
/// Index operator, only use on DynamicAnys where isArray /// Index operator, only use on DynamicAnys where isArray
/// returns true! In all other cases a BadCastException is thrown! /// returns true! In all other cases a BadCastException is thrown!
const DynamicAny& operator[](std::vector<DynamicAny>::size_type n) const; const DynamicAny& operator [] (std::vector<DynamicAny>::size_type n) const;
/// const Index operator, only use on DynamicAnys where isArray /// const Index operator, only use on DynamicAnys where isArray
/// returns true! In all other cases a BadCastException is thrown! /// returns true! In all other cases a BadCastException is thrown!
DynamicAny& operator[](const std::string& name); DynamicAny& operator [] (const std::string& name);
/// Index operator by name, only use on DynamicAnys where isStruct /// Index operator by name, only use on DynamicAnys where isStruct
/// returns true! In all other cases a BadCastException is thrown! /// returns true! In all other cases a BadCastException is thrown!
const DynamicAny& operator[](const std::string& name) const; const DynamicAny& operator [] (const std::string& name) const;
/// Index operator by name, only use on DynamicAnys where isStruct /// Index operator by name, only use on DynamicAnys where isStruct
/// returns true! In all other cases a BadCastException is thrown! /// returns true! In all other cases a BadCastException is thrown!
const std::type_info& type() const; const std::type_info& type() const;
/// Returns the type information of the stored content. /// Returns the type information of the stored content.
bool isInteger() const;
/// Returns true if stored value is integer.
bool isSigned() const;
/// Returns true if stored value is signed.
bool isNumeric() const;
/// Returns true if stored value is numeric.
/// Returns false for numeric strings (e.g. "123" is string, not number)
bool isString() const;
/// Returns true if stored value is std::string.
static DynamicAny parse(const std::string& val); static DynamicAny parse(const std::string& val);
/// Parses the string which must be in JSON format /// Parses the string which must be in JSON format
@ -253,11 +343,71 @@ private:
static DynamicAny parseArray(const std::string& val, std::string::size_type& pos); static DynamicAny parseArray(const std::string& val, std::string::size_type& pos);
static std::string parseString(const std::string& val, std::string::size_type& pos); static std::string parseString(const std::string& val, std::string::size_type& pos);
static void skipWhiteSpace(const std::string& val, std::string::size_type& pos); static void skipWhiteSpace(const std::string& val, std::string::size_type& pos);
private:
template <typename T>
T add(const DynamicAny& other) const
{
return convert<T>() + other.convert<T>();
}
template <typename T>
T subtract(const DynamicAny& other) const
{
return convert<T>() - other.convert<T>();
}
template <typename T>
T multiply(const DynamicAny& other) const
{
return convert<T>() * other.convert<T>();
}
template <typename T>
T divide(const DynamicAny& other) const
{
return convert<T>() / other.convert<T>();
}
DynamicAnyHolder* _pHolder; DynamicAnyHolder* _pHolder;
}; };
inline void DynamicAny::swap(DynamicAny& ptr)
{
std::swap(_pHolder, ptr._pHolder);
}
inline const std::type_info& DynamicAny::type() const
{
return _pHolder->type();
}
inline DynamicAny DynamicAny::operator + (const char* other) const
{
return convert<std::string>() + other;
}
inline DynamicAny& DynamicAny::operator += (const char*other)
{
return *this = convert<std::string>() + other;
}
inline bool DynamicAny::operator == (const char* other) const
{
return convert<std::string>() == other;
}
inline bool DynamicAny::operator != (const char* other) const
{
return convert<std::string>() != other;
}
inline bool DynamicAny::isArray() const inline bool DynamicAny::isArray() const
{ {
return _pHolder->isArray(); return _pHolder->isArray();
@ -270,6 +420,30 @@ inline bool DynamicAny::isStruct() const
} }
inline bool DynamicAny::isInteger() const
{
return _pHolder->isInteger();
}
inline bool DynamicAny::isSigned() const
{
return _pHolder->isSigned();
}
inline bool DynamicAny::isNumeric() const
{
return _pHolder->isNumeric();
}
inline bool DynamicAny::isString() const
{
return _pHolder->isString();
}
} // namespace Poco } // namespace Poco

View File

@ -101,6 +101,10 @@ public:
virtual void convert(Timestamp& val) const = 0; virtual void convert(Timestamp& val) const = 0;
virtual bool isArray() const = 0; virtual bool isArray() const = 0;
virtual bool isStruct() const = 0; virtual bool isStruct() const = 0;
virtual bool isInteger() const = 0;
virtual bool isSigned() const = 0;
virtual bool isNumeric() const = 0;
virtual bool isString() const = 0;
#ifndef POCO_LONG_IS_64_BIT #ifndef POCO_LONG_IS_64_BIT
void convert(long& val) const; void convert(long& val) const;
@ -289,6 +293,26 @@ public:
return typeid(T); return typeid(T);
} }
bool isInteger() const
{
return std::numeric_limits<T>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<T>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<T>::is_specialized;
}
bool isString() const
{
return type() == typeid(std::string);
}
void convert(Int8&) const void convert(Int8&) const
{ {
throw NotImplementedException("No DynamicAnyHolder specialization for type", typeid(T).name()); throw NotImplementedException("No DynamicAnyHolder specialization for type", typeid(T).name());
@ -503,6 +527,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<Int8>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<Int8>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<Int8>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
Int8 _val; Int8 _val;
}; };
@ -627,6 +671,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<Int16>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<Int16>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<Int16>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
Int16 _val; Int16 _val;
}; };
@ -751,6 +815,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<Int32>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<Int32>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<Int32>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
Int32 _val; Int32 _val;
}; };
@ -875,6 +959,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<Int64>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<Int64>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<Int64>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
Int64 _val; Int64 _val;
}; };
@ -999,6 +1103,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<UInt8>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<UInt8>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<UInt8>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
UInt8 _val; UInt8 _val;
}; };
@ -1123,6 +1247,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<UInt16>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<UInt16>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<UInt16>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
UInt16 _val; UInt16 _val;
}; };
@ -1247,6 +1391,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<UInt32>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<UInt32>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<UInt32>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
UInt32 _val; UInt32 _val;
}; };
@ -1377,6 +1541,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<UInt64>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<UInt64>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<UInt64>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
UInt64 _val; UInt64 _val;
}; };
@ -1499,6 +1683,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<bool>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<bool>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<bool>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
bool _val; bool _val;
}; };
@ -1624,6 +1828,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<float>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<float>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<float>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
float _val; float _val;
}; };
@ -1755,6 +1979,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<double>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<double>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<double>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
double _val; double _val;
}; };
@ -1877,6 +2121,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<char>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<char>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<char>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
char _val; char _val;
}; };
@ -2029,6 +2293,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return true;
}
private: private:
std::string _val; std::string _val;
}; };
@ -2156,6 +2440,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<long>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<long>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<long>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
long _val; long _val;
}; };
@ -2280,6 +2584,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return std::numeric_limits<unsigned long>::is_integer;
}
bool isSigned() const
{
return std::numeric_limits<unsigned long>::is_signed;
}
bool isNumeric() const
{
return std::numeric_limits<unsigned long>::is_specialized;
}
bool isString() const
{
return false;
}
private: private:
unsigned long _val; unsigned long _val;
}; };
@ -2369,7 +2693,7 @@ public:
{ {
// Serialize in JSON format: note: although this a vector<T>, the code only // Serialize in JSON format: note: although this a vector<T>, the code only
// supports vector<DynamicAny>. We can't make this a total specialization, // supports vector<DynamicAny>. We can't make this a total specialization,
// because of an otherwise cyclic dependency between DynamicAny and DynamicAnyHolder // because of the cyclic dependency between DynamicAny and DynamicAnyHolder
// JSON format definition: [ n times: elem ',' ], no ',' for last elem // JSON format definition: [ n times: elem ',' ], no ',' for last elem
val.append("[ "); val.append("[ ");
@ -2424,6 +2748,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
T& operator[](typename std::vector<T>::size_type n) T& operator[](typename std::vector<T>::size_type n)
{ {
return _val.operator[](n); return _val.operator[](n);
@ -2556,6 +2900,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private: private:
DateTime _val; DateTime _val;
}; };
@ -2678,6 +3042,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private: private:
LocalDateTime _val; LocalDateTime _val;
}; };
@ -2800,6 +3184,26 @@ public:
return false; return false;
} }
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private: private:
Timestamp _val; Timestamp _val;
}; };

View File

@ -357,6 +357,26 @@ public:
return true; return true;
} }
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
DynamicAny& operator[](const std::string& name) DynamicAny& operator[](const std::string& name)
{ {
return _val.operator[](name); return _val.operator[](name);

View File

@ -69,19 +69,147 @@ DynamicAny::~DynamicAny()
} }
void DynamicAny::swap(DynamicAny& ptr) DynamicAny& DynamicAny::operator = (const DynamicAny& other)
{ {
std::swap(_pHolder, ptr._pHolder); DynamicAny tmp(other);
swap(tmp);
return *this;
} }
const std::type_info& DynamicAny::type() const DynamicAny DynamicAny::operator + (const DynamicAny& other) const
{ {
return _pHolder->type(); if (isInteger())
{
if(isSigned())
return add<Poco::Int64>(other);
else
return add<Poco::UInt64>(other);
}
else if (isNumeric())
return add<double>(other);
else if (isString())
return add<std::string>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
} }
DynamicAny& DynamicAny::operator[](std::vector<DynamicAny>::size_type n) DynamicAny& DynamicAny::operator += (const DynamicAny& other)
{
if (isInteger())
{
if(isSigned())
return *this = add<Poco::Int64>(other);
else
return *this = add<Poco::UInt64>(other);
}
else if (isNumeric())
return *this = add<double>(other);
else if (isString())
return *this = add<std::string>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
}
DynamicAny DynamicAny::operator - (const DynamicAny& other) const
{
if (isInteger())
{
if(isSigned())
return subtract<Poco::Int64>(other);
else
return subtract<Poco::UInt64>(other);
}
else if (isNumeric())
return subtract<double>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
}
DynamicAny& DynamicAny::operator -= (const DynamicAny& other)
{
if (isInteger())
{
if(isSigned())
return *this = subtract<Poco::Int64>(other);
else
return *this = subtract<Poco::UInt64>(other);
}
else if (isNumeric())
return *this = subtract<double>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
}
DynamicAny DynamicAny::operator * (const DynamicAny& other) const
{
if (isInteger())
{
if(isSigned())
return multiply<Poco::Int64>(other);
else
return multiply<Poco::UInt64>(other);
}
else if (isNumeric())
return multiply<double>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
}
DynamicAny& DynamicAny::operator *= (const DynamicAny& other)
{
if (isInteger())
{
if(isSigned())
return *this = multiply<Poco::Int64>(other);
else
return *this = multiply<Poco::UInt64>(other);
}
else if (isNumeric())
return *this = multiply<double>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
}
DynamicAny DynamicAny::operator / (const DynamicAny& other) const
{
if (isInteger())
{
if(isSigned())
return divide<Poco::Int64>(other);
else
return divide<Poco::UInt64>(other);
}
else if (isNumeric())
return divide<double>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
}
DynamicAny& DynamicAny::operator /= (const DynamicAny& other)
{
if (isInteger())
{
if(isSigned())
return *this = divide<Poco::Int64>(other);
else
return *this = divide<Poco::UInt64>(other);
}
else if (isNumeric())
return *this = divide<double>(other);
else
throw InvalidArgumentException("Invalid operation for this data type.");
}
DynamicAny& DynamicAny::operator [] (std::vector<DynamicAny>::size_type n)
{ {
DynamicAnyHolderImpl<std::vector<DynamicAny> >* pHolder = dynamic_cast<DynamicAnyHolderImpl<std::vector<DynamicAny> > *>(_pHolder); DynamicAnyHolderImpl<std::vector<DynamicAny> >* pHolder = dynamic_cast<DynamicAnyHolderImpl<std::vector<DynamicAny> > *>(_pHolder);
if (pHolder) if (pHolder)
@ -91,7 +219,7 @@ DynamicAny& DynamicAny::operator[](std::vector<DynamicAny>::size_type n)
} }
const DynamicAny& DynamicAny::operator[](std::vector<DynamicAny>::size_type n) const const DynamicAny& DynamicAny::operator [] (std::vector<DynamicAny>::size_type n) const
{ {
const DynamicAnyHolderImpl<std::vector<DynamicAny> >* pHolder = dynamic_cast<const DynamicAnyHolderImpl<std::vector<DynamicAny> > *>(_pHolder); const DynamicAnyHolderImpl<std::vector<DynamicAny> >* pHolder = dynamic_cast<const DynamicAnyHolderImpl<std::vector<DynamicAny> > *>(_pHolder);
if (pHolder) if (pHolder)
@ -101,8 +229,7 @@ const DynamicAny& DynamicAny::operator[](std::vector<DynamicAny>::size_type n) c
} }
DynamicAny& DynamicAny::operator [] (const std::string& name)
DynamicAny& DynamicAny::operator[](const std::string& name)
{ {
DynamicAnyHolderImpl<DynamicStruct>* pHolder = dynamic_cast<DynamicAnyHolderImpl<DynamicStruct> *>(_pHolder); DynamicAnyHolderImpl<DynamicStruct>* pHolder = dynamic_cast<DynamicAnyHolderImpl<DynamicStruct> *>(_pHolder);
if (pHolder) if (pHolder)
@ -112,7 +239,7 @@ DynamicAny& DynamicAny::operator[](const std::string& name)
} }
const DynamicAny& DynamicAny::operator[](const std::string& name) const const DynamicAny& DynamicAny::operator [] (const std::string& name) const
{ {
const DynamicAnyHolderImpl<DynamicStruct>* pHolder = dynamic_cast<const DynamicAnyHolderImpl<DynamicStruct>* >(_pHolder); const DynamicAnyHolderImpl<DynamicStruct>* pHolder = dynamic_cast<const DynamicAnyHolderImpl<DynamicStruct>* >(_pHolder);
if (pHolder) if (pHolder)

View File

@ -120,6 +120,23 @@ void DynamicAnyTest::testInt8()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -191,6 +208,23 @@ void DynamicAnyTest::testInt16()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -262,6 +296,23 @@ void DynamicAnyTest::testInt32()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -333,6 +384,23 @@ void DynamicAnyTest::testInt64()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -404,6 +472,23 @@ void DynamicAnyTest::testUInt8()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -475,6 +560,23 @@ void DynamicAnyTest::testUInt16()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -546,6 +648,23 @@ void DynamicAnyTest::testUInt32()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -617,6 +736,23 @@ void DynamicAnyTest::testUInt64()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -830,6 +966,23 @@ void DynamicAnyTest::testFloat()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1.0f;
assert (a3 == 33.0f);
a3 = a1 - 1.0f;
assert (a3 == 31.0f);
a3 += 1.0f;
assert (a3 == 32.0f);
a3 -= 1.0f;
assert (a3 == 31.0f);
a3 = a1 / 2.0f;
assert (a3 == 16.0f);
a3 = a1 * 2.0f;
assert (a3 == 64.0f);
a3 /= 2.0f;
assert (a3 == 32.0f);
a3 *= 2.0f;
assert (a3 == 64.0f);
} }
@ -901,6 +1054,24 @@ void DynamicAnyTest::testDouble()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1.0;
assert (a3 == 33.0);
a3 = a1 - 1.0;
assert (a3 == 31.0);
a3 += 1.0;
assert (a3 == 32.0);
a3 -= 1.0;
assert (a3 == 31.0);
a3 = a1 / 2.0;
assert (a3 == 16.0);
a3 = a1 * 2.0;
assert (a3 == 64.0);
a3 /= 2.0;
assert (a3 == 32.0);
a3 *= 2.0;
assert (a3 == 64.0);
} }
@ -967,6 +1138,17 @@ void DynamicAnyTest::testString()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a4(123);
std::string s("456");
DynamicAny a5 = a4 + s;
assert (a5 == "123456");
a4 += s;
assert (a4 == "123456");
DynamicAny a6 = a4 + "789";
assert (a6 == "123456789");
a4 += "789";
assert (a4 == "123456789");
} }
@ -1038,6 +1220,23 @@ void DynamicAnyTest::testLong()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -1109,6 +1308,23 @@ void DynamicAnyTest::testULong()
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
} }
DynamicAny a3 = a1 + 1;
assert (a3 == 33);
a3 = a1 - 1;
assert (a3 == 31);
a3 += 1;
assert (a3 == 32);
a3 -= 1;
assert (a3 == 31);
a3 = a1 / 2;
assert (a3 == 16);
a3 = a1 * 2;
assert (a3 == 64);
a3 /= 2;
assert (a3 == 32);
a3 *= 2;
assert (a3 == 64);
} }
@ -1119,7 +1335,7 @@ void DynamicAnyTest::testConversionOperator()
assert (i == 42); assert (i == 42);
any = 123; any = 123;
std::string s = any;//'s(any)' bombs on gcc 3.4.4 std::string s = any;
assert (s == "123"); assert (s == "123");
any = 321; any = 321;
@ -1128,6 +1344,89 @@ void DynamicAnyTest::testConversionOperator()
any = "456"; any = "456";
assert (any == "456"); assert (any == "456");
DynamicAny any2 = 52;
DynamicAny any3 = any + any2;
}
void DynamicAnyTest::testArithmeticOperators()
{
DynamicAny any1 = 1;
DynamicAny any2 = 2;
DynamicAny any3 = any1 + any2;
assert (any3 == 3);
any1 = 3;
any2 = 5;
any3 = any2 - any1;
assert (any3 == 2);
any3 -= 1;
assert (any3 == 1);
any1 = 3;
any2 = 5;
any3 = any1 * any2;
assert (any3 == 15);
any3 *= 3;
assert (any3 == 45);
any1 = 3;
any2 = 9;
any3 = any2 / any1;
assert (any3 == 3);
any3 /= 3;
assert (any3 == 1);
any1 = 1.0f;
any2 = .5f;
any3 = .0f;
any3 = any1 + any2;
assert (any3 == 1.5f);
any3 += .5f;
assert (any3 == 2.0f);
any1 = 1.0;
any2 = .5;
any3 = 0.0;
any3 = any1 + any2;
assert (any3 == 1.5);
any3 += .5;
assert (any3 == 2.0);
any1 = 1;
any2 = "2";
any3 = any1 + any2;
assert (any3 == 3);
any2 = "4";
any3 += any2;
assert (any3 == 7);
any1 = "123";
any2 = "456";
any3 = any1 + any2;
assert (any3 == "123456");
any2 = "789";
any3 += any2;
assert (any3 == "123456789");
try { any3 = any1 - any2; fail ("must fail"); }
catch (InvalidArgumentException&){}
try { any3 -= any2; fail ("must fail"); }
catch (InvalidArgumentException&){}
try { any3 = any1 * any2; fail ("must fail"); }
catch (InvalidArgumentException&){}
try { any3 *= any2; fail ("must fail"); }
catch (InvalidArgumentException&){}
try { any3 = any1 / any2; fail ("must fail"); }
catch (InvalidArgumentException&){}
try { any3 /= any2; fail ("must fail"); }
catch (InvalidArgumentException&){}
} }
@ -1779,6 +2078,7 @@ CppUnit::Test* DynamicAnyTest::suite()
CppUnit_addTest(pSuite, DynamicAnyTest, testLong); CppUnit_addTest(pSuite, DynamicAnyTest, testLong);
CppUnit_addTest(pSuite, DynamicAnyTest, testULong); CppUnit_addTest(pSuite, DynamicAnyTest, testULong);
CppUnit_addTest(pSuite, DynamicAnyTest, testConversionOperator); CppUnit_addTest(pSuite, DynamicAnyTest, testConversionOperator);
CppUnit_addTest(pSuite, DynamicAnyTest, testArithmeticOperators);
CppUnit_addTest(pSuite, DynamicAnyTest, testLimitsInt); CppUnit_addTest(pSuite, DynamicAnyTest, testLimitsInt);
CppUnit_addTest(pSuite, DynamicAnyTest, testLimitsFloat); CppUnit_addTest(pSuite, DynamicAnyTest, testLimitsFloat);
CppUnit_addTest(pSuite, DynamicAnyTest, testCtor); CppUnit_addTest(pSuite, DynamicAnyTest, testCtor);

View File

@ -63,6 +63,7 @@ public:
void testULong(); void testULong();
void testString(); void testString();
void testConversionOperator(); void testConversionOperator();
void testArithmeticOperators();
void testLimitsInt(); void testLimitsInt();
void testLimitsFloat(); void testLimitsFloat();
void testCtor(); void testCtor();