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.
/// 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
/// DynamicAnyHolderImpl is available. For supported types, see DynamicAnyHolder documentation.
{
@ -133,7 +143,7 @@ public:
}
template <typename T>
operator T() const
operator T () const
/// Safe conversion operator for implicit type
/// conversions.
///
@ -146,7 +156,7 @@ public:
_pHolder->convert(result);
return result;
}
template <typename T>
const T& extract() const
/// Returns a const reference to the actual value.
@ -162,14 +172,6 @@ public:
throw BadCastException();
}
DynamicAny& operator = (const DynamicAny& other)
/// Assignment operator
{
DynamicAny tmp(other);
swap(tmp);
return *this;
}
template <typename T>
DynamicAny& operator = (const T& other)
/// Assignment operator
@ -179,39 +181,114 @@ public:
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>
bool operator == (const T& other) const
/// Equality operator
{
T value;
_pHolder->convert(value);
return value == other;
return convert<T>() == other;
}
bool operator == (const char* other) const
/// Equality operator
{
std::string value;
_pHolder->convert(value);
return value == other;
}
bool operator == (const char* other) const;
/// Equality operator specialization for const char*
template <typename T>
bool operator != (const T& other) const
/// Inequality operator
{
T value;
_pHolder->convert(value);
return value != other;
return convert<T>() != other;
}
bool operator != (const char* other) const
/// Inequality operator
{
std::string value;
_pHolder->convert(value);
return value != other;
}
bool operator != (const char* other) const;
/// Inequality operator specialization for const char*
bool isArray() const;
/// Returns true if DynamicAny represents a vector
@ -219,25 +296,38 @@ public:
bool isStruct() const;
/// 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
/// 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
/// 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
/// 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
/// returns true! In all other cases a BadCastException is thrown!
const std::type_info& type() const;
/// 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);
/// 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 std::string parseString(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;
};
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
{
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

View File

@ -101,6 +101,10 @@ public:
virtual void convert(Timestamp& val) const = 0;
virtual bool isArray() 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
void convert(long& val) const;
@ -289,6 +293,26 @@ public:
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
{
throw NotImplementedException("No DynamicAnyHolder specialization for type", typeid(T).name());
@ -503,6 +527,26 @@ public:
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:
Int8 _val;
};
@ -627,6 +671,26 @@ public:
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:
Int16 _val;
};
@ -751,6 +815,26 @@ public:
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:
Int32 _val;
};
@ -875,6 +959,26 @@ public:
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:
Int64 _val;
};
@ -999,6 +1103,26 @@ public:
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:
UInt8 _val;
};
@ -1123,6 +1247,26 @@ public:
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:
UInt16 _val;
};
@ -1247,6 +1391,26 @@ public:
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:
UInt32 _val;
};
@ -1377,6 +1541,26 @@ public:
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:
UInt64 _val;
};
@ -1499,6 +1683,26 @@ public:
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:
bool _val;
};
@ -1624,6 +1828,26 @@ public:
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:
float _val;
};
@ -1755,6 +1979,26 @@ public:
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:
double _val;
};
@ -1877,6 +2121,26 @@ public:
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:
char _val;
};
@ -2029,6 +2293,26 @@ public:
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return true;
}
private:
std::string _val;
};
@ -2156,6 +2440,26 @@ public:
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:
long _val;
};
@ -2280,6 +2584,26 @@ public:
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:
unsigned long _val;
};
@ -2369,7 +2693,7 @@ public:
{
// Serialize in JSON format: note: although this a vector<T>, the code only
// 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
val.append("[ ");
@ -2424,6 +2748,26 @@ public:
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)
{
return _val.operator[](n);
@ -2556,6 +2900,26 @@ public:
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private:
DateTime _val;
};
@ -2678,6 +3042,26 @@ public:
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private:
LocalDateTime _val;
};
@ -2800,6 +3184,26 @@ public:
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
private:
Timestamp _val;
};

View File

@ -357,6 +357,26 @@ public:
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)
{
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);
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);
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);
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);
if (pHolder)

View File

@ -120,6 +120,23 @@ void DynamicAnyTest::testInt8()
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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&)
{
}
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);
any = 123;
std::string s = any;//'s(any)' bombs on gcc 3.4.4
std::string s = any;
assert (s == "123");
any = 321;
@ -1128,6 +1344,89 @@ void DynamicAnyTest::testConversionOperator()
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, testULong);
CppUnit_addTest(pSuite, DynamicAnyTest, testConversionOperator);
CppUnit_addTest(pSuite, DynamicAnyTest, testArithmeticOperators);
CppUnit_addTest(pSuite, DynamicAnyTest, testLimitsInt);
CppUnit_addTest(pSuite, DynamicAnyTest, testLimitsFloat);
CppUnit_addTest(pSuite, DynamicAnyTest, testCtor);

View File

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