From 6af9e61e9b1833d8e3573666a23dce81719205b0 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 14 Aug 2016 17:21:47 +0200 Subject: [PATCH] Implement comparison operators for the Array class fixes #12426 --- lib/base/value-operators.cpp | 46 ++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/base/value-operators.cpp b/lib/base/value-operators.cpp index 580fafc73..ad0039722 100644 --- a/lib/base/value-operators.cpp +++ b/lib/base/value-operators.cpp @@ -580,7 +580,28 @@ bool icinga::operator<(const Value& lhs, const Value& rhs) return static_cast(lhs) < static_cast(rhs); else if ((lhs.IsObjectType() || lhs.IsEmpty()) && (rhs.IsObjectType() || rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty())) return Convert::ToDateTimeValue(lhs) < Convert::ToDateTimeValue(rhs); - else + else if (lhs.IsObjectType() && rhs.IsObjectType()) { + Array::Ptr larr = lhs; + Array::Ptr rarr = rhs; + + ObjectLock llock(larr); + ObjectLock rlock(rarr); + + Array::SizeType llen = larr->GetLength(); + Array::SizeType rlen = rarr->GetLength(); + + for (Array::SizeType i = 0; i < std::max(llen, rlen); i++) { + Value lval = (i >= llen) ? Empty : larr->Get(i); + Value rval = (i >= rlen) ? Empty : rarr->Get(i); + + if (lval < rval) + return true; + else if (lval > rval) + return false; + } + + return false; + } else BOOST_THROW_EXCEPTION(std::invalid_argument("Operator < cannot be applied to values of type '" + lhs.GetTypeName() + "' and '" + rhs.GetTypeName() + "'")); } @@ -612,7 +633,28 @@ bool icinga::operator>(const Value& lhs, const Value& rhs) return static_cast(lhs) > static_cast(rhs); else if ((lhs.IsObjectType() || lhs.IsEmpty()) && (rhs.IsObjectType() || rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty())) return Convert::ToDateTimeValue(lhs) > Convert::ToDateTimeValue(rhs); - else + else if (lhs.IsObjectType() && rhs.IsObjectType()) { + Array::Ptr larr = lhs; + Array::Ptr rarr = rhs; + + ObjectLock llock(larr); + ObjectLock rlock(rarr); + + Array::SizeType llen = larr->GetLength(); + Array::SizeType rlen = rarr->GetLength(); + + for (Array::SizeType i = 0; i < std::max(llen, rlen); i++) { + Value lval = (i >= llen) ? Empty : larr->Get(i); + Value rval = (i >= rlen) ? Empty : rarr->Get(i); + + if (lval > rval) + return true; + else if (lval < rval) + return false; + } + + return false; + } else BOOST_THROW_EXCEPTION(std::invalid_argument("Operator > cannot be applied to values of type '" + lhs.GetTypeName() + "' and '" + rhs.GetTypeName() + "'")); }