summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qstring.h
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2012-04-01 01:05:47 +0200
committerQt by Nokia <qt-info@nokia.com>2012-04-04 23:29:37 +0200
commita959f34d716f42925b22d42838e7a4b97e415c69 (patch)
tree7491904bb192c19c04538665b590724dece8a36a /src/corelib/tools/qstring.h
parentff6e8460e601a2fb1eb41a1907417524a67505bb (diff)
Clean up constructors for "statics" in QString and QByteArray
There were two constuctors offering essentially the same functionality. One taking the QStatic*Data<N> struct, the other what essentially amounts to a pointer wrapper of that struct. The former was dropped and the latter untemplatized and kept, as that is the most generic and widely applicable. The template parameter in the wrapper was not very useful as it essentially duplicated information that already maintained in the struct, and there were no consistency checks to ensure they were in sync. In this case, using a wrapper is preferred over the use of naked pointers both as a way to make explicit the transfer of ownership as well as to avoid unintended conversions. By using the reference count (even if only by calling deref() in the destructor), QByteArray and QString must own their Data pointers. Const qualification was dropped from the member variable in these wrappers as it causes some compilers to emit warnings on the lack of constructors, and because it isn't needed there. To otherwise reduce noise, QStatic*Data<N> gained a member function to directly access the const_cast'ed naked pointer. This plays nicely with the above constructor. Its use also allows us to do further changes in the QStatic*Data structs with fewer changes in remaining code. The function has an assert on isStatic(), to ensure it is not inadvertently used with data that requires ref-count operations. With this change, the need for the private constructor taking a naked Q*Data pointer is obviated and that was dropped too. In updating QStringBuilder's QConcatenable specializations I noticed they were broken (using data, instead of data()), so a test was added to avoid this happening again in the future. An unnecessary ref-count increment in QByteArray::clear was also dropped. Change-Id: I9b92fbaae726ab9807837e83d0d19812bf7db5ab Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qstring.h')
-rw-r--r--src/corelib/tools/qstring.h44
1 files changed, 27 insertions, 17 deletions
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 4f241e72e2..50796a9e29 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -113,12 +113,16 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
#ifndef QT_NO_UNICODE_LITERAL
# define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str)
# if defined(Q_COMPILER_LAMBDA)
-# define QStringLiteral(str) ([]() -> QStaticStringDataPtr<sizeof(QT_UNICODE_LITERAL(str))/2 - 1> { \
+
+# define QStringLiteral(str) \
+ ([]() -> QStringDataPtr { \
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
static const QStaticStringData<Size> qstring_literal = \
{ { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QStringData) }, QT_UNICODE_LITERAL(str) }; \
- QStaticStringDataPtr<Size> holder = { &qstring_literal }; \
- return holder; }())
+ QStringDataPtr holder = { qstring_literal.data_ptr() }; \
+ return holder; \
+ }()) \
+ /**/
# elif defined(Q_CC_GNU)
// We need to create a QStringData in the .rodata section of memory
@@ -130,8 +134,11 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
static const QStaticStringData<Size> qstring_literal = \
{ { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QStringData) }, QT_UNICODE_LITERAL(str) }; \
- QStaticStringDataPtr<Size> holder = { &qstring_literal }; \
- holder; })
+ QStringDataPtr holder = { qstring_literal.data_ptr() }; \
+ holder; \
+ }) \
+ /**/
+
# endif
#endif // QT_NO_UNICODE_LITERAL
@@ -147,12 +154,17 @@ struct QStaticStringData
{
QStringData str;
qunicodechar data[N + 1];
+
+ QStringData *data_ptr() const
+ {
+ Q_ASSERT(str.ref.isStatic());
+ return const_cast<QStringData *>(&str);
+ }
};
-template <int N>
-struct QStaticStringDataPtr
+struct QStringDataPtr
{
- const QStaticStringData<N> *ptr;
+ QStringData *ptr;
};
class Q_CORE_EXPORT QString
@@ -421,11 +433,13 @@ public:
// note - this are all inline so we can benefit from strlen() compile time optimizations
static inline QString fromAscii(const char *str, int size = -1)
{
- return QString(fromAscii_helper(str, (str && size == -1) ? int(strlen(str)) : size), 0);
+ QStringDataPtr dataPtr = { fromAscii_helper(str, (str && size == -1) ? int(strlen(str)) : size) };
+ return QString(dataPtr);
}
static inline QString fromLatin1(const char *str, int size = -1)
{
- return QString(fromLatin1_helper(str, (str && size == -1) ? int(strlen(str)) : size), 0);
+ QStringDataPtr dataPtr = { fromLatin1_helper(str, (str && size == -1) ? int(strlen(str)) : size) };
+ return QString(dataPtr);
}
static inline QString fromUtf8(const char *str, int size = -1)
{
@@ -600,7 +614,7 @@ public:
// compatibility
struct Null { };
static const Null null;
- inline QString(const Null &): d(const_cast<Data *>(&shared_null.str)) {}
+ inline QString(const Null &): d(shared_null.data_ptr()) {}
inline QString &operator=(const Null &) { *this = QString(); return *this; }
inline bool isNull() const { return d == &shared_null.str; }
@@ -609,10 +623,7 @@ public:
bool isRightToLeft() const;
QString(int size, Qt::Initialization);
- template <int n>
- inline QString(const QStaticStringData<n> &dd) : d(const_cast<QStringData *>(&dd.str)) {}
- template <int N>
- Q_DECL_CONSTEXPR inline QString(QStaticStringDataPtr<N> dd) : d(const_cast<QStringData *>(&dd.ptr->str)) {}
+ Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {}
private:
#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED)
@@ -627,7 +638,6 @@ private:
static const QStaticStringData<1> shared_null;
static const QStaticStringData<1> shared_empty;
Data *d;
- inline QString(Data *dd, int /*dummy*/) : d(dd) {}
static int grow(int);
static void free(Data *);
@@ -888,7 +898,7 @@ inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
-inline QString::QString() : d(const_cast<Data *>(&shared_null.str)) {}
+inline QString::QString() : d(shared_null.data_ptr()) {}
inline QString::~QString() { if (!d->ref.deref()) free(d); }
inline void QString::reserve(int asize)