More operators and some code fixes

This commit is contained in:
Aleksandar Fabijanic
2007-09-12 22:56:20 +00:00
parent 5a6eb68529
commit dd81a7ecf0
4 changed files with 190 additions and 26 deletions

View File

@@ -177,28 +177,28 @@ public:
template <typename T> template <typename T>
DynamicAny& operator = (const T& other) DynamicAny& operator = (const T& other)
/// Assignment operator /// Assignment operator for assigning POD to DynamicAny
{ {
DynamicAny tmp(other); DynamicAny tmp(other);
swap(tmp); swap(tmp);
return *this; return *this;
} }
DynamicAny& operator = (const DynamicAny& other); DynamicAny& operator = (const DynamicAny& other);
/// Assignment operator specialization for DynamicAny /// Assignment operator specialization for DynamicAny
template <typename T> template <typename T>
DynamicAny operator + (const T& other) const const DynamicAny operator + (const T& other) const
/// Addition operator /// Addition operator for adding POD to DynamicAny
{ {
return convert<T>() + other; return convert<T>() + other;
} }
DynamicAny operator + (const DynamicAny& other) const; const DynamicAny operator + (const DynamicAny& other) const;
/// Addition operator specialization for DynamicAny /// Addition operator specialization for DynamicAny
DynamicAny operator + (const char* other) const; const DynamicAny operator + (const char* other) const;
/// Addition operator specialization for const char* /// Addition operator specialization for adding const char* to DynamicAny
DynamicAny& operator ++ (); DynamicAny& operator ++ ();
/// Pre-increment operator /// Pre-increment operator
@@ -214,7 +214,7 @@ public:
template <typename T> template <typename T>
DynamicAny& operator += (const T& other) DynamicAny& operator += (const T& other)
/// Addition asignment operator /// Addition asignment operator for addition/assignment of POD to DynamicAny.
{ {
return *this = convert<T>() + other; return *this = convert<T>() + other;
} }
@@ -226,13 +226,13 @@ public:
/// Addition asignment operator specialization for const char* /// Addition asignment operator specialization for const char*
template <typename T> template <typename T>
DynamicAny operator - (const T& other) const const DynamicAny operator - (const T& other) const
/// Subtraction operator /// Subtraction operator for subtracting POD from DynamicAny
{ {
return convert<T>() - other; return convert<T>() - other;
} }
DynamicAny operator - (const DynamicAny& other) const; const DynamicAny operator - (const DynamicAny& other) const;
/// Subtraction operator specialization for DynamicAny /// Subtraction operator specialization for DynamicAny
template <typename T> template <typename T>
@@ -246,13 +246,13 @@ public:
/// Subtraction asignment operator specialization for DynamicAny /// Subtraction asignment operator specialization for DynamicAny
template <typename T> template <typename T>
DynamicAny operator * (const T& other) const const DynamicAny operator * (const T& other) const
/// Multiplication operator /// Multiplication operator for multiplying DynamicAny with POD
{ {
return convert<T>() * other; return convert<T>() * other;
} }
DynamicAny operator * (const DynamicAny& other) const; const DynamicAny operator * (const DynamicAny& other) const;
/// Multiplication operator specialization for DynamicAny /// Multiplication operator specialization for DynamicAny
template <typename T> template <typename T>
@@ -266,13 +266,13 @@ public:
/// Multiplication asignment operator specialization for DynamicAny /// Multiplication asignment operator specialization for DynamicAny
template <typename T> template <typename T>
DynamicAny operator / (const T& other) const const DynamicAny operator / (const T& other) const
/// Division operator /// Division operator for dividing DynamicAny with POD
{ {
return convert<T>() / other; return convert<T>() / other;
} }
DynamicAny operator / (const DynamicAny& other) const; const DynamicAny operator / (const DynamicAny& other) const;
/// Division operator specialization for DynamicAny /// Division operator specialization for DynamicAny
template <typename T> template <typename T>
@@ -295,6 +295,9 @@ public:
bool operator == (const char* other) const; bool operator == (const char* other) const;
/// Equality operator specialization for const char* /// Equality operator specialization for const char*
bool operator == (const DynamicAny& other) const;
/// Equality operator specialization for DynamicAny
template <typename T> template <typename T>
bool operator != (const T& other) const bool operator != (const T& other) const
/// Inequality operator /// Inequality operator
@@ -302,6 +305,9 @@ public:
return convert<T>() != other; return convert<T>() != other;
} }
bool operator != (const DynamicAny& other) const;
/// Inequality operator specialization for DynamicAny
bool operator != (const char* other) const; bool operator != (const char* other) const;
/// Inequality operator specialization for const char* /// Inequality operator specialization for const char*
@@ -387,6 +393,15 @@ private:
}; };
///
/// inlines
///
///
/// DynamicAny members
///
inline void DynamicAny::swap(DynamicAny& ptr) inline void DynamicAny::swap(DynamicAny& ptr)
{ {
std::swap(_pHolder, ptr._pHolder); std::swap(_pHolder, ptr._pHolder);
@@ -399,7 +414,7 @@ inline const std::type_info& DynamicAny::type() const
} }
inline DynamicAny DynamicAny::operator + (const char* other) const inline const DynamicAny DynamicAny::operator + (const char* other) const
{ {
return convert<std::string>() + other; return convert<std::string>() + other;
} }
@@ -411,12 +426,24 @@ inline DynamicAny& DynamicAny::operator += (const char*other)
} }
inline bool DynamicAny::operator == (const DynamicAny& other) const
{
return convert<std::string>() == other.convert<std::string>();
}
inline bool DynamicAny::operator == (const char* other) const inline bool DynamicAny::operator == (const char* other) const
{ {
return convert<std::string>() == other; return convert<std::string>() == other;
} }
inline bool DynamicAny::operator != (const DynamicAny& other) const
{
return convert<std::string>() != other.convert<std::string>();
}
inline bool DynamicAny::operator != (const char* other) const inline bool DynamicAny::operator != (const char* other) const
{ {
return convert<std::string>() != other; return convert<std::string>() != other;
@@ -459,6 +486,98 @@ inline bool DynamicAny::isString() const
} }
///
/// DynamicAny non-member functions
///
template <typename T>
inline const DynamicAny operator + (const T& other, const DynamicAny& da)
/// Addition operator for adding DynamicAny to POD
{
return da.convert<T>() + other;
}
inline const DynamicAny operator + (const char* other, const DynamicAny& da)
/// Addition operator for adding DynamicAny to const char*
{
std::string tmp = other;
return other + da.convert<std::string>();
}
template <typename T>
inline const DynamicAny operator - (const T& other, const DynamicAny& da)
/// Subtraction operator for subtracting DynamicAny from POD
{
DynamicAny tmp = other;
return tmp - da.convert<T>();
}
template <typename T>
inline const DynamicAny operator * (const T& other, const DynamicAny& da)
/// Multiplication operator for multiplying POD with DynamicAny
{
return da.convert<T>() * other;
}
template <typename T>
inline const DynamicAny operator / (const T& other, const DynamicAny& da)
/// Division operator for dividing POD with DynamicAny
{
DynamicAny tmp = other;
return tmp / da.convert<T>();
}
template <typename T>
inline T& operator += (T& other, const DynamicAny& da)
/// Addition asignment operator for addition/assignment of DynamicAny to POD.
{
return other += da.convert<T>();
}
template <typename T>
inline T& operator -= (T& other, const DynamicAny& da)
/// Subtraction asignment operator for subtraction/assignment of DynamicAny to POD.
{
return other -= da.convert<T>();
}
template <typename T>
inline T& operator *= (T& other, const DynamicAny& da)
/// Multiplication asignment operator for multiplication/assignment of DynamicAny to POD.
{
return other *= da.convert<T>();
}
template <typename T>
inline T& operator /= (T& other, const DynamicAny& da)
/// Division asignment operator for division/assignment of DynamicAny to POD.
{
return other /= da.convert<T>();
}
inline bool operator == (const std::string& other, const DynamicAny& da)
/// Equality operator for DynamicAny comparison to std::string
{
return da.convert<std::string>() == other;
}
inline bool operator != (const std::string& other, const DynamicAny& da)
/// Equality operator for DynamicAny comparison to std::string
{
return da.convert<std::string>() != other;
}
} // namespace Poco } // namespace Poco

View File

@@ -77,7 +77,7 @@ DynamicAny& DynamicAny::operator = (const DynamicAny& other)
} }
DynamicAny DynamicAny::operator + (const DynamicAny& other) const const DynamicAny DynamicAny::operator + (const DynamicAny& other) const
{ {
if (isInteger()) if (isInteger())
{ {
@@ -113,7 +113,7 @@ DynamicAny& DynamicAny::operator += (const DynamicAny& other)
} }
DynamicAny DynamicAny::operator - (const DynamicAny& other) const const DynamicAny DynamicAny::operator - (const DynamicAny& other) const
{ {
if (isInteger()) if (isInteger())
{ {
@@ -145,7 +145,7 @@ DynamicAny& DynamicAny::operator -= (const DynamicAny& other)
} }
DynamicAny DynamicAny::operator * (const DynamicAny& other) const const DynamicAny DynamicAny::operator * (const DynamicAny& other) const
{ {
if (isInteger()) if (isInteger())
{ {
@@ -177,7 +177,7 @@ DynamicAny& DynamicAny::operator *= (const DynamicAny& other)
} }
DynamicAny DynamicAny::operator / (const DynamicAny& other) const const DynamicAny DynamicAny::operator / (const DynamicAny& other) const
{ {
if (isInteger()) if (isInteger())
{ {

View File

@@ -1327,16 +1327,20 @@ void DynamicAnyTest::testULong()
assert (a3 == 64); assert (a3 == 64);
} }
void DynamicAnyTest::testConversionOperator() void DynamicAnyTest::testConversionOperator()
{ {
DynamicAny any("42"); DynamicAny any("42");
int i = any; int i = any;
assert (i == 42); assert (i == 42);
assert (any == i);
any = 123; any = 123;
std::string s = any; std::string s = any;
assert (s == "123"); assert (s == "123");
assert (s == any);
assert (any == s);
assert ("123" == any);
any = 321; any = 321;
s = any.convert<std::string>(); s = any.convert<std::string>();
@@ -1344,10 +1348,29 @@ void DynamicAnyTest::testConversionOperator()
any = "456"; any = "456";
assert (any == "456"); assert (any == "456");
assert ("456" == any);
DynamicAny any2 = "1.5"; DynamicAny any2 = "1.5";
double d = any2; double d = any2;
assert (d == 1.5); assert (d == 1.5);
assert (any2 == d);
}
void DynamicAnyTest::testComparisonOperators()
{
DynamicAny any1 = 1;
DynamicAny any2 = "1";
assert (any1 == any2);
assert (any1 == 1);
assert (any1 == "1");
assert ("1" == any1);
any1 = "2";
assert (any1 != any2);
assert (any1 != 1);
assert (any1 != "1");
assert ("1" != any1);
} }
@@ -1357,27 +1380,42 @@ void DynamicAnyTest::testArithmeticOperators()
DynamicAny any2 = 2; DynamicAny any2 = 2;
DynamicAny any3 = any1 + any2; DynamicAny any3 = any1 + any2;
assert (any3 == 3); assert (any3 == 3);
int i = 1;
i += any1;
assert (2 == i);
any1 = 3; any1 = 3;
assert ((5 - any1) == 2);
any2 = 5; any2 = 5;
any3 = any2 - any1; any3 = any2 - any1;
assert (any3 == 2); assert (any3 == 2);
any3 -= 1; any3 -= 1;
assert (any3 == 1); assert (any3 == 1);
i = 5;
i -= any1;
assert (2 == i);
any1 = 3; any1 = 3;
assert ((5 * any1) == 15);
any2 = 5; any2 = 5;
any3 = any1 * any2; any3 = any1 * any2;
assert (any3 == 15); assert (any3 == 15);
any3 *= 3; any3 *= 3;
assert (any3 == 45); assert (any3 == 45);
i = 5;
i *= any1;
assert (15 == i);
any1 = 3; any1 = 3;
assert ((9 / any1) == 3);
any2 = 9; any2 = 9;
any3 = any2 / any1; any3 = any2 / any1;
assert (any3 == 3); assert (any3 == 3);
any3 /= 3; any3 /= 3;
assert (any3 == 1); assert (any3 == 1);
i = 9;
i /= any1;
assert (3 == i);
any1 = 1.0f; any1 = 1.0f;
any2 = .5f; any2 = .5f;
@@ -1402,6 +1440,7 @@ void DynamicAnyTest::testArithmeticOperators()
any2 = "4"; any2 = "4";
any3 += any2; any3 += any2;
assert (any3 == 7); assert (any3 == 7);
assert (1 + any3 == 8);
any1 = "123"; any1 = "123";
any2 = "456"; any2 = "456";
@@ -1410,6 +1449,7 @@ void DynamicAnyTest::testArithmeticOperators()
any2 = "789"; any2 = "789";
any3 += any2; any3 += any2;
assert (any3 == "123456789"); assert (any3 == "123456789");
assert (("xyz" + any3) == "xyz123456789");
try { any3 = any1 - any2; fail ("must fail"); } try { any3 = any1 - any2; fail ("must fail"); }
catch (InvalidArgumentException&){} catch (InvalidArgumentException&){}
@@ -2054,8 +2094,9 @@ void DynamicAnyTest::testGetIdxMustThrow(DynamicAny& a1, std::vector<DynamicAny>
{ {
try try
{ {
DynamicAny& val1 = a1[n]; DynamicAny& val1 = a1[n];
fail("bad cast - must throw"); fail("bad cast - must throw");
val1 = 0; // silence the compiler
} }
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
@@ -2064,8 +2105,9 @@ void DynamicAnyTest::testGetIdxMustThrow(DynamicAny& a1, std::vector<DynamicAny>
try try
{ {
const DynamicAny& c1 = a1; const DynamicAny& c1 = a1;
const DynamicAny& cval1 = c1[n]; const DynamicAny& cval1 = c1[n];
fail("bad const cast - must throw"); fail("bad const cast - must throw");
assert (cval1 == c1); // silence the compiler
} }
catch (Poco::BadCastException&) catch (Poco::BadCastException&)
{ {
@@ -2103,6 +2145,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, testComparisonOperators);
CppUnit_addTest(pSuite, DynamicAnyTest, testArithmeticOperators); 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);

View File

@@ -63,6 +63,7 @@ public:
void testULong(); void testULong();
void testString(); void testString();
void testConversionOperator(); void testConversionOperator();
void testComparisonOperators();
void testArithmeticOperators(); void testArithmeticOperators();
void testLimitsInt(); void testLimitsInt();
void testLimitsFloat(); void testLimitsFloat();
@@ -96,6 +97,7 @@ private:
assert (val1 == expectedResult); assert (val1 == expectedResult);
const Poco::DynamicAny& c1 = a1; const Poco::DynamicAny& c1 = a1;
assert (a1 == c1); // silence the compiler
const Poco::DynamicAny& cval1 = a1[n]; const Poco::DynamicAny& cval1 = a1[n];
assert (cval1 == expectedResult); assert (cval1 == expectedResult);
} }