File: metaobject.h

package info (click to toggle)
gammaray 3.1.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 24,796 kB
  • sloc: cpp: 109,174; ansic: 2,156; sh: 336; python: 274; yacc: 90; lex: 82; xml: 61; makefile: 28; javascript: 9; ruby: 5
file content (154 lines) | stat: -rw-r--r-- 4,927 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
  metaobject.h

  This file is part of GammaRay, the Qt application inspection and manipulation tool.

  SPDX-FileCopyrightText: 2011 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
  Author: Volker Krause <volker.krause@kdab.com>

  SPDX-License-Identifier: GPL-2.0-or-later

  Contact KDAB at <info@kdab.com> for commercial licensing options.
*/

#ifndef GAMMARAY_METAOBJECT_H
#define GAMMARAY_METAOBJECT_H

#include "gammaray_core_export.h"

#include "metaproperty.h"
#include "typetraits.h"

#include <QVector>

namespace GammaRay {
/*! Compile-time introspection adaptor for non-QObject classes. */
class GAMMARAY_CORE_EXPORT MetaObject
{
public:
    MetaObject();
    virtual ~MetaObject();

    /*!
     * Returns the amount of properties available in this class (including base classes).
     */
    int propertyCount() const;

    /*!
     * Returns the property adaptor for index @p index.
     */
    MetaProperty *propertyAt(int index) const;

    /*! Add a base class meta object. */
    void addBaseClass(MetaObject *baseClass);

    /*! Add a property for this class. This transfers ownership. */
    void addProperty(MetaProperty *property);

    /*! Returns the name of the class represented by this object. */
    QString className() const;

    /*! Casts a void pointer for an instance of this type to one appropriate
     * for use with the property at index @p index.
     * Make sure to use this when dealing with multi-inheritance.
     */
    void *castForPropertyAt(void *object, int index) const;

    /*! Casts to a void pointer for an instance of this type to one referring
     *  to the given base class type. If @p baseClass is not a base class
     *  of this type, @c nullptr is returned.
     */
    void *castTo(void *object, const QString &baseClass) const;

    /*! Sets the name of this class to @p className. */
    void setClassName(const QString &className);

    /*! Returns the MetaObject for the @p index base class. */
    MetaObject *superClass(int index = 0) const;
    /*! Returns @c true if this class inherits (directly or indirectly) a class named @p className. */
    bool inherits(const QString &className) const;

    /*! Returns @c true if this is a polymorphic type.
     *  @see std::is_polymorphic
     */
    bool isPolymorphic() const;

    /*! Casts to a void pointer for an instance of this type
     *  coming from the given base class. This performs the equivalent
     *  of a dynamic_cast and thus can return @p nullptr.
     */
    void *castFrom(void *object, MetaObject *baseClass) const;

protected:
    /*! Casts up to base class @p baseClassIndex.
     * This is important when traversing multi-inheritance trees.
     */
    virtual void *castToBaseClass(void *object, int baseClassIndex) const = 0;

    /*! Casts down from base class @p baseClassIndex.
     *  This performs a dynamic cast on polymorphic types, and is undefined for non-polymorphic types.
     */
    virtual void *castFromBaseClass(void *object, int baseClassIndex) const = 0;

    /*! Returns if this type is polymorphic. This can but does not require
     *  to return @c true for types derives from a polymorphic type.
     */
    virtual bool isClassPolymorphic() const = 0;

protected:
    ///@cond internal
    QVector<MetaObject *> m_baseClasses;
    ///@endcond

private:
    Q_DISABLE_COPY(MetaObject)
    QVector<MetaProperty *> m_properties;
    QString m_className;
};

///@cond internal
/*! Template implementation of MetaObject. */
template<typename T, typename Base1 = void, typename Base2 = void, typename Base3 = void>
class MetaObjectImpl : public MetaObject
{
protected:
    void *castToBaseClass(void *object, int baseClassIndex) const override
    {
        Q_ASSERT(baseClassIndex >= 0 && baseClassIndex < m_baseClasses.size());
        switch (baseClassIndex) {
        case 0:
            return static_cast<Base1 *>(static_cast<T *>(object));
        case 1:
            return static_cast<Base2 *>(static_cast<T *>(object));
        case 2:
            return static_cast<Base3 *>(static_cast<T *>(object));
        }
        Q_ASSERT_X(false, "MetaObjectImpl::castToBaseClass",
                   "Unexpected baseClassIndex encountered");
        return nullptr;
    }

    void *castFromBaseClass(void *object, int baseClassIndex) const override
    {
        Q_ASSERT(baseClassIndex >= 0 && baseClassIndex < m_baseClasses.size());
        Q_ASSERT(isPolymorphic());
        switch (baseClassIndex) {
        case 0:
            return DynamicCast<T *>(static_cast<Base1 *>(object));
        case 1:
            return DynamicCast<T *>(static_cast<Base2 *>(object));
        case 2:
            return DynamicCast<T *>(static_cast<Base3 *>(object));
        }
        return nullptr;
    }

    bool isClassPolymorphic() const override
    {
        return IsPolymorphic<T>();
    }
};
///@endcond
}

#endif // GAMMARAY_METAOBJECT_H