Reputation: 79457
From the docs:
Internally, QList is represented as an array of pointers to items of type T. If T is itself a pointer type or a basic type that is no larger than a pointer, or if T is one of Qt's shared classes, then QList stores the items directly in the pointer array.
I'm interested to know, how does QList
'decide' whether to store pointers or the items themselves depending on the type?
Do they do it using some esoteric template syntax?
Upvotes: 1
Views: 1313
Reputation: 40492
Let's read the source (I'm using Qt 4.8).
qlist.h:
struct Node {
void *v;
#if defined(Q_CC_BOR)
Q_INLINE_TEMPLATE T &t();
#else
Q_INLINE_TEMPLATE T &t()
{ return *reinterpret_cast<T*>(QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
? v : this); }
#endif
};
QList
uses QTypeInfo
to determine type properties. QTypeInfo
is declared for various types separately. In qglobal.h:
Default declaration for unknown type:
template <typename T>
class QTypeInfo
{
public:
enum {
isPointer = false,
isComplex = true,
isStatic = true,
isLarge = (sizeof(T)>sizeof(void*)),
isDummy = false
};
};
Declaration for pointers:
template <typename T>
class QTypeInfo<T*>
{
public:
enum {
isPointer = true,
isComplex = false,
isStatic = false,
isLarge = false,
isDummy = false
};
};
Macros for convenient type info declaration:
#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
class QTypeInfo<TYPE > \
{ \
public: \
enum { \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \
isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \
isLarge = (sizeof(TYPE)>sizeof(void*)), \
isPointer = false, \
isDummy = (((FLAGS) & Q_DUMMY_TYPE) != 0) \
}; \
static inline const char *name() { return #TYPE; } \
}
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
template<> \
Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
Declaration for primitive types:
Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE); /* ... */
Also it's defined for specific Qt types, e.g. in qurl.h:
Q_DECLARE_TYPEINFO(QUrl, Q_MOVABLE_TYPE);
Or in qhash.h:
Q_DECLARE_TYPEINFO(QHashDummyValue, Q_MOVABLE_TYPE | Q_DUMMY_TYPE);
When QList
uses QTypeInfo<T>
, the compiler picks up the closest of present QTypeInfo
definitions.
Upvotes: 2