On 03/21/2018 12:23 PM, Marc-André Lureau wrote:

struct QObjectCommon {
      QType type;
      size_t refcnt;
}

struct QObject {
      QObjectCommon base;
}

struct QString {
      QObjectCommon base;
      ...
}

What is the QOJECT() macro you proposed with that?

Here's what you can do while still leaving all "subtypes" of QObject free to put base at a non-zero offset:

#define QOBJECT(o) ((QObject *)(&(o)->base))

QEMU_BUILD_BUG_MSG(offsetof(QObject, base),
    "base of QObject must be at offset 0");

#define qobject_to(type, obj) ({ \
QObjectCommon *_tmp = qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)); \
    _tmp ? container_of(_tmp, type, base) : (type *)NULL; })


static inline QObjectCommon *qobject_check_type(const QObject *obj, QType type)
{
    if (obj && qobject_type(obj) == type) {
        return QOBJECT(obj);
    } else {
        return NULL;
    }
}


Or, you keep your idea of requiring ALL subtypes to put base at offset 0, so that qobject_to() also becomes simpler.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Reply via email to