From 1caaa8a0209b72d561e9b864e26fd5f50349332d Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Wed, 18 Nov 2015 14:03:45 +0900 Subject: [PATCH] Reduce duplicate code between String::ctor() and operator=(). It's safer to have only one pair of ref()/deref() than to have a several pairs. --- taglib/toolkit/tstring.cpp | 72 ++++++++++---------------------------- taglib/toolkit/tstring.h | 5 +++ 2 files changed, 23 insertions(+), 54 deletions(-) diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index 024744a3..3255f564 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -234,12 +234,6 @@ public: { } - StringPrivate(const wstring &s) - : RefCounter() - , data(s) - { - } - StringPrivate(uint n, wchar_t c) : RefCounter() , data(static_cast(n), c) @@ -746,90 +740,62 @@ String &String::operator+=(char c) String &String::operator=(const String &s) { - if(&s == this) - return *this; - - if(d->deref()) - delete d; - d = s.d; - d->ref(); + String(s).swap(*this); return *this; } String &String::operator=(const std::string &s) { - if(d->deref()) - delete d; - - d = new StringPrivate; - copyFromLatin1(d->data, s.c_str(), s.length()); - + String(s).swap(*this); return *this; } String &String::operator=(const wstring &s) { - if(d->deref()) - delete d; - d = new StringPrivate(s); + String(s).swap(*this); return *this; } String &String::operator=(const wchar_t *s) { - if(d->deref()) - delete d; - - d = new StringPrivate(s); + String(s).swap(*this); return *this; } String &String::operator=(char c) { - if(d->deref()) - delete d; - - d = new StringPrivate(1, static_cast(c)); + String(c).swap(*this); return *this; } String &String::operator=(wchar_t c) { - if(d->deref()) - delete d; - - d = new StringPrivate(1, c); + String(c, wcharByteOrder()).swap(*this); return *this; } String &String::operator=(const char *s) { - if(d->deref()) - delete d; - - d = new StringPrivate; - copyFromLatin1(d->data, s, ::strlen(s)); - + String(s).swap(*this); return *this; } String &String::operator=(const ByteVector &v) { - if(d->deref()) - delete d; - - d = new StringPrivate; - copyFromLatin1(d->data, v.data(), v.size()); - - // If we hit a null in the ByteVector, shrink the string again. - d->data.resize(::wcslen(d->data.c_str())); - + String(v).swap(*this); return *this; } +void String::swap(String &s) +{ + using std::swap; + + swap(d, s.d); +} + bool String::operator<(const String &s) const { - return d->data < s.d->data; + return (d->data < s.d->data); } //////////////////////////////////////////////////////////////////////////////// @@ -838,10 +804,8 @@ bool String::operator<(const String &s) const void String::detach() { - if(d->count() > 1) { - d->deref(); - d = new StringPrivate(d->data); - } + if(d->count() > 1) + String(d->data.c_str()).swap(*this); } } diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index 85acc528..b7314bda 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -494,6 +494,11 @@ namespace TagLib { */ String &operator=(const ByteVector &v); + /*! + * Exchanges the content of the String by the content of \a s. + */ + void swap(String &s); + /*! * To be able to use this class in a Map, this operator needed to be * implemented. Returns true if \a s is less than this string in a byte-wise