summaryrefslogtreecommitdiff
path: root/qobject/qnum.c
diff options
context:
space:
mode:
authorMax Reitz <mreitz@redhat.com>2017-11-14 19:01:25 +0100
committerMax Reitz <mreitz@redhat.com>2017-11-17 18:21:30 +0100
commitb38dd678a21582e03ecd2dec76ccf8290455628a (patch)
tree1076a9bc7235d44314418bb7ef140685692e999e /qobject/qnum.c
parent254bf807e5354c7b424d6fc28cb17c4f9ba43e35 (diff)
downloadqemu-b38dd678a21582e03ecd2dec76ccf8290455628a.tar.gz
qapi: Add qobject_is_equal()
This generic function (along with its implementations for different types) determines whether two QObjects are equal. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-id: 20171114180128.17076-4-mreitz@redhat.com Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'qobject/qnum.c')
-rw-r--r--qobject/qnum.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 476e81c93b..410686a611 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -213,6 +213,60 @@ QNum *qobject_to_qnum(const QObject *obj)
}
/**
+ * qnum_is_equal(): Test whether the two QNums are equal
+ *
+ * Negative integers are never considered equal to unsigned integers,
+ * but positive integers in the range [0, INT64_MAX] are considered
+ * equal independently of whether the QNum's kind is i64 or u64.
+ *
+ * Doubles are never considered equal to integers.
+ */
+bool qnum_is_equal(const QObject *x, const QObject *y)
+{
+ QNum *num_x = qobject_to_qnum(x);
+ QNum *num_y = qobject_to_qnum(y);
+
+ switch (num_x->kind) {
+ case QNUM_I64:
+ switch (num_y->kind) {
+ case QNUM_I64:
+ /* Comparison in native int64_t type */
+ return num_x->u.i64 == num_y->u.i64;
+ case QNUM_U64:
+ /* Implicit conversion of x to uin64_t, so we have to
+ * check its sign before */
+ return num_x->u.i64 >= 0 && num_x->u.i64 == num_y->u.u64;
+ case QNUM_DOUBLE:
+ return false;
+ }
+ abort();
+ case QNUM_U64:
+ switch (num_y->kind) {
+ case QNUM_I64:
+ return qnum_is_equal(y, x);
+ case QNUM_U64:
+ /* Comparison in native uint64_t type */
+ return num_x->u.u64 == num_y->u.u64;
+ case QNUM_DOUBLE:
+ return false;
+ }
+ abort();
+ case QNUM_DOUBLE:
+ switch (num_y->kind) {
+ case QNUM_I64:
+ case QNUM_U64:
+ return false;
+ case QNUM_DOUBLE:
+ /* Comparison in native double type */
+ return num_x->u.dbl == num_y->u.dbl;
+ }
+ abort();
+ }
+
+ abort();
+}
+
+/**
* qnum_destroy_obj(): Free all memory allocated by a
* QNum object
*/