diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 3746e6d8..672005aa 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -118,54 +118,113 @@ if(NOT HAVE_GCC_BYTESWAP_16 OR NOT HAVE_GCC_BYTESWAP_32 OR NOT HAVE_GCC_BYTESWAP endif() endif() +# Determine where shared_ptr is defined regardless of C++11 support. + +check_cxx_source_compiles(" + #include + int main() { std::shared_ptr x; return 0; } +" HAVE_STD_SHARED_PTR) + +if(NOT HAVE_STD_SHARED_PTR) + check_cxx_source_compiles(" + #include + int main() { std::tr1::shared_ptr x; return 0; } + " HAVE_TR1_SHARED_PTR) + + if(NOT HAVE_TR1_SHARED_PTR) + check_cxx_source_compiles(" + #include + int main() { boost::shared_ptr x; return 0; } + " HAVE_BOOST_SHARED_PTR) + endif() +endif() + +# Determine where unique_ptr or scoped_ptr is defined regardless of C++11 support. + +check_cxx_source_compiles(" + #include + int main() { std::unique_ptr x; return 0; } +" HAVE_STD_UNIQUE_PTR) + +if(NOT HAVE_STD_UNIQUE_PTR) + check_cxx_source_compiles(" + #include + int main() { boost::scoped_ptr x; return 0; } + " HAVE_BOOST_SCOPED_PTR) +endif() + # Determine which kind of atomic operations your compiler supports. check_cxx_source_compiles(" + #include int main() { - volatile int x; - __sync_add_and_fetch(&x, 1); - int y = __sync_sub_and_fetch(&x, 1); + std::atomic x; + x.fetch_add(1); + x.fetch_sub(1); return 0; } -" HAVE_GCC_ATOMIC) +" HAVE_STD_ATOMIC) -if(NOT HAVE_GCC_ATOMIC) +if(NOT HAVE_STD_ATOMIC) check_cxx_source_compiles(" - #include + #include int main() { - volatile int32_t x; - OSAtomicIncrement32Barrier(&x); - int32_t y = OSAtomicDecrement32Barrier(&x); + boost::atomic x(1); + x.fetch_add(1); + x.fetch_sub(1); return 0; } - " HAVE_MAC_ATOMIC) + " HAVE_BOOST_ATOMIC) - if(NOT HAVE_MAC_ATOMIC) + if(NOT HAVE_BOOST_ATOMIC) check_cxx_source_compiles(" - #include int main() { - volatile LONG x; - InterlockedIncrement(&x); - LONG y = InterlockedDecrement(&x); + volatile int x; + __sync_add_and_fetch(&x, 1); + int y = __sync_sub_and_fetch(&x, 1); return 0; } - " HAVE_WIN_ATOMIC) + " HAVE_GCC_ATOMIC) - if(NOT HAVE_WIN_ATOMIC) + if(NOT HAVE_GCC_ATOMIC) check_cxx_source_compiles(" - #include + #include int main() { - volatile int x; - __sync_add_and_fetch(&x, 1); - int y = __sync_sub_and_fetch(&x, 1); + volatile int32_t x; + OSAtomicIncrement32Barrier(&x); + int32_t y = OSAtomicDecrement32Barrier(&x); return 0; } - " HAVE_IA64_ATOMIC) + " HAVE_MAC_ATOMIC) + + if(NOT HAVE_MAC_ATOMIC) + check_cxx_source_compiles(" + #include + int main() { + volatile LONG x; + InterlockedIncrement(&x); + LONG y = InterlockedDecrement(&x); + return 0; + } + " HAVE_WIN_ATOMIC) + + if(NOT HAVE_WIN_ATOMIC) + check_cxx_source_compiles(" + #include + int main() { + volatile int x; + __sync_add_and_fetch(&x, 1); + int y = __sync_sub_and_fetch(&x, 1); + return 0; + } + " HAVE_IA64_ATOMIC) + endif() + endif() endif() endif() endif() -# Determine whether your compiler supports some safer version of sprintf. +# Determine whether your compiler supports snpritf or sprintf_s. check_cxx_source_compiles(" #include @@ -198,52 +257,6 @@ else() set(HAVE_ZLIB 0) endif() -# Determine whether your compiler supports move semantics. - -check_cxx_source_compiles(" - #ifdef __clang__ - # pragma clang diagnostic error \"-Wc++11-extensions\" - #endif - #include - int func(int &&x) { return x - 1; } - int main() { return func(std::move(1)); } -" TAGLIB_USE_MOVE_SEMANTICS) - -# Determine where shared_ptr is defined regardless of C++11 support. - -check_cxx_source_compiles(" - #include - int main() { std::shared_ptr x; return 0; } -" TAGLIB_USE_STD_SHARED_PTR) - -if(NOT TAGLIB_USE_STD_SHARED_PTR) - check_cxx_source_compiles(" - #include - int main() { std::tr1::shared_ptr x; return 0; } - " TAGLIB_USE_TR1_SHARED_PTR) - - if(NOT TAGLIB_USE_TR1_SHARED_PTR) - check_cxx_source_compiles(" - #include - int main() { boost::shared_ptr x; return 0; } - " TAGLIB_USE_BOOST_SHARED_PTR) - endif() -endif() - -# Determine where unique_ptr or scoped_ptr is defined regardless of C++11 support. - -check_cxx_source_compiles(" - #include - int main() { std::unique_ptr x; return 0; } -" TAGLIB_USE_STD_UNIQUE_PTR) - -if(NOT TAGLIB_USE_STD_UNIQUE_PTR) - check_cxx_source_compiles(" - #include - int main() { boost::scoped_ptr x; return 0; } - " TAGLIB_USE_BOOST_SCOPED_PTR) -endif() - # Determine whether CppUnit is installed. set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) diff --git a/config.h.cmake b/config.h.cmake index 8424abf6..086122c6 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -18,13 +18,24 @@ #cmakedefine HAVE_MAC_BYTESWAP 1 #cmakedefine HAVE_OPENBSD_BYTESWAP 1 +/* Defined if your compiler supports shared_ptr */ +#cmakedefine HAVE_STD_SHARED_PTR 1 // #include / std::shared_ptr +#cmakedefine HAVE_TR1_SHARED_PTR 1 // #include / std::tr1::shared_ptr +#cmakedefine HAVE_BOOST_SHARED_PTR 1 // #include / boost::shared_ptr + +/* Defined if your compiler supports unique_ptr or scoped_ptr */ +#cmakedefine HAVE_STD_UNIQUE_PTR 1 // #include / std::unique_ptr +#cmakedefine HAVE_BOOST_SCOPED_PTR 1 // #include / boost::scoped_ptr + /* Defined if your compiler supports some atomic operations */ +#cmakedefine HAVE_STD_ATOMIC 1 +#cmakedefine HAVE_BOOST_ATOMIC 1 #cmakedefine HAVE_GCC_ATOMIC 1 #cmakedefine HAVE_MAC_ATOMIC 1 #cmakedefine HAVE_WIN_ATOMIC 1 #cmakedefine HAVE_IA64_ATOMIC 1 -/* Defined if your compiler supports some safer version of sprintf */ +/* Defined if your compiler supports snpritf or sprintf_s. */ #cmakedefine HAVE_SNPRINTF 1 #cmakedefine HAVE_SPRINTF_S 1 diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index 1b406ebd..a36bd867 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -53,7 +53,7 @@ set(tag_HDRS toolkit/tmap.h toolkit/tmap.tcc toolkit/tpropertymap.h - toolkit/tsmartptr.h + toolkit/trefcounter.h mpeg/mpegfile.h mpeg/mpegproperties.h mpeg/mpegheader.h @@ -300,7 +300,7 @@ set(toolkit_SRCS toolkit/tfilestream.cpp toolkit/tdebug.cpp toolkit/tpropertymap.cpp - toolkit/tsmartptr.cpp + toolkit/trefcounter.cpp toolkit/unicode.cpp ) diff --git a/taglib/asf/asfattribute.cpp b/taglib/asf/asfattribute.cpp index 302af77f..8abea065 100644 --- a/taglib/asf/asfattribute.cpp +++ b/taglib/asf/asfattribute.cpp @@ -23,32 +23,45 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#include -#include +#include "taglib.h" +#include "tdebug.h" +#include "tsmartptr.h" #include "asfattribute.h" #include "asffile.h" using namespace TagLib; +namespace +{ + struct AttributeData + { + ASF::Attribute::AttributeTypes type; + String stringValue; + ByteVector byteVectorValue; + ASF::Picture pictureValue; + union { + unsigned int intValue; + unsigned short shortValue; + unsigned long long longLongValue; + bool boolValue; + }; + int stream; + int language; + }; +} + class ASF::Attribute::AttributePrivate { public: AttributePrivate() - : pictureValue(ASF::Picture::fromInvalid()), - stream(0), - language(0) {} - AttributeTypes type; - String stringValue; - ByteVector byteVectorValue; - ASF::Picture pictureValue; - union { - unsigned int intValue; - unsigned short shortValue; - unsigned long long longLongValue; - bool boolValue; - }; - int stream; - int language; + : data(new AttributeData()) + { + data->pictureValue = ASF::Picture::fromInvalid(); + data->stream = 0; + data->language = 0; + } + + SHARED_PTR data; }; //////////////////////////////////////////////////////////////////////////////// @@ -58,135 +71,127 @@ public: ASF::Attribute::Attribute() : d(new AttributePrivate()) { - d->type = UnicodeType; + d->data->type = UnicodeType; } ASF::Attribute::Attribute(const ASF::Attribute &other) - : d(other.d) + : d(new AttributePrivate(*other.d)) { } ASF::Attribute::Attribute(const String &value) : d(new AttributePrivate()) { - d->type = UnicodeType; - d->stringValue = value; + d->data->type = UnicodeType; + d->data->stringValue = value; } ASF::Attribute::Attribute(const ByteVector &value) : d(new AttributePrivate()) { - d->type = BytesType; - d->byteVectorValue = value; + d->data->type = BytesType; + d->data->byteVectorValue = value; } ASF::Attribute::Attribute(const ASF::Picture &value) : d(new AttributePrivate()) { - d->type = BytesType; - d->pictureValue = value; + d->data->type = BytesType; + d->data->pictureValue = value; } ASF::Attribute::Attribute(unsigned int value) : d(new AttributePrivate()) { - d->type = DWordType; - d->intValue = value; + d->data->type = DWordType; + d->data->intValue = value; } ASF::Attribute::Attribute(unsigned long long value) : d(new AttributePrivate()) { - d->type = QWordType; - d->longLongValue = value; + d->data->type = QWordType; + d->data->longLongValue = value; } ASF::Attribute::Attribute(unsigned short value) : d(new AttributePrivate()) { - d->type = WordType; - d->shortValue = value; + d->data->type = WordType; + d->data->shortValue = value; } ASF::Attribute::Attribute(bool value) : d(new AttributePrivate()) { - d->type = BoolType; - d->boolValue = value; + d->data->type = BoolType; + d->data->boolValue = value; } ASF::Attribute::~Attribute() { + delete d; } ASF::Attribute &ASF::Attribute::operator=(const ASF::Attribute &other) { - d = other.d; + *d = *other.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -ASF::Attribute &ASF::Attribute::operator=(ASF::Attribute &&other) -{ - d = std::move(other.d); - return *this; -} - -#endif - ASF::Attribute::AttributeTypes ASF::Attribute::type() const { - return d->type; + return d->data->type; } String ASF::Attribute::toString() const { - return d->stringValue; + return d->data->stringValue; } ByteVector ASF::Attribute::toByteVector() const { - if(d->pictureValue.isValid()) - return d->pictureValue.render(); - return d->byteVectorValue; + if(d->data->pictureValue.isValid()) + return d->data->pictureValue.render(); + + return d->data->byteVectorValue; } unsigned short ASF::Attribute::toBool() const { - return d->shortValue; + return d->data->shortValue; } unsigned short ASF::Attribute::toUShort() const { - return d->shortValue; + return d->data->shortValue; } unsigned int ASF::Attribute::toUInt() const { - return d->intValue; + return d->data->intValue; } unsigned long long ASF::Attribute::toULongLong() const { - return d->longLongValue; + return d->data->longLongValue; } ASF::Picture ASF::Attribute::toPicture() const { - return d->pictureValue; + return d->data->pictureValue; } String ASF::Attribute::parse(ASF::File &f, int kind) { uint size, nameLength; String name; - d->pictureValue = Picture::fromInvalid(); + d->data->pictureValue = Picture::fromInvalid(); // extended content descriptor if(kind == 0) { nameLength = f.readWORD(); name = f.readString(nameLength); - d->type = ASF::Attribute::AttributeTypes(f.readWORD()); + d->data->type = ASF::Attribute::AttributeTypes(f.readWORD()); size = f.readWORD(); } // metadata & metadata library @@ -194,11 +199,11 @@ String ASF::Attribute::parse(ASF::File &f, int kind) int temp = f.readWORD(); // metadata library if(kind == 2) { - d->language = temp; + d->data->language = temp; } - d->stream = f.readWORD(); + d->data->stream = f.readWORD(); nameLength = f.readWORD(); - d->type = ASF::Attribute::AttributeTypes(f.readWORD()); + d->data->type = ASF::Attribute::AttributeTypes(f.readWORD()); size = f.readDWORD(); name = f.readString(nameLength); } @@ -207,42 +212,42 @@ String ASF::Attribute::parse(ASF::File &f, int kind) debug("ASF::Attribute::parse() -- Value larger than 64kB"); } - switch(d->type) { + switch(d->data->type) { case WordType: - d->shortValue = f.readWORD(); + d->data->shortValue = f.readWORD(); break; case BoolType: if(kind == 0) { - d->boolValue = f.readDWORD() == 1; + d->data->boolValue = f.readDWORD() == 1; } else { - d->boolValue = f.readWORD() == 1; + d->data->boolValue = f.readWORD() == 1; } break; case DWordType: - d->intValue = f.readDWORD(); + d->data->intValue = f.readDWORD(); break; case QWordType: - d->longLongValue = f.readQWORD(); + d->data->longLongValue = f.readQWORD(); break; case UnicodeType: - d->stringValue = f.readString(size); + d->data->stringValue = f.readString(size); break; case BytesType: case GuidType: - d->byteVectorValue = f.readBlock(size); + d->data->byteVectorValue = f.readBlock(size); break; } - if(d->type == BytesType && name == "WM/Picture") { - d->pictureValue.parse(d->byteVectorValue); - if(d->pictureValue.isValid()) { - d->byteVectorValue.clear(); + if(d->data->type == BytesType && name == "WM/Picture") { + d->data->pictureValue.parse(d->data->byteVectorValue); + if(d->data->pictureValue.isValid()) { + d->data->byteVectorValue.clear(); } } @@ -251,7 +256,7 @@ String ASF::Attribute::parse(ASF::File &f, int kind) int ASF::Attribute::dataSize() const { - switch (d->type) { + switch (d->data->type) { case WordType: return 2; case BoolType: @@ -261,12 +266,12 @@ int ASF::Attribute::dataSize() const case QWordType: return 5; case UnicodeType: - return static_cast(d->stringValue.size() * 2 + 2); + return static_cast(d->data->stringValue.size() * 2 + 2); case BytesType: - if(d->pictureValue.isValid()) - return d->pictureValue.dataSize(); + if(d->data->pictureValue.isValid()) + return d->data->pictureValue.dataSize(); case GuidType: - return static_cast(d->byteVectorValue.size()); + return static_cast(d->data->byteVectorValue.size()); } return 0; } @@ -275,54 +280,54 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const { ByteVector data; - switch (d->type) { + switch (d->data->type) { case WordType: - data.append(ByteVector::fromUInt16LE(d->shortValue)); + data.append(ByteVector::fromUInt16LE(d->data->shortValue)); break; case BoolType: if(kind == 0) { - data.append(ByteVector::fromUInt32LE(d->boolValue ? 1 : 0)); + data.append(ByteVector::fromUInt32LE(d->data->boolValue ? 1 : 0)); } else { - data.append(ByteVector::fromUInt16LE(d->boolValue ? 1 : 0)); + data.append(ByteVector::fromUInt16LE(d->data->boolValue ? 1 : 0)); } break; case DWordType: - data.append(ByteVector::fromUInt32LE(d->intValue)); + data.append(ByteVector::fromUInt32LE(d->data->intValue)); break; case QWordType: - data.append(ByteVector::fromUInt64LE(d->longLongValue)); + data.append(ByteVector::fromUInt64LE(d->data->longLongValue)); break; case UnicodeType: - data.append(File::renderString(d->stringValue)); + data.append(File::renderString(d->data->stringValue)); break; case BytesType: - if(d->pictureValue.isValid()) { - data.append(d->pictureValue.render()); + if(d->data->pictureValue.isValid()) { + data.append(d->data->pictureValue.render()); break; } case GuidType: - data.append(d->byteVectorValue); + data.append(d->data->byteVectorValue); break; } if(kind == 0) { data = File::renderString(name, true) + - ByteVector::fromUInt16LE((int)d->type) + + ByteVector::fromUInt16LE((int)d->data->type) + ByteVector::fromUInt16LE(data.size()) + data; } else { ByteVector nameData = File::renderString(name); - data = ByteVector::fromUInt16LE(kind == 2 ? d->language : 0) + - ByteVector::fromUInt16LE(d->stream) + + data = ByteVector::fromUInt16LE(kind == 2 ? d->data->language : 0) + + ByteVector::fromUInt16LE(d->data->stream) + ByteVector::fromUInt16LE(nameData.size()) + - ByteVector::fromUInt16LE((int)d->type) + + ByteVector::fromUInt16LE((int)d->data->type) + ByteVector::fromUInt32LE(data.size()) + nameData + data; @@ -333,21 +338,21 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const int ASF::Attribute::language() const { - return d->language; + return d->data->language; } void ASF::Attribute::setLanguage(int value) { - d->language = value; + d->data->language = value; } int ASF::Attribute::stream() const { - return d->stream; + return d->data->stream; } void ASF::Attribute::setStream(int value) { - d->stream = value; + d->data->stream = value; } diff --git a/taglib/asf/asfattribute.h b/taglib/asf/asfattribute.h index 18269da4..469490f6 100644 --- a/taglib/asf/asfattribute.h +++ b/taglib/asf/asfattribute.h @@ -36,7 +36,6 @@ namespace TagLib namespace ASF { - class File; class Picture; @@ -115,17 +114,6 @@ namespace TagLib */ ASF::Attribute &operator=(const Attribute &other); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves the contents of \a other into this item. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - ASF::Attribute &operator=(Attribute &&other); - -#endif - /*! * Destroys the attribute. */ @@ -191,21 +179,17 @@ namespace TagLib */ void setStream(int value); -#ifndef DO_NOT_DOCUMENT - /* THIS IS PRIVATE, DON'T TOUCH IT! */ - String parse(ASF::File &file, int kind = 0); -#endif - //! Returns the size of the stored data int dataSize() const; private: friend class File; + String parse(ASF::File &file, int kind = 0); ByteVector render(const String &name, int kind = 0) const; class AttributePrivate; - RefCountPtr d; + AttributePrivate *d; }; } diff --git a/taglib/asf/asfpicture.cpp b/taglib/asf/asfpicture.cpp index 62477585..b4f10ea8 100644 --- a/taglib/asf/asfpicture.cpp +++ b/taglib/asf/asfpicture.cpp @@ -23,24 +23,39 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#include -#include +#include "taglib.h" +#include "tdebug.h" +#include "tsmartptr.h" #include "asfattribute.h" #include "asffile.h" #include "asfpicture.h" using namespace TagLib; +namespace +{ + struct PictureData + { + bool valid; + ASF::Picture::Type type; + String mimeType; + String description; + ByteVector picture; + }; +} + class ASF::Picture::PicturePrivate { public: - bool valid; - Type type; - String mimeType; - String description; - ByteVector picture; + PicturePrivate() + : data(new PictureData()) + { + } + + SHARED_PTR data; }; + //////////////////////////////////////////////////////////////////////////////// // Picture class members //////////////////////////////////////////////////////////////////////////////// @@ -48,115 +63,96 @@ public: ASF::Picture::Picture() : d(new PicturePrivate()) { - d->valid = true; + d->data->valid = true; } ASF::Picture::Picture(const Picture& other) - : d(other.d) + : d(new PicturePrivate(*other.d)) { } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -ASF::Picture::Picture(Picture &&other) - : d(std::move(other.d)) -{ -} - -#endif - ASF::Picture::~Picture() { + delete d; } bool ASF::Picture::isValid() const { - return d->valid; + return d->data->valid; } String ASF::Picture::mimeType() const { - return d->mimeType; + return d->data->mimeType; } void ASF::Picture::setMimeType(const String &value) { - d->mimeType = value; + d->data->mimeType = value; } ASF::Picture::Type ASF::Picture::type() const { - return d->type; + return d->data->type; } void ASF::Picture::setType(const ASF::Picture::Type& t) { - d->type = t; + d->data->type = t; } String ASF::Picture::description() const { - return d->description; + return d->data->description; } void ASF::Picture::setDescription(const String &desc) { - d->description = desc; + d->data->description = desc; } ByteVector ASF::Picture::picture() const { - return d->picture; + return d->data->picture; } void ASF::Picture::setPicture(const ByteVector &p) { - d->picture = p; + d->data->picture = p; } int ASF::Picture::dataSize() const { return static_cast( - 9 + (d->mimeType.length() + d->description.length()) * 2 + - d->picture.size()); + 9 + (d->data->mimeType.length() + d->data->description.length()) * 2 + + d->data->picture.size()); } ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other) { - d = other.d; + *d = *other.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -ASF::Picture& ASF::Picture::operator=(ASF::Picture &&other) -{ - d = std::move(other.d); - return *this; -} - -#endif - - ByteVector ASF::Picture::render() const { if(!isValid()) return ByteVector::null; return - ByteVector((char)d->type) + - ByteVector::fromUInt32LE(d->picture.size()) + - ASF::File::renderString(d->mimeType) + - ASF::File::renderString(d->description) + - d->picture; + ByteVector((char)d->data->type) + + ByteVector::fromUInt32LE(d->data->picture.size()) + + ASF::File::renderString(d->data->mimeType) + + ASF::File::renderString(d->data->description) + + d->data->picture; } void ASF::Picture::parse(const ByteVector& bytes) { - d->valid = false; + d->data->valid = false; if(bytes.size() < 9) return; size_t pos = 0; - d->type = (Type)bytes[0]; ++pos; + d->data->type = (Type)bytes[0]; ++pos; const uint dataLen = bytes.toUInt32LE(pos); pos+=4; const ByteVector nullStringTerminator(2, 0); @@ -164,27 +160,27 @@ void ASF::Picture::parse(const ByteVector& bytes) size_t endPos = bytes.find(nullStringTerminator, pos, 2); if(endPos == ByteVector::npos) return; - d->mimeType = String(bytes.mid(pos, endPos - pos), String::UTF16LE); + d->data->mimeType = String(bytes.mid(pos, endPos - pos), String::UTF16LE); pos = endPos+2; endPos = bytes.find(nullStringTerminator, pos, 2); if(endPos == ByteVector::npos) return; - d->description = String(bytes.mid(pos, endPos - pos), String::UTF16LE); + d->data->description = String(bytes.mid(pos, endPos - pos), String::UTF16LE); pos = endPos+2; if(dataLen + pos != bytes.size()) return; - d->picture = bytes.mid(pos, dataLen); - d->valid = true; + d->data->picture = bytes.mid(pos, dataLen); + d->data->valid = true; return; } ASF::Picture ASF::Picture::fromInvalid() { Picture ret; - ret.d->valid = false; + ret.d->data->valid = false; return ret; } diff --git a/taglib/asf/asfpicture.h b/taglib/asf/asfpicture.h index 463bd43d..2c07cb63 100644 --- a/taglib/asf/asfpicture.h +++ b/taglib/asf/asfpicture.h @@ -35,6 +35,7 @@ namespace TagLib { namespace ASF { + class Attribute; //! An ASF attached picture interface implementation @@ -46,7 +47,8 @@ namespace TagLib * \see Attribute::toPicture() * \see Attribute::Attribute(const Picture& picture) */ - class TAGLIB_EXPORT Picture { + class TAGLIB_EXPORT Picture + { public: /*! @@ -107,17 +109,6 @@ namespace TagLib */ Picture(const Picture& other); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Constructs an picture equivalent to \a other. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - Picture(Picture &&other); - -#endif - /*! * Destroys the picture. */ @@ -128,17 +119,6 @@ namespace TagLib */ Picture& operator=(const Picture& other); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves the contents of \a other into this picture. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - Picture& operator=(Picture &&other); - -#endif - /*! * Returns true if Picture stores valid picture */ @@ -223,15 +203,14 @@ namespace TagLib */ int dataSize() const; -#ifndef DO_NOT_DOCUMENT - /* THIS IS PRIVATE, DON'T TOUCH IT! */ - void parse(const ByteVector& ); - static Picture fromInvalid(); - friend class Attribute; -#endif private: + friend class Attribute; + + void parse(const ByteVector &); + static Picture fromInvalid(); + class PicturePrivate; - RefCountPtr d; + PicturePrivate *d; }; } } diff --git a/taglib/audioproperties.h b/taglib/audioproperties.h index 750924d4..9ae5468b 100644 --- a/taglib/audioproperties.h +++ b/taglib/audioproperties.h @@ -104,6 +104,7 @@ namespace TagLib { AudioProperties(ReadStyle style); private: + // Noncopyable. Derived classes as well. AudioProperties(const AudioProperties &); AudioProperties &operator=(const AudioProperties &); diff --git a/taglib/fileref.cpp b/taglib/fileref.cpp index 77c78069..51dd390b 100644 --- a/taglib/fileref.cpp +++ b/taglib/fileref.cpp @@ -33,9 +33,10 @@ # include #endif -#include -#include -#include +#include "tfile.h" +#include "tstring.h" +#include "tdebug.h" +#include "tsmartptr.h" #include "fileref.h" #include "asffile.h" @@ -66,12 +67,12 @@ namespace ResolverList fileTypeResolvers; - RefCountPtr create( + SHARED_PTR create( FileName fileName, bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle) { - RefCountPtr file; + SHARED_PTR file; for(ResolverConstIterator it = fileTypeResolvers.begin(); it != fileTypeResolvers.end(); ++it) { file.reset((*it)->createFile(fileName, readAudioProperties, audioPropertiesStyle)); @@ -169,12 +170,12 @@ public: { } - FileRefPrivate(RefCountPtr f) - : file(f) + FileRefPrivate(const SHARED_PTR &f) + : file(f) { } - RefCountPtr file; + SHARED_PTR file; }; //////////////////////////////////////////////////////////////////////////////// @@ -187,7 +188,8 @@ FileRef::FileRef() } FileRef::FileRef(FileName fileName, - bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle) + bool readAudioProperties, + AudioProperties::ReadStyle audioPropertiesStyle) : d(new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle))) { } @@ -198,21 +200,13 @@ FileRef::FileRef(File *file) } FileRef::FileRef(const FileRef &ref) - : d(ref.d) + : d(new FileRefPrivate(ref.d->file)) { } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -FileRef::FileRef(FileRef &&ref) - : d(std::move(ref.d)) -{ -} - -#endif - FileRef::~FileRef() { + delete d; } Tag *FileRef::tag() const @@ -330,26 +324,16 @@ bool FileRef::isNull() const FileRef &FileRef::operator=(const FileRef &ref) { - d = ref.d; + *d = *ref.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -FileRef &FileRef::operator=(FileRef &&ref) -{ - d = std::move(ref.d); - return *this; -} - -#endif - bool FileRef::operator==(const FileRef &ref) const { - return ref.d->file == d->file; + return (d->file == ref.d->file); } bool FileRef::operator!=(const FileRef &ref) const { - return ref.d->file != d->file; + return (d->file != ref.d->file); } diff --git a/taglib/fileref.h b/taglib/fileref.h index 465730f0..c0b4607a 100644 --- a/taglib/fileref.h +++ b/taglib/fileref.h @@ -143,17 +143,6 @@ namespace TagLib { */ FileRef(const FileRef &ref); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Move \a ref into the FileRef. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - FileRef(FileRef &&ref); - -#endif - /*! * Destroys this FileRef instance. */ @@ -286,17 +275,6 @@ namespace TagLib { */ FileRef &operator=(const FileRef &ref); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a ref into this FileRef. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - FileRef &operator=(FileRef &&ref); - -#endif - /*! * Returns true if this FileRef and \a ref point to the same File object. */ @@ -310,7 +288,7 @@ namespace TagLib { private: class FileRefPrivate; - RefCountPtr d; + FileRefPrivate *d; }; } // namespace TagLib diff --git a/taglib/flac/flacpicture.h b/taglib/flac/flacpicture.h index b6def57a..213284f0 100644 --- a/taglib/flac/flacpicture.h +++ b/taglib/flac/flacpicture.h @@ -199,8 +199,6 @@ namespace TagLib { PicturePrivate *d; }; - typedef List PictureList; - } } diff --git a/taglib/mp4/mp4coverart.cpp b/taglib/mp4/mp4coverart.cpp index 56e6aa52..b5ff8b89 100644 --- a/taglib/mp4/mp4coverart.cpp +++ b/taglib/mp4/mp4coverart.cpp @@ -23,63 +23,66 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#include -#include +#include "taglib.h" +#include "tdebug.h" +#include "tsmartptr.h" #include "mp4coverart.h" using namespace TagLib; +namespace +{ + struct CoverArtData + { + MP4::CoverArt::Format format; + ByteVector data; + }; +} + class MP4::CoverArt::CoverArtPrivate { public: - CoverArtPrivate() : format(MP4::CoverArt::JPEG) {} + CoverArtPrivate(Format f, const ByteVector &v) + : data(new CoverArtData()) + { + data->format = f; + data->data = v; + } - Format format; - ByteVector data; + SHARED_PTR data; }; MP4::CoverArt::CoverArt(Format format, const ByteVector &data) - : d(new CoverArtPrivate()) + : d(new CoverArtPrivate(format, data)) { - d->format = format; - d->data = data; } -MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d) +MP4::CoverArt::CoverArt(const CoverArt &item) + : d(new CoverArtPrivate(*item.d)) { } MP4::CoverArt & - MP4::CoverArt::operator=(const CoverArt &item) +MP4::CoverArt::operator=(const CoverArt &item) { - d = item.d; + *d = *item.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -MP4::CoverArt & - MP4::CoverArt::operator=(CoverArt &&item) -{ - d = std::move(item.d); - return *this; -} - -#endif - MP4::CoverArt::~CoverArt() { + delete d; } MP4::CoverArt::Format MP4::CoverArt::format() const { - return d->format; + return d->data->format; } ByteVector MP4::CoverArt::data() const { - return d->data; + return d->data->data; } diff --git a/taglib/mp4/mp4coverart.h b/taglib/mp4/mp4coverart.h index ea9784ad..d87efe05 100644 --- a/taglib/mp4/mp4coverart.h +++ b/taglib/mp4/mp4coverart.h @@ -54,9 +54,6 @@ namespace TagLib { CoverArt(const CoverArt &item); CoverArt &operator=(const CoverArt &item); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - CoverArt &operator=(CoverArt &&item); -#endif //! Format of the image Format format() const; @@ -66,13 +63,11 @@ namespace TagLib { private: class CoverArtPrivate; - RefCountPtr d; + CoverArtPrivate *d; }; typedef List CoverArtList; - } - } #endif diff --git a/taglib/mp4/mp4item.cpp b/taglib/mp4/mp4item.cpp index 23749e76..379ecc80 100644 --- a/taglib/mp4/mp4item.cpp +++ b/taglib/mp4/mp4item.cpp @@ -23,10 +23,14 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ +#include "config.h" + #include #include -#include -#include + +#include "taglib.h" +#include "tdebug.h" +#include "tsmartptr.h" #include "mp4item.h" using namespace TagLib; @@ -59,234 +63,227 @@ namespace return String(buf); } + + struct ItemData + { + bool valid; + MP4::AtomDataType atomDataType; + MP4::Item::ItemType type; + union { + bool m_bool; + int m_int; + MP4::Item::IntPair m_intPair; + uchar m_byte; + uint m_uint; + long long m_longlong; + }; + StringList m_stringList; + ByteVectorList m_byteVectorList; + MP4::CoverArtList m_coverArtList; + }; } class MP4::Item::ItemPrivate { public: - ItemPrivate() : valid(true), atomDataType(MP4::TypeUndefined), type(MP4::Item::TypeUndefined) {} + ItemPrivate() + : data(new ItemData()) + { + data->valid = true; + data->atomDataType = MP4::TypeUndefined; + data->type = MP4::Item::TypeUndefined; + } - bool valid; - AtomDataType atomDataType; - ItemType type; - union { - bool m_bool; - int m_int; - IntPair m_intPair; - uchar m_byte; - uint m_uint; - long long m_longlong; - }; - StringList m_stringList; - ByteVectorList m_byteVectorList; - MP4::CoverArtList m_coverArtList; + SHARED_PTR data; }; MP4::Item::Item() : d(new ItemPrivate()) { - d->valid = false; + d->data->valid = false; } MP4::Item::Item(const Item &item) - : d(item.d) + : d(new ItemPrivate(*item.d)) { } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -MP4::Item::Item(Item &&item) - : d(std::move(item.d)) -{ -} - -#endif - MP4::Item & MP4::Item::operator=(const Item &item) { - d = item.d; + *d = *item.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -MP4::Item & - MP4::Item::operator=(Item &&item) -{ - d = std::move(item.d); - return *this; -} - -#endif MP4::Item::~Item() { + delete d; } MP4::Item::Item(bool value) : d(new ItemPrivate()) { - d->m_bool = value; - d->type = TypeBool; + d->data->m_bool = value; + d->data->type = TypeBool; } MP4::Item::Item(int value) : d(new ItemPrivate()) { - d->m_int = value; - d->type = TypeInt; + d->data->m_int = value; + d->data->type = TypeInt; } MP4::Item::Item(uchar value) : d(new ItemPrivate()) { - d->m_byte = value; - d->type = TypeByte; + d->data->m_byte = value; + d->data->type = TypeByte; } MP4::Item::Item(uint value) : d(new ItemPrivate()) { - d->m_uint = value; - d->type = TypeUInt; + d->data->m_uint = value; + d->data->type = TypeUInt; } MP4::Item::Item(long long value) : d(new ItemPrivate()) { - d->m_longlong = value; - d->type = TypeLongLong; + d->data->m_longlong = value; + d->data->type = TypeLongLong; } MP4::Item::Item(int value1, int value2) : d(new ItemPrivate()) { - d->m_intPair.first = value1; - d->m_intPair.second = value2; - d->type = TypeIntPair; + d->data->m_intPair.first = value1; + d->data->m_intPair.second = value2; + d->data->type = TypeIntPair; } MP4::Item::Item(const ByteVectorList &value) : d(new ItemPrivate()) { - d->m_byteVectorList = value; - d->type = TypeByteVectorList; + d->data->m_byteVectorList = value; + d->data->type = TypeByteVectorList; } MP4::Item::Item(const StringList &value) : d(new ItemPrivate()) { - d->m_stringList = value; - d->type = TypeStringList; + d->data->m_stringList = value; + d->data->type = TypeStringList; } MP4::Item::Item(const MP4::CoverArtList &value) : d(new ItemPrivate()) { - d->m_coverArtList = value; - d->type = TypeCoverArtList; + d->data->m_coverArtList = value; + d->data->type = TypeCoverArtList; } void MP4::Item::setAtomDataType(MP4::AtomDataType type) { - d->atomDataType = type; + d->data->atomDataType = type; } MP4::AtomDataType MP4::Item::atomDataType() const { - return d->atomDataType; + return d->data->atomDataType; } bool MP4::Item::toBool() const { - return d->m_bool; + return d->data->m_bool; } int MP4::Item::toInt() const { - return d->m_int; + return d->data->m_int; } uchar MP4::Item::toByte() const { - return d->m_byte; + return d->data->m_byte; } TagLib::uint MP4::Item::toUInt() const { - return d->m_uint; + return d->data->m_uint; } long long MP4::Item::toLongLong() const { - return d->m_longlong; + return d->data->m_longlong; } MP4::Item::IntPair MP4::Item::toIntPair() const { - return d->m_intPair; + return d->data->m_intPair; } StringList MP4::Item::toStringList() const { - return d->m_stringList; + return d->data->m_stringList; } ByteVectorList MP4::Item::toByteVectorList() const { - return d->m_byteVectorList; + return d->data->m_byteVectorList; } MP4::CoverArtList MP4::Item::toCoverArtList() const { - return d->m_coverArtList; + return d->data->m_coverArtList; } bool MP4::Item::isValid() const { - return d->valid; + return d->data->valid; } String MP4::Item::toString() const { StringList desc; - switch (d->type) { + switch (d->data->type) { case TypeBool: - return d->m_bool ? "true" : "false"; + return d->data->m_bool ? "true" : "false"; case TypeInt: - return format("%d", d->m_int); + return format("%d", d->data->m_int); case TypeIntPair: - return format("%d/%d", d->m_intPair.first, d->m_intPair.second); + return format("%d/%d", d->data->m_intPair.first, d->data->m_intPair.second); case TypeByte: - return format("%d", d->m_byte); + return format("%d", d->data->m_byte); case TypeUInt: - return format("%u", d->m_uint); + return format("%u", d->data->m_uint); case TypeLongLong: - return format("%lld", d->m_longlong); + return format("%lld", d->data->m_longlong); case TypeStringList: - return d->m_stringList.toString(" / "); + return d->data->m_stringList.toString(" / "); case TypeByteVectorList: - for(TagLib::uint i = 0; i < d->m_byteVectorList.size(); i++) { + for(TagLib::uint i = 0; i < d->data->m_byteVectorList.size(); i++) { desc.append(format( - "[%d bytes of data]", static_cast(d->m_byteVectorList[i].size()))); + "[%d bytes of data]", static_cast(d->data->m_byteVectorList[i].size()))); } return desc.toString(", "); case TypeCoverArtList: - for(TagLib::uint i = 0; i < d->m_coverArtList.size(); i++) { + for(TagLib::uint i = 0; i < d->data->m_coverArtList.size(); i++) { desc.append(format( - "[%d bytes of data]", static_cast(d->m_coverArtList[i].data().size()))); + "[%d bytes of data]", static_cast(d->data->m_coverArtList[i].data().size()))); } return desc.toString(", "); case TypeUndefined: diff --git a/taglib/mp4/mp4item.h b/taglib/mp4/mp4item.h index 8ad23cf1..177463e5 100644 --- a/taglib/mp4/mp4item.h +++ b/taglib/mp4/mp4item.h @@ -56,14 +56,8 @@ namespace TagLib { Item(); Item(const Item &item); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - Item(Item &&item); -#endif Item &operator=(const Item &item); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - Item &operator=(Item &&item); -#endif ~Item(); Item(int value); @@ -97,7 +91,7 @@ namespace TagLib { private: class ItemPrivate; - RefCountPtr d; + ItemPrivate *d; }; } diff --git a/taglib/mpeg/id3v2/id3v2tag.cpp b/taglib/mpeg/id3v2/id3v2tag.cpp index efd629af..a1dcacf1 100644 --- a/taglib/mpeg/id3v2/id3v2tag.cpp +++ b/taglib/mpeg/id3v2/id3v2tag.cpp @@ -48,10 +48,16 @@ using namespace ID3v2; class ID3v2::Tag::TagPrivate { public: - TagPrivate() : file(0), tagOffset(-1), extendedHeader(0), footer(0), paddingSize(0) + TagPrivate() + : file(0) + , tagOffset(-1) + , extendedHeader(0) + , footer(0) + , paddingSize(0) { frameList.setAutoDelete(true); } + ~TagPrivate() { delete extendedHeader; diff --git a/taglib/mpeg/mpegheader.cpp b/taglib/mpeg/mpegheader.cpp index a71035b7..bbab765b 100644 --- a/taglib/mpeg/mpegheader.cpp +++ b/taglib/mpeg/mpegheader.cpp @@ -25,41 +25,51 @@ #include -#include -#include -#include +#include "tstring.h" +#include "tdebug.h" +#include "tsmartptr.h" #include "mpegheader.h" using namespace TagLib; +namespace +{ + struct HeaderData + { + bool isValid; + MPEG::Header::Version version; + int layer; + bool protectionEnabled; + int bitrate; + int sampleRate; + bool isPadded; + MPEG::Header::ChannelMode channelMode; + bool isCopyrighted; + bool isOriginal; + int frameLength; + int samplesPerFrame; + }; +} class MPEG::Header::HeaderPrivate { public: - HeaderPrivate() : - isValid(false), - version(Version1), - layer(0), - protectionEnabled(false), - sampleRate(0), - isPadded(false), - channelMode(Stereo), - isCopyrighted(false), - isOriginal(false), - frameLength(0), - samplesPerFrame(0) {} + HeaderPrivate() + : data(new HeaderData()) + { + data->isValid = false; + data->layer = 0; + data->version = Version1; + data->protectionEnabled = false; + data->sampleRate = 0; + data->isPadded = false; + data->channelMode = Stereo; + data->isCopyrighted = false; + data->isOriginal = false; + data->frameLength = 0; + data->samplesPerFrame = 0; + } - bool isValid; - Version version; - int layer; - bool protectionEnabled; - int bitrate; - int sampleRate; - bool isPadded; - ChannelMode channelMode; - bool isCopyrighted; - bool isOriginal; - int frameLength; - int samplesPerFrame; + SHARED_PTR data; }; //////////////////////////////////////////////////////////////////////////////// @@ -73,99 +83,80 @@ MPEG::Header::Header(const ByteVector &data) } MPEG::Header::Header(const Header &h) - : d(h.d) + : d(new HeaderPrivate(*h.d)) { } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -MPEG::Header::Header(Header &&h) - : d(std::move(h.d)) -{ -} - -#endif - MPEG::Header::~Header() { } bool MPEG::Header::isValid() const { - return d->isValid; + return d->data->isValid; } MPEG::Header::Version MPEG::Header::version() const { - return d->version; + return d->data->version; } int MPEG::Header::layer() const { - return d->layer; + return d->data->layer; } bool MPEG::Header::protectionEnabled() const { - return d->protectionEnabled; + return d->data->protectionEnabled; } int MPEG::Header::bitrate() const { - return d->bitrate; + return d->data->bitrate; } int MPEG::Header::sampleRate() const { - return d->sampleRate; + return d->data->sampleRate; } bool MPEG::Header::isPadded() const { - return d->isPadded; + return d->data->isPadded; } MPEG::Header::ChannelMode MPEG::Header::channelMode() const { - return d->channelMode; + return d->data->channelMode; } bool MPEG::Header::isCopyrighted() const { - return d->isCopyrighted; + return d->data->isCopyrighted; } bool MPEG::Header::isOriginal() const { - return d->isOriginal; + return d->data->isOriginal; } int MPEG::Header::frameLength() const { - return d->frameLength; + return d->data->frameLength; } int MPEG::Header::samplesPerFrame() const { - return d->samplesPerFrame; + return d->data->samplesPerFrame; } MPEG::Header &MPEG::Header::operator=(const Header &h) { - d = h.d; + *d = *h.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -MPEG::Header &MPEG::Header::operator=(Header &&h) -{ - d = std::move(h.d); - return *this; -} - -#endif - //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// @@ -189,22 +180,22 @@ void MPEG::Header::parse(const ByteVector &data) // Set the MPEG version if(!flags[20] && !flags[19]) - d->version = Version2_5; + d->data->version = Version2_5; else if(flags[20] && !flags[19]) - d->version = Version2; + d->data->version = Version2; else if(flags[20] && flags[19]) - d->version = Version1; + d->data->version = Version1; // Set the MPEG layer if(!flags[18] && flags[17]) - d->layer = 3; + d->data->layer = 3; else if(flags[18] && !flags[17]) - d->layer = 2; + d->data->layer = 2; else if(flags[18] && flags[17]) - d->layer = 1; + d->data->layer = 1; - d->protectionEnabled = !flags[16]; + d->data->protectionEnabled = !flags[16]; // Set the bitrate @@ -221,15 +212,15 @@ void MPEG::Header::parse(const ByteVector &data) } }; - const int versionIndex = d->version == Version1 ? 0 : 1; - const int layerIndex = d->layer > 0 ? d->layer - 1 : 0; + const int versionIndex = d->data->version == Version1 ? 0 : 1; + const int layerIndex = d->data->layer > 0 ? d->data->layer - 1 : 0; // The bitrate index is encoded as the first 4 bits of the 3rd byte, // i.e. 1111xxxx int i = uchar(data[2]) >> 4; - d->bitrate = bitrates[versionIndex][layerIndex][i]; + d->data->bitrate = bitrates[versionIndex][layerIndex][i]; // Set the sample rate @@ -243,9 +234,9 @@ void MPEG::Header::parse(const ByteVector &data) i = uchar(data[2]) >> 2 & 0x03; - d->sampleRate = sampleRates[d->version][i]; + d->data->sampleRate = sampleRates[d->data->version][i]; - if(d->sampleRate == 0) { + if(d->data->sampleRate == 0) { debug("MPEG::Header::parse() -- Invalid sample rate."); return; } @@ -253,20 +244,20 @@ void MPEG::Header::parse(const ByteVector &data) // The channel mode is encoded as a 2 bit value at the end of the 3nd byte, // i.e. xxxxxx11 - d->channelMode = ChannelMode((uchar(data[3]) & 0xC0) >> 6); + d->data->channelMode = ChannelMode((uchar(data[3]) & 0xC0) >> 6); // TODO: Add mode extension for completeness - d->isOriginal = flags[2]; - d->isCopyrighted = flags[3]; - d->isPadded = flags[9]; + d->data->isOriginal = flags[2]; + d->data->isCopyrighted = flags[3]; + d->data->isPadded = flags[9]; // Calculate the frame length - if(d->layer == 1) - d->frameLength = 24000 * 2 * d->bitrate / d->sampleRate + int(d->isPadded); + if(d->data->layer == 1) + d->data->frameLength = 24000 * 2 * d->data->bitrate / d->data->sampleRate + int(d->data->isPadded); else - d->frameLength = 72000 * d->bitrate / d->sampleRate + int(d->isPadded); + d->data->frameLength = 72000 * d->data->bitrate / d->data->sampleRate + int(d->data->isPadded); // Samples per frame @@ -277,9 +268,9 @@ void MPEG::Header::parse(const ByteVector &data) { 1152, 576 } // Layer III }; - d->samplesPerFrame = samplesPerFrame[layerIndex][versionIndex]; + d->data->samplesPerFrame = samplesPerFrame[layerIndex][versionIndex]; // Now that we're done parsing, set this to be a valid frame. - d->isValid = true; + d->data->isValid = true; } diff --git a/taglib/mpeg/mpegheader.h b/taglib/mpeg/mpegheader.h index 0e168df1..020ebd06 100644 --- a/taglib/mpeg/mpegheader.h +++ b/taglib/mpeg/mpegheader.h @@ -27,7 +27,6 @@ #define TAGLIB_MPEGHEADER_H #include "taglib_export.h" -#include "tsmartptr.h" namespace TagLib { @@ -57,17 +56,6 @@ namespace TagLib { */ Header(const Header &h); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a h into this Header. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - Header(Header &&h); - -#endif - /*! * Destroys this Header instance. */ @@ -166,22 +154,11 @@ namespace TagLib { */ Header &operator=(const Header &h); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a h into this Header. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - Header &operator=(Header &&h); - -#endif - private: void parse(const ByteVector &data); class HeaderPrivate; - RefCountPtr d; + HeaderPrivate *d; }; } } diff --git a/taglib/riff/aiff/aiffproperties.cpp b/taglib/riff/aiff/aiffproperties.cpp index 274af03f..57dd65de 100644 --- a/taglib/riff/aiff/aiffproperties.cpp +++ b/taglib/riff/aiff/aiffproperties.cpp @@ -40,7 +40,6 @@ public: sampleWidth(0), sampleFrames(0) { - } int length; @@ -64,11 +63,12 @@ RIFF::AIFF::AudioProperties::AudioProperties(const ByteVector &data, ReadStyle s RIFF::AIFF::AudioProperties::~AudioProperties() { + delete d; } bool RIFF::AIFF::AudioProperties::isNull() const { - return (static_cast(d)); + return (d == 0); } int RIFF::AIFF::AudioProperties::length() const diff --git a/taglib/riff/aiff/aiffproperties.h b/taglib/riff/aiff/aiffproperties.h index 8cb78c49..cc05bd45 100644 --- a/taglib/riff/aiff/aiffproperties.h +++ b/taglib/riff/aiff/aiffproperties.h @@ -73,7 +73,7 @@ namespace TagLib { void read(const ByteVector &data); class PropertiesPrivate; - RefCountPtr d; + PropertiesPrivate *d; }; } } diff --git a/taglib/taglib_config.h.cmake b/taglib/taglib_config.h.cmake index 4f2045d1..8b4c89df 100644 --- a/taglib/taglib_config.h.cmake +++ b/taglib/taglib_config.h.cmake @@ -1,17 +1,3 @@ /* taglib_config.h. Generated by cmake from taglib_config.h.cmake */ -/* The variables below indicate the compiler capability. */ -/* DO NOT MODIFY them manually. It may break the binary compatibility. */ - -/* Defined if your compiler supports the move semantics */ -#cmakedefine TAGLIB_USE_MOVE_SEMANTICS 1 - -/* Defined if your compiler supports shared_ptr */ -#cmakedefine TAGLIB_USE_STD_SHARED_PTR 1 // #include / std::shared_ptr -#cmakedefine TAGLIB_USE_TR1_SHARED_PTR 1 // #include / std::tr1::shared_ptr -#cmakedefine TAGLIB_USE_BOOST_SHARED_PTR 1 // #include / boost::shared_ptr - -/* Defined if your compiler supports unique_ptr or scoped_ptr */ -#cmakedefine TAGLIB_USE_STD_UNIQUE_PTR 1 // #include / std::unique_ptr -#cmakedefine TAGLIB_USE_BOOST_SCOPED_PTR 1 // #include / boost::scoped_ptr diff --git a/taglib/tagunion.cpp b/taglib/tagunion.cpp index 904ec17b..b313e2c8 100644 --- a/taglib/tagunion.cpp +++ b/taglib/tagunion.cpp @@ -26,7 +26,7 @@ #include "tagunion.h" #include "tstringlist.h" #include "tpropertymap.h" - +#include "tsmartptr.h" #define stringUnion(method) \ for(size_t j = 0; j < COUNT; ++j) { \ @@ -56,7 +56,7 @@ namespace TagLib class TagUnion::TagUnionPrivate { public: - NonRefCountPtr tags[COUNT]; + SCOPED_PTR tags[COUNT]; }; template @@ -68,6 +68,7 @@ namespace TagLib template TagUnion::~TagUnion() { + delete d; } template diff --git a/taglib/tagunion.h b/taglib/tagunion.h index b7610621..0b41355e 100644 --- a/taglib/tagunion.h +++ b/taglib/tagunion.h @@ -26,6 +26,8 @@ #ifndef TAGLIB_TAGUNION_H #define TAGLIB_TAGUNION_H +// This file is not a part of TagLib public interface. This is not installed. + #include "tag.h" #ifndef DO_NOT_DOCUMENT @@ -87,7 +89,7 @@ namespace TagLib { private: class TagUnionPrivate; - NonRefCountPtr d; + TagUnionPrivate *d; }; // If you add a new typedef here, add a corresponding explicit instantiation diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index 8018f779..6f1efd26 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -41,8 +41,9 @@ # include #endif -#include -#include +#include "tstring.h" +#include "tdebug.h" +#include "tsmartptr.h" #include "tbytevector.h" // This is a bit ugly to keep writing over and over again. @@ -366,20 +367,13 @@ public: { } - ByteVectorPrivate(RefCountPtr d, size_t o, size_t l) + ByteVectorPrivate(ByteVectorPrivate* d, size_t o, size_t l) : data(d->data) , offset(d->offset + o) , length(l) { } - ByteVectorPrivate(const std::vector &v, size_t o, size_t l) - : data(new std::vector(v.begin() + o, v.begin() + o + l)) - , offset(0) - , length(l) - { - } - ByteVectorPrivate(size_t l, char c) : data(new std::vector(l, c)) , offset(0) @@ -406,15 +400,7 @@ public: { } - ByteVectorPrivate &operator=(const ByteVectorPrivate &x) - { - if(&x != this) - data = x.data; - - return *this; - } - - RefCountPtr > data; + SHARED_PTR > data; size_t offset; size_t length; }; @@ -480,7 +466,7 @@ ByteVector::ByteVector(size_t size, char value) } ByteVector::ByteVector(const ByteVector &v) - : d(v.d) + : d(new ByteVectorPrivate(*v.d)) { } @@ -489,15 +475,6 @@ ByteVector::ByteVector(const ByteVector &v, size_t offset, size_t length) { } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -ByteVector::ByteVector(ByteVector &&v) - : d(std::move(v.d)) -{ -} - -#endif - ByteVector::ByteVector(char c) : d(new ByteVectorPrivate(1, c)) { @@ -515,6 +492,7 @@ ByteVector::ByteVector(const char *data) ByteVector::~ByteVector() { + delete d; } ByteVector &ByteVector::setData(const char *data, size_t length) @@ -641,8 +619,8 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit } // new private data of appropriate size: - ByteVectorPrivate *newData = new ByteVectorPrivate(newSize, 0); - char *target = DATA(newData); + ByteVectorPrivate newData(newSize, '\0'); + char *target = &(*newData.data)[0]; const char *source = DATA(d); // copy modified data into new private data: @@ -662,7 +640,7 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit } // replace private data: - d.reset(newData); + *d = newData; return *this; } @@ -708,7 +686,7 @@ ByteVector &ByteVector::append(char c) ByteVector &ByteVector::clear() { detach(); - *this = ByteVector(); + *d = *ByteVector::null.d; return *this; } @@ -1071,30 +1049,20 @@ ByteVector ByteVector::operator+(const ByteVector &v) const ByteVector &ByteVector::operator=(const ByteVector &v) { - d = v.d; + *d = *v.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -ByteVector &ByteVector::operator=(ByteVector &&v) -{ - d = std::move(v.d); - return *this; -} - -#endif - ByteVector &ByteVector::operator=(char c) { - d = ByteVector(c).d; + *this = ByteVector(c); return *this; } ByteVector &ByteVector::operator=(const char *data) { - d = ByteVector(data).d; + *this = ByteVector(data); return *this; } @@ -1119,9 +1087,6 @@ ByteVector ByteVector::toHex() const void ByteVector::detach() { d->detach(); - - if(!d.unique()) - d.reset(new ByteVectorPrivate(*(d->data), d->offset, d->length)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/toolkit/tbytevector.h b/taglib/toolkit/tbytevector.h index ae3039a7..af8d1db8 100644 --- a/taglib/toolkit/tbytevector.h +++ b/taglib/toolkit/tbytevector.h @@ -28,7 +28,6 @@ #include "taglib_export.h" #include "taglib.h" -#include "tsmartptr.h" #include #include @@ -68,17 +67,6 @@ namespace TagLib { */ ByteVector(const ByteVector &v); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Constructs a byte vector equivalent to \a v. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - ByteVector(ByteVector &&v); - -#endif - /*! * Constructs a byte vector that is a copy of \a v. */ @@ -502,17 +490,6 @@ namespace TagLib { */ ByteVector &operator=(const ByteVector &v); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a v into this ByteVector. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - ByteVector &operator=(ByteVector &&v); - -#endif - /*! * Copies ByteVector \a v. */ @@ -551,7 +528,7 @@ namespace TagLib { private: class ByteVectorPrivate; - RefCountPtr d; + ByteVectorPrivate *d; }; /*! diff --git a/taglib/toolkit/tfile.cpp b/taglib/toolkit/tfile.cpp index 4e3c4f1a..3acd7c93 100644 --- a/taglib/toolkit/tfile.cpp +++ b/taglib/toolkit/tfile.cpp @@ -27,6 +27,7 @@ #include "tfilestream.h" #include "tstring.h" #include "tdebug.h" +#include "tsmartptr.h" #include "tpropertymap.h" #include "audioproperties.h" @@ -65,7 +66,7 @@ public: } private: - NonRefCountPtr p; + SCOPED_PTR p; }; // FilePrivate implementation which doesn't take ownership of the stream. @@ -93,6 +94,7 @@ private: File::~File() { + delete d; } FileName File::name() const diff --git a/taglib/toolkit/tfile.h b/taglib/toolkit/tfile.h index 680958e0..2584383e 100644 --- a/taglib/toolkit/tfile.h +++ b/taglib/toolkit/tfile.h @@ -278,13 +278,14 @@ namespace TagLib { static size_t bufferSize(); private: + // Noncopyable. Derived classes as well. File(const File &); File &operator=(const File &); class FilePrivateBase; class ManagedFilePrivate; class UnmanagedFilePrivate; - NonRefCountPtr d; + FilePrivateBase *d; }; } diff --git a/taglib/toolkit/tfilestream.cpp b/taglib/toolkit/tfilestream.cpp index f3877f68..0f8cf6ac 100644 --- a/taglib/toolkit/tfilestream.cpp +++ b/taglib/toolkit/tfilestream.cpp @@ -196,6 +196,8 @@ FileStream::~FileStream() { if(isOpen()) closeFile(d->file); + + delete d; } FileName FileStream::name() const @@ -402,7 +404,7 @@ void FileStream::seek(offset_t offset, Position p) SetFilePointer(d->file, liOffset.LowPart, &liOffset.HighPart, whence); if(GetLastError() != NO_ERROR) { - debug("File::seek() -- Failed to set the file size."); + debug("File::seek() -- Failed to set the file pointer."); } #else diff --git a/taglib/toolkit/tfilestream.h b/taglib/toolkit/tfilestream.h index 80240ad5..d4d44e95 100644 --- a/taglib/toolkit/tfilestream.h +++ b/taglib/toolkit/tfilestream.h @@ -142,7 +142,7 @@ namespace TagLib { private: class FileStreamPrivate; - NonRefCountPtr d; + FileStreamPrivate *d; }; } diff --git a/taglib/toolkit/tiostream.h b/taglib/toolkit/tiostream.h index 6a439cba..3c9de381 100644 --- a/taglib/toolkit/tiostream.h +++ b/taglib/toolkit/tiostream.h @@ -158,6 +158,8 @@ namespace TagLib { virtual void truncate(offset_t length) = 0; private: + // Noncopyable. Derived classes as well. + IOStream(const IOStream &); IOStream &operator=(const IOStream &); }; diff --git a/taglib/toolkit/tlist.h b/taglib/toolkit/tlist.h index 51fb8576..c33c9566 100644 --- a/taglib/toolkit/tlist.h +++ b/taglib/toolkit/tlist.h @@ -27,7 +27,6 @@ #define TAGLIB_LIST_H #include "taglib.h" -#include "tsmartptr.h" #include namespace TagLib { @@ -70,17 +69,6 @@ namespace TagLib { */ List(const List &l); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a l into this List. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - List(List &&l); - -#endif - /*! * Destroys this List instance. If auto deletion is enabled and this list * contains a pointer type all of the memebers are also deleted. @@ -135,26 +123,6 @@ namespace TagLib { */ List &append(const List &l); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Appends \a item to the end of the list and returns a reference to the - * list. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - List &append(T &&item); - - /*! - * Appends all of the values in \a l to the end of the list and returns a - * reference to the list. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - List &append(List &&l); - -#endif - /*! * Prepends \a item to the beginning list and returns a reference to the * list. @@ -167,26 +135,6 @@ namespace TagLib { */ List &prepend(const List &l); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Prepends \a item to the beginning list and returns a reference to the - * list. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - List &prepend(T &&item); - - /*! - * Prepends all of the items in \a l to the beginning list and returns a - * reference to the list. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - List &prepend(List &&l); - -#endif - /*! * Clears the list. If auto deletion is enabled and this list contains a * pointer type the members are also deleted. @@ -275,17 +223,6 @@ namespace TagLib { */ List &operator=(const List &l); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a l into this List. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - List &operator=(List &&l); - -#endif - /*! * Compares this list with \a l and returns true if all of the elements are * the same. @@ -308,7 +245,7 @@ namespace TagLib { private: #ifndef DO_NOT_DOCUMENT template class ListPrivate; - RefCountPtr > d; + ListPrivate *d; #endif }; diff --git a/taglib/toolkit/tlist.tcc b/taglib/toolkit/tlist.tcc index 17dc642b..a9e74a61 100644 --- a/taglib/toolkit/tlist.tcc +++ b/taglib/toolkit/tlist.tcc @@ -1,3 +1,4 @@ + /*************************************************************************** copyright : (C) 2002 - 2008 by Scott Wheeler email : wheeler@kde.org @@ -23,8 +24,8 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#include #include +#include "trefcounter.h" namespace TagLib { @@ -36,34 +37,30 @@ namespace TagLib { // template specialization. This is implemented in such a way that calling // setAutoDelete() on non-pointer types will simply have no effect. -// A base for the generic and specialized private class types. New -// non-templatized members should be added here. - -class ListPrivateBase -{ -public: - ListPrivateBase() : autoDelete(false) {} - bool autoDelete; -}; - // A generic implementation template -template class List::ListPrivate : public ListPrivateBase +template class List::ListPrivate : public RefCounter { public: - ListPrivate() : ListPrivateBase() {} - ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} + ListPrivate() + { + } -#ifdef TAGLIB_USE_MOVE_SEMANTICS + ListPrivate(const std::list &l) + : list(l) + { + } - ListPrivate(std::list &&l) : ListPrivateBase(), list(l) {} - -#endif - - void clear() { + void clear() + { std::list().swap(list); } + + void setAutoDelete(bool) + { + } + std::list list; }; @@ -71,38 +68,49 @@ public: // setAutoDelete() functionality. template -template class List::ListPrivate : public ListPrivateBase +template class List::ListPrivate : public RefCounter { public: - ListPrivate() : ListPrivateBase() {} - ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} + ListPrivate() + : autoDelete(false) + { + } -#ifdef TAGLIB_USE_MOVE_SEMANTICS + ListPrivate(const std::list &l) + : list(l) + , autoDelete(false) + { + } - ListPrivate(std::list &&l) : ListPrivateBase(), list(l) {} - -#endif - - ~ListPrivate() { + ~ListPrivate() + { deletePointers(); } - void clear() { + void clear() + { deletePointers(); std::list().swap(list); } + void setAutoDelete(bool del) + { + autoDelete = del; + } + std::list list; private: - void deletePointers() { - if(!autoDelete) - return; - - typename std::list::const_iterator it = list.begin(); - for(; it != list.end(); ++it) - delete *it; + void deletePointers() + { + if(autoDelete) { + typename std::list::const_iterator it = list.begin(); + for(; it != list.end(); ++it) + delete *it; + } } + + bool autoDelete; }; //////////////////////////////////////////////////////////////////////////////// @@ -111,29 +119,22 @@ private: template List::List() - : d(new ListPrivate()) + : d(new ListPrivate()) { } template List::List(const List &l) -: d(l.d) + : d(l.d) { + d->ref(); } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -template -List::List(List &&l) - : d(std::move(l.d)) -{ -} - -#endif - template List::~List() { + if(d->deref()) + delete d; } template @@ -198,29 +199,6 @@ List &List::append(const List &l) return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -template -List &List::append(T &&item) -{ - detach(); - d->list.push_back(item); - return *this; -} - -template -List &List::append(List &&l) -{ - detach(); - - for(Iterator it = l.begin(); it != l.end(); ++it) - d->list.push_back(std::move(*it)); - - return *this; -} - -#endif - template List &List::prepend(const T &item) { @@ -233,33 +211,10 @@ template List &List::prepend(const List &l) { detach(); - d->list.insert(d->list.begin(), l.d->list.begin(), l.d->list.end()); + d->list.insert(d->list.begin(), l.begin(), l.end()); return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -template -List &List::prepend(T &&item) -{ - detach(); - d->list.push_front(item); - return *this; -} - -template -List &List::prepend(List &&l) -{ - detach(); - - for(typename std::list::reverse_iterator it = l.d->list.rbegin(); it != l.d->list.rend(); ++it) - d->list.push_front(std::move(*it)); - - return *this; -} - -#endif - template List &List::clear() { @@ -329,7 +284,7 @@ const T &List::back() const template void List::setAutoDelete(bool autoDelete) { - d->autoDelete = autoDelete; + d->setAutoDelete(autoDelete); } template @@ -364,21 +319,16 @@ const T &List::operator[](size_t i) const template List &List::operator=(const List &l) { + if(&l == this) + return *this; + + if(d->deref()) + delete d; d = l.d; + d->ref(); return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -template -List &List::operator=(List &&l) -{ - d = std::move(l.d); - return *this; -} - -#endif - template bool List::operator==(const List &l) const { @@ -398,8 +348,11 @@ bool List::operator!=(const List &l) const template void List::detach() { - if(!d.unique()) - d.reset(new ListPrivate(d->list)); + if(!d->unique()) { + d->deref(); + d = new ListPrivate(d->list); + } } } // namespace TagLib + diff --git a/taglib/toolkit/tmap.h b/taglib/toolkit/tmap.h index f291226f..74069ada 100644 --- a/taglib/toolkit/tmap.h +++ b/taglib/toolkit/tmap.h @@ -27,7 +27,6 @@ #define TAGLIB_MAP_H #include "taglib.h" -#include "tsmartptr.h" #include namespace TagLib { @@ -42,7 +41,7 @@ namespace TagLib { template class Map { - public: + private: #ifndef DO_NOT_DOCUMENT #ifdef WANT_CLASS_INSTANTIATION_OF_MAP // Some STL implementations get snippy over the use of the @@ -53,14 +52,18 @@ namespace TagLib { // Not all the specializations of Map can use the class keyword // (when T is not actually a class type), so don't apply this // generally. - typedef typename std::map::iterator Iterator; - typedef typename std::map::const_iterator ConstIterator; + typedef std::map MapType; #else - typedef typename std::map::iterator Iterator; - typedef typename std::map::const_iterator ConstIterator; + typedef std::map MapType; #endif #endif + public: +#ifndef DO_NOT_DOCUMENT + typedef typename MapType::iterator Iterator; + typedef typename MapType::const_iterator ConstIterator; +#endif + /*! * Constructs an empty Map. */ @@ -73,17 +76,6 @@ namespace TagLib { */ Map(const Map &m); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a m into this Map. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - Map(Map &&m); - -#endif - /*! * Destroys this instance of the Map. */ @@ -119,18 +111,6 @@ namespace TagLib { */ Map &insert(const Key &key, const T &value); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Inserts \a value under \a key in the map. If a value for \a key already - * exists it will be overwritten. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - Map &insert(const Key &key, T &&value); - -#endif - /*! * Removes all of the elements from elements from the map. This however * will not delete pointers if the mapped type is a pointer type. @@ -197,17 +177,6 @@ namespace TagLib { */ Map &operator=(const Map &m); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a m into this Map. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - Map &operator=(Map &&m); - -#endif - protected: /* * If this List is being shared via implicit sharing, do a deep copy of the @@ -219,8 +188,7 @@ namespace TagLib { private: #ifndef DO_NOT_DOCUMENT template class MapPrivate; - RefCountPtr > d; - + MapPrivate *d; #endif }; } diff --git a/taglib/toolkit/tmap.tcc b/taglib/toolkit/tmap.tcc index e1c7ac6d..d388fb2d 100644 --- a/taglib/toolkit/tmap.tcc +++ b/taglib/toolkit/tmap.tcc @@ -23,6 +23,8 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ +#include "trefcounter.h" + namespace TagLib { //////////////////////////////////////////////////////////////////////////////// @@ -31,44 +33,21 @@ namespace TagLib { template template -class Map::MapPrivate +class Map::MapPrivate : public RefCounter { public: - MapPrivate() {} - -#ifdef WANT_CLASS_INSTANTIATION_OF_MAP - - MapPrivate(const std::map &m) : RefCounter(), map(m) {} - -# ifdef TAGLIB_USE_MOVE_SEMANTICS - - MapPrivate(std::map &&m) : RefCounter(), map(m) {} - -# endif - - void clear() { - std::map().swap(map); + MapPrivate() + : RefCounter() + { } - std::map map; - -#else - - MapPrivate(const std::map& m) : map(m) {} - -# ifdef TAGLIB_USE_MOVE_SEMANTICS - - MapPrivate(std::map &&m) : map(m) {} - -# endif - - void clear() { - std::map().swap(map); + MapPrivate(const MapType &m) + : RefCounter() + , map(m) + { } - - std::map map; - -#endif + + MapType map; }; template @@ -78,24 +57,16 @@ Map::Map() } template -Map::Map(const Map &m) - : d(m.d) +Map::Map(const Map &m) : d(m.d) { + d->ref(); } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -template -TagLib::Map::Map(Map &&m) - : d(std::move(m.d)) -{ -} - -#endif - template Map::~Map() { + if(d->deref()) + delete d; } template @@ -132,18 +103,6 @@ Map &Map::insert(const Key &key, const T &value) return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -template -Map &Map::insert(const Key &key, T &&value) -{ - detach(); - d->map[key] = value; - return *this; -} - -#endif - template Map &Map::clear() { @@ -217,21 +176,16 @@ T &Map::operator[](const Key &key) template Map &Map::operator=(const Map &m) { + if(&m == this) + return *this; + + if(d->deref()) + delete(d); d = m.d; + d->ref(); return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -template -Map &Map::operator=(Map &&m) -{ - d = std::move(m.d); - return *this; -} - -#endif - //////////////////////////////////////////////////////////////////////////////// // protected members //////////////////////////////////////////////////////////////////////////////// @@ -239,8 +193,12 @@ Map &Map::operator=(Map &&m) template void Map::detach() { - if(!d.unique()) - d.reset(new MapPrivate(d->map)); + if(!d->unique()) { + d->deref(); + d = new MapPrivate(d->map); + } } } // namespace TagLib + + diff --git a/taglib/toolkit/tsmartptr.cpp b/taglib/toolkit/trefcounter.cpp similarity index 84% rename from taglib/toolkit/tsmartptr.cpp rename to taglib/toolkit/trefcounter.cpp index 87ad6ee3..495c2529 100644 --- a/taglib/toolkit/tsmartptr.cpp +++ b/taglib/toolkit/trefcounter.cpp @@ -23,14 +23,8 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#include "taglib_config.h" - -#if !defined(TAGLIB_USE_STD_SHARED_PTR) \ - && !defined(TAGLIB_USE_TR1_SHARED_PTR) \ - && !defined(TAGLIB_USE_BOOST_SHARED_PTR) - #include "config.h" -#include "tsmartptr.h" +#include "trefcounter.h" #if defined(HAVE_STD_ATOMIC) # include @@ -72,10 +66,10 @@ namespace TagLib { - class CounterBase::CounterBasePrivate + class RefCounter::RefCounterPrivate { public: - CounterBasePrivate() + RefCounterPrivate() : refCount(1) { } @@ -83,33 +77,28 @@ namespace TagLib volatile ATOMIC_INT refCount; }; - CounterBase::CounterBase() - : d(new CounterBasePrivate()) + RefCounter::RefCounter() + : d(new RefCounterPrivate()) { } - CounterBase::~CounterBase() + RefCounter::~RefCounter() { delete d; } - void CounterBase::addref() - { + void RefCounter::ref() + { ATOMIC_INC(d->refCount); } - void CounterBase::release() - { - if(ATOMIC_DEC(d->refCount) == 0) { - dispose(); - delete this; - } + bool RefCounter::deref() + { + return (ATOMIC_DEC(d->refCount) == 0); } - long CounterBase::use_count() const - { - return static_cast(d->refCount); + bool RefCounter::unique() const + { + return (d->refCount == 1); } } - -#endif diff --git a/taglib/toolkit/trefcounter.h b/taglib/toolkit/trefcounter.h new file mode 100644 index 00000000..1b7fe4a0 --- /dev/null +++ b/taglib/toolkit/trefcounter.h @@ -0,0 +1,54 @@ +/*************************************************************************** + copyright : (C) 2013 by Tsuda Kageyu + email : tsuda.kageyu@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_REFCOUNTER_H +#define TAGLIB_REFCOUNTER_H + +#include "taglib.h" + +#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class. +/*! + * \warning This is not part of the TagLib public API! + */ +namespace TagLib +{ + class RefCounter + { + public: + RefCounter(); + virtual ~RefCounter(); + + void ref(); + bool deref(); + bool unique() const; + + private: + class RefCounterPrivate; + RefCounterPrivate *d; + }; +} + +#endif // DO_NOT_DOCUMENT +#endif diff --git a/taglib/toolkit/tsmartptr.h b/taglib/toolkit/tsmartptr.h index c3532195..c89609f6 100644 --- a/taglib/toolkit/tsmartptr.h +++ b/taglib/toolkit/tsmartptr.h @@ -26,179 +26,64 @@ #ifndef TAGLIB_SMARTPTR_H #define TAGLIB_SMARTPTR_H -#include "taglib_config.h" -#include +// This file is not a part of TagLib public interface. This is not installed. -#if defined(TAGLIB_USE_STD_SHARED_PTR) -# include -#elif defined(TAGLIB_USE_TR1_SHARED_PTR) -# include -#elif defined(TAGLIB_USE_BOOST_SHARED_PTR) -# include -#endif - -#if defined(TAGLIB_USE_STD_UNIQUE_PTR) -# include -#elif defined(TAGLIB_USE_BOOST_SCOPED_PTR) -# include -#endif +#include "config.h" #ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class. /*! * \warning This is not part of the TagLib public API! */ +#if defined(HAVE_STD_SHARED_PTR) + +# include +# define SHARED_PTR std::shared_ptr + +#elif defined(HAVE_TR1_SHARED_PTR) + +# include +# define SHARED_PTR std::tr1::shared_ptr + +#elif defined(HAVE_BOOST_SHARED_PTR) + +# include +# define SHARED_PTR boost::shared_ptr + +#else // HAVE_STD_SHARED_PTR + +# include + +# if defined(HAVE_GCC_ATOMIC) +# define ATOMIC_INT int +# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1) +# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1) +# elif defined(HAVE_WIN_ATOMIC) +# if !defined(NOMINMAX) +# define NOMINMAX +# endif +# include +# define ATOMIC_INT long +# define ATOMIC_INC(x) InterlockedIncrement(&x) +# define ATOMIC_DEC(x) InterlockedDecrement(&x) +# elif defined(HAVE_MAC_ATOMIC) +# include +# define ATOMIC_INT int32_t +# define ATOMIC_INC(x) OSAtomicIncrement32Barrier(&x) +# define ATOMIC_DEC(x) OSAtomicDecrement32Barrier(&x) +# elif defined(HAVE_IA64_ATOMIC) +# include +# define ATOMIC_INT int +# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1) +# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1) +# else +# define ATOMIC_INT int +# define ATOMIC_INC(x) (++x) +# define ATOMIC_DEC(x) (--x) +# endif + namespace TagLib { -#if defined(TAGLIB_USE_STD_SHARED_PTR) \ - || defined(TAGLIB_USE_TR1_SHARED_PTR) \ - || defined(TAGLIB_USE_BOOST_SHARED_PTR) - - // RefCountPtr is just a thin wrapper of shared_ptr. - // It will be optimized out by compilers and performs equivalent to them. - - template - class RefCountPtr - { - public: - RefCountPtr() - : sp() - { - } - - template - explicit RefCountPtr(U *p) - : sp(p) - { - } - - RefCountPtr(const RefCountPtr &x) - : sp(x.sp) - { - } - - template - RefCountPtr(const RefCountPtr &x) - : sp(x.sp) - { - } - -# ifdef TAGLIB_USE_MOVE_SEMANTICS - - RefCountPtr(RefCountPtr &&x) - : sp(std::move(x.sp)) - { - } - - template - RefCountPtr(RefCountPtr &&x) - : sp(std::move(x.sp)) - { - } - -# endif - - T *get() const - { - return sp.get(); - } - - long use_count() const - { - return sp.use_count(); - } - - bool unique() const - { - return sp.unique(); - } - - template - void reset(U *p) - { - sp.reset(p); - } - - void reset() - { - sp.reset(); - } - - void swap(RefCountPtr &x) - { - sp.swap(x.sp); - } - - RefCountPtr &operator=(const RefCountPtr &x) - { - sp = x.sp; - return *this; - } - - template - RefCountPtr &operator=(const RefCountPtr &x) - { - sp = x.sp; - return *this; - } - -# ifdef TAGLIB_USE_MOVE_SEMANTICS - - RefCountPtr &operator=(RefCountPtr &&x) - { - sp = std::move(x.sp); - return *this; - } - - template - RefCountPtr &operator=(RefCountPtr &&x) - { - sp = std::move(x.sp); - return *this; - } - -# endif - - T& operator*() const - { - return sp.operator*(); - } - - T* operator->() const - { - return sp.operator->(); - } - - operator bool() const - { - return static_cast(sp); - } - - bool operator!() const - { - return !static_cast(sp); - } - - private: - template friend class RefCountPtr; - -# if defined(TAGLIB_USE_STD_SHARED_PTR) - - std::shared_ptr sp; - -# elif defined(TAGLIB_USE_TR1_SHARED_PTR) - - std::tr1::shared_ptr sp; - -# else - - boost::shared_ptr sp; - -# endif - }; - -#else // TAGLIB_USE_STD_SHARED_PTR etc. - // Self-implements RefCountPtr if shared_ptr is not available. // I STRONGLY RECOMMEND using standard shared_ptr rather than this class. @@ -207,18 +92,37 @@ namespace TagLib class CounterBase { public: - CounterBase(); - virtual ~CounterBase(); + CounterBase() + : refCount(1) + { + } - void addref(); - void release(); - long use_count() const; + virtual ~CounterBase() + { + } + + void addref() + { + ATOMIC_INC(refCount); + } + + void release() + { + if(ATOMIC_DEC(refCount) == 0) { + dispose(); + delete this; + } + } + + long use_count() const + { + return static_cast(refCount); + } virtual void dispose() = 0; private: - class CounterBasePrivate; - CounterBasePrivate *d; + volatile ATOMIC_INT refCount; }; // Counter impl class. Provides a dynamic deleter. @@ -380,83 +284,45 @@ namespace TagLib template friend class RefCountPtr; }; -#endif // TAGLIB_USE_STD_SHARED_PTR etc. - -#if defined(TAGLIB_USE_STD_UNIQUE_PTR) || defined(TAGLIB_USE_BOOST_SCOPED_PTR) - - // NonRefCountPtr is just a thin wrapper of unique_ptr or scoped_ptr. - // It will be optimized out by compilers and performs equivalent to them. - - template - class NonRefCountPtr + template + bool operator==(const RefCountPtr &a, const RefCountPtr &b) { - public: - explicit NonRefCountPtr(T *p = 0) - : up(p) - { - } + return (a.get() == b.get()); + } - ~NonRefCountPtr() - { - } + template + bool operator!=(const RefCountPtr &a, const RefCountPtr &b) + { + return (a.get() != b.get()); + } - void reset(T *p = 0) - { - NonRefCountPtr(p).swap(*this); - } + template + void swap(RefCountPtr &a, RefCountPtr &b) + { + a.swap(b); + } +} - T &operator*() const - { - return up.operator*(); - } +# define SHARED_PTR TagLib::RefCountPtr - T *operator->() const - { - return up.operator->(); - } +#endif // HAVE_STD_SHARED_PTR etc. - T *get() const - { - return up.get(); - } +#if defined(HAVE_STD_UNIQUE_PTR) - operator bool() const - { - return static_cast(up); - } +# include +# define SCOPED_PTR std::unique_ptr - bool operator!() const - { - return !static_cast(up); - } +#elif defined(HAVE_BOOST_SCOPED_PTR) - void swap(NonRefCountPtr &x) - { - up.swap(x.up); - } +# include +# define SCOPED_PTR boost::scoped_ptr - private: - - // Noncopyable - NonRefCountPtr(const NonRefCountPtr &); - NonRefCountPtr &operator=(const NonRefCountPtr &); - - void operator==(const NonRefCountPtr &) const; - void operator!=(const NonRefCountPtr &) const; - -# if defined(TAGLIB_USE_STD_UNIQUE_PTR) - - std::unique_ptr up; - -# else - - boost::scoped_ptr up; - -# endif - }; - -#else // TAGLIB_USE_STD_UNIQUE_PTR +#else // HAVE_STD_UNIQUE_PTR + +# include +namespace TagLib +{ // Self-implements NonRefCountPtr if unique_ptr is not available. // I STRONGLY RECOMMEND using standard unique_ptr rather than this class. @@ -522,34 +388,6 @@ namespace TagLib T *px; }; -#endif // TAGLIB_USE_STD_UNIQUE_PTR - - // Comparison operators for smart pointers. - - template - bool operator==(const RefCountPtr &a, const RefCountPtr &b) - { - return (a.get() == b.get()); - } - - template - bool operator!=(const RefCountPtr &a, const RefCountPtr &b) - { - return (a.get() != b.get()); - } - - template - bool operator==(const RefCountPtr &a, U *b) - { - return (a.get() == b); - } - - template - bool operator!=(const RefCountPtr &a, U *b) - { - return (a.get() != b); - } - template bool operator==(const NonRefCountPtr &a, U *b) { @@ -562,42 +400,17 @@ namespace TagLib return (a.get() != b); } - template - bool operator==(T *a, const RefCountPtr &b) - { - return (a == b.get()); - } - - template - bool operator!=(T *a, const RefCountPtr &b) - { - return (a != b.get()); - } - - template - bool operator==(T *a, const NonRefCountPtr &b) - { - return (a == b.get()); - } - - template - bool operator!=(T *a, const NonRefCountPtr &b) - { - return (a != b.get()); - } - template - void swap(RefCountPtr &a, RefCountPtr &b) - { - a.swap(b); - } - - template - void swap(NonRefCountPtr &a, NonRefCountPtr &b) + void swap(NonRefCountPtr &a, NonRefCountPtr &b) { a.swap(b); } } +# define SCOPED_PTR TagLib::NonRefCountPtr + +#endif // HAVE_STD_UNIQUE_PTR etc. + + #endif // DO_NOT_DOCUMENT #endif diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index 36c6f12f..88cd3e6f 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -30,6 +30,7 @@ #include "tstring.h" #include "tdebug.h" #include "tstringlist.h" +#include "tsmartptr.h" #include #include @@ -185,38 +186,30 @@ namespace TagLib { class String::StringPrivate { public: - StringPrivate() + StringPrivate() + : data(new std::wstring()) { } StringPrivate(const std::wstring &s) - : data(s) + : data(new std::wstring(s)) { } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - StringPrivate(std::wstring &&s) - : data(s) - { - } - -#endif - StringPrivate(size_t n, wchar_t c) - : data(n, c) + : data(new std::wstring(n, c)) { } /*! * Stores string in UTF-16. The byte order depends on the CPU endian. */ - std::wstring data; + SHARED_PTR data; /*! * This is only used to hold the the most recent value of toCString(). */ - std::string cstring; + SHARED_PTR cstring; }; const String String::null; @@ -232,19 +225,10 @@ String::String() } String::String(const String &s) - : d(s.d) + : d(new StringPrivate(*s.d)) { } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -String::String(String &&s) - : d(std::move(s.d)) -{ -} - -#endif - String::String(const std::string &s, Type t) : d(new StringPrivate()) { @@ -325,6 +309,7 @@ String::String(const ByteVector &v, Type t) String::~String() { + delete d; } std::string String::to8Bit(bool unicode) const @@ -332,18 +317,18 @@ std::string String::to8Bit(bool unicode) const std::string s; if(!unicode) { - s.resize(d->data.size()); + s.resize(d->data->size()); std::string::iterator targetIt = s.begin(); - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) { + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { *targetIt = static_cast(*it); ++targetIt; } } else { - s.resize(d->data.size() * 4 + 1); + s.resize(d->data->size() * 4 + 1); - UTF16toUTF8(&d->data[0], d->data.size(), &s[0], s.size()); + UTF16toUTF8(&(*d->data)[0], d->data->size(), &s[0], s.size()); s.resize(::strlen(s.c_str())); } @@ -352,43 +337,43 @@ std::string String::to8Bit(bool unicode) const const std::wstring &String::toWString() const { - return d->data; + return *d->data; } const char *String::toCString(bool unicode) const { - d->cstring = to8Bit(unicode); - return d->cstring.c_str(); + d->cstring.reset(new std::string(to8Bit(unicode))); + return d->cstring->c_str(); } String::Iterator String::begin() { - return d->data.begin(); + return d->data->begin(); } String::ConstIterator String::begin() const { - return d->data.begin(); + return d->data->begin(); } String::Iterator String::end() { - return d->data.end(); + return d->data->end(); } String::ConstIterator String::end() const { - return d->data.end(); + return d->data->end(); } size_t String::find(const String &s, size_t offset) const { - return d->data.find(s.d->data, offset); + return d->data->find(*s.d->data, offset); } size_t String::rfind(const String &s, size_t offset) const { - return d->data.rfind(s.d->data, offset); + return d->data->rfind(*s.d->data, offset); } StringList String::split(const String &separator) const @@ -421,13 +406,13 @@ bool String::startsWith(const String &s) const String String::substr(size_t position, size_t length) const { - return String(d->data.substr(position, length)); + return String(d->data->substr(position, length)); } String &String::append(const String &s) { detach(); - d->data += s.d->data; + *d->data += *s.d->data; return *this; } @@ -435,15 +420,10 @@ String String::upper() const { static const int shift = 'A' - 'a'; - String s; - s.d->data.resize(d->data.size()); - - wchar_t *p = &s.d->data[0]; - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); ++it) { + String s(*this); + for(Iterator it = s.begin(); it != s.end(); ++it) { if(*it >= 'a' && *it <= 'z') - *p++ = *it + shift; - else - *p++ = *it; + *it = *it + shift; } return s; @@ -451,7 +431,7 @@ String String::upper() const size_t String::size() const { - return d->data.size(); + return d->data->size(); } size_t String::length() const @@ -461,7 +441,7 @@ size_t String::length() const bool String::isEmpty() const { - return d->data.empty(); + return d->data->empty(); } bool String::isNull() const @@ -478,7 +458,7 @@ ByteVector String::data(Type t) const ByteVector v(size(), 0); char *p = v.data(); - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) *p++ = static_cast(*it); return v; @@ -487,7 +467,7 @@ ByteVector String::data(Type t) const { ByteVector v(size() * 4 + 1, 0); - UTF16toUTF8(&d->data[0], d->data.size(), v.data(), v.size()); + UTF16toUTF8(&(*d->data)[0], d->data->size(), v.data(), v.size()); v.resize(::strlen(v.data())); return v; @@ -503,7 +483,7 @@ ByteVector String::data(Type t) const *p++ = '\xff'; *p++ = '\xfe'; - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) { + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { *p++ = static_cast(*it & 0xff); *p++ = static_cast(*it >> 8); } @@ -515,7 +495,7 @@ ByteVector String::data(Type t) const ByteVector v(size() * 2, 0); char *p = v.data(); - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) { + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { *p++ = static_cast(*it >> 8); *p++ = static_cast(*it & 0xff); } @@ -527,7 +507,7 @@ ByteVector String::data(Type t) const ByteVector v(size() * 2, 0); char *p = v.data(); - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) { + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { *p++ = static_cast(*it & 0xff); *p++ = static_cast(*it >> 8); } @@ -546,13 +526,13 @@ int String::toInt(bool *ok) const { int value = 0; - const size_t size = d->data.size(); - const bool negative = size > 0 && d->data[0] == '-'; + const size_t size = d->data->size(); + const bool negative = size > 0 && (*d->data)[0] == '-'; const size_t start = negative ? 1 : 0; size_t i = start; - for(; i < size && d->data[i] >= '0' && d->data[i] <= '9'; i++) - value = value * 10 + (d->data[i] - '0'); + for(; i < size && (*d->data)[i] >= '0' && (*d->data)[i] <= '9'; i++) + value = value * 10 + ((*d->data)[i] - '0'); if(negative) value = value * -1; @@ -565,8 +545,8 @@ int String::toInt(bool *ok) const String String::stripWhiteSpace() const { - std::wstring::const_iterator begin = d->data.begin(); - std::wstring::const_iterator end = d->data.end(); + std::wstring::const_iterator begin = d->data->begin(); + std::wstring::const_iterator end = d->data->end(); while(begin != end && (*begin == '\t' || *begin == '\n' || *begin == '\f' || @@ -591,7 +571,7 @@ String String::stripWhiteSpace() const bool String::isLatin1() const { - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) { + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { if(*it >= 256) return false; } @@ -600,7 +580,7 @@ bool String::isLatin1() const bool String::isAscii() const { - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) { + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { if(*it >= 128) return false; } @@ -638,22 +618,22 @@ String String::number(int n) // static TagLib::wchar &String::operator[](size_t i) { detach(); - return d->data[i]; + return (*d->data)[i]; } const TagLib::wchar &String::operator[](size_t i) const { - return d->data[i]; + return (*d->data)[i]; } bool String::operator==(const String &s) const { - return (d == s.d || d->data == s.d->data); + return (d->data == s.d->data || *d->data == *s.d->data); } bool String::operator==(const char *s) const { - for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) { + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { if(*it != static_cast(*s)) return false; @@ -665,7 +645,7 @@ bool String::operator==(const char *s) const bool String::operator==(const wchar_t *s) const { - return (d->data == s); + return (*d->data == s); } bool String::operator!=(const String &s) const @@ -677,7 +657,7 @@ String &String::operator+=(const String &s) { detach(); - d->data += s.d->data; + *d->data += *s.d->data; return *this; } @@ -685,7 +665,7 @@ String &String::operator+=(const wchar_t *s) { detach(); - d->data += s; + *d->data += *s; return *this; } @@ -694,7 +674,7 @@ String &String::operator+=(const char *s) detach(); for(int i = 0; s[i] != 0; i++) - d->data += uchar(s[i]); + *d->data += uchar(s[i]); return *this; } @@ -702,7 +682,7 @@ String &String::operator+=(wchar_t c) { detach(); - d->data += c; + *d->data += c; return *this; } @@ -710,29 +690,19 @@ String &String::operator+=(char c) { detach(); - d->data += uchar(c); + *d->data += uchar(c); return *this; } String &String::operator=(const String &s) { - d = s.d; + *d = *s.d; return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -String &String::operator=(String &&s) -{ - d = std::move(s.d); - return *this; -} - -#endif - String &String::operator=(const std::string &s) { - d.reset(new StringPrivate()); + d->data.reset(new std::wstring()); copyFromLatin1(s.c_str(), s.length()); return *this; @@ -740,23 +710,13 @@ String &String::operator=(const std::string &s) String &String::operator=(const std::wstring &s) { - d.reset(new StringPrivate(s)); + d->data.reset(new std::wstring(s)); return *this; } -#ifdef TAGLIB_USE_MOVE_SEMANTICS - -String &String::operator=(std::wstring &&s) -{ - d.reset(new StringPrivate(s)); - return *this; -} - -#endif - String &String::operator=(const wchar_t *s) { - d.reset(new StringPrivate()); + d->data.reset(new std::wstring()); copyFromUTF16(s, ::wcslen(s), WCharByteOrder); return *this; @@ -764,19 +724,19 @@ String &String::operator=(const wchar_t *s) String &String::operator=(char c) { - d.reset(new StringPrivate(1, static_cast(c))); + d->data.reset(new std::wstring(1, c)); return *this; } String &String::operator=(wchar_t c) { - d.reset(new StringPrivate(1, c)); + d->data.reset(new std::wstring(1, c)); return *this; } String &String::operator=(const char *s) { - d.reset(new StringPrivate()); + d->data.reset(new std::wstring()); copyFromLatin1(s, ::strlen(s)); return *this; @@ -784,18 +744,18 @@ String &String::operator=(const char *s) String &String::operator=(const ByteVector &v) { - d.reset(new StringPrivate()); + d->data.reset(new std::wstring()); copyFromLatin1(v.data(), v.size()); // If we hit a null in the ByteVector, shrink the string again. - d->data.resize(::wcslen(d->data.c_str())); + d->data->resize(::wcslen(d->data->c_str())); return *this; } bool String::operator<(const String &s) const { - return d->data < s.d->data; + return *d->data < *s.d->data; } //////////////////////////////////////////////////////////////////////////////// @@ -804,8 +764,8 @@ bool String::operator<(const String &s) const void String::detach() { - if(!d.unique()) - d.reset(new StringPrivate(d->data)); + if(!d->data.unique()) + d->data.reset(new std::wstring(*d->data)); } //////////////////////////////////////////////////////////////////////////////// @@ -814,18 +774,18 @@ void String::detach() void String::copyFromLatin1(const char *s, size_t length) { - d->data.resize(length); + d->data->resize(length); for(size_t i = 0; i < length; ++i) - d->data[i] = static_cast(s[i]); + (*d->data)[i] = static_cast(s[i]); } void String::copyFromUTF8(const char *s, size_t length) { - d->data.resize(length); + d->data->resize(length); - UTF8toUTF16(s, length, &d->data[0], d->data.size()); - d->data.resize(::wcslen(d->data.c_str())); + UTF8toUTF16(s, length, &(*d->data)[0], d->data->size()); + d->data->resize(::wcslen(d->data->c_str())); } void String::copyFromUTF16(const wchar_t *s, size_t length, Type t) @@ -847,12 +807,12 @@ void String::copyFromUTF16(const wchar_t *s, size_t length, Type t) else swap = (t != WCharByteOrder); - d->data.resize(length); - memcpy(&d->data[0], s, length * sizeof(wchar_t)); + d->data->resize(length); + memcpy(&(*d->data)[0], s, length * sizeof(wchar_t)); if(swap) { for(size_t i = 0; i < length; ++i) - d->data[i] = byteSwap(static_cast(s[i])); + (*d->data)[i] = byteSwap(static_cast(s[i])); } } @@ -884,9 +844,9 @@ void String::copyFromUTF16(const char *s, size_t length, Type t) else swap = (t != WCharByteOrder); - d->data.resize(length / 2); + d->data->resize(length / 2); for(size_t i = 0; i < length / 2; ++i) { - d->data[i] = swap ? combine(*s, *(s + 1)) : combine(*(s + 1), *s); + (*d->data)[i] = swap ? combine(*s, *(s + 1)) : combine(*(s + 1), *s); s += 2; } } diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index 3da8814b..b463eff2 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -119,17 +119,6 @@ namespace TagLib { */ String(const String &s); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Constructs a String equivalent to \a s. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - String(String &&s); - -#endif - /*! * Makes a deep copy of the data in \a s. * @@ -403,17 +392,6 @@ namespace TagLib { */ String &operator=(const String &s); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a s into this String. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - String &operator=(String &&s); - -#endif - /*! * Performs a deep copy of the data in \a s. */ @@ -424,17 +402,6 @@ namespace TagLib { */ String &operator=(const std::wstring &s); -#ifdef TAGLIB_USE_MOVE_SEMANTICS - - /*! - * Moves \a s into this String. - * - * \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined. - */ - String &operator=(std::wstring &&s); - -#endif - /*! * Performs a deep copy of the data in \a s. */ @@ -520,7 +487,7 @@ namespace TagLib { static const Type WCharByteOrder; class StringPrivate; - RefCountPtr d; + StringPrivate *d; }; /*! diff --git a/tests/test_smartptr.cpp b/tests/test_smartptr.cpp index 49165d07..7ca2ab55 100644 --- a/tests/test_smartptr.cpp +++ b/tests/test_smartptr.cpp @@ -26,7 +26,7 @@ public: void testSharedptrBasic() { int * ip = new int; - RefCountPtr cp ( ip ); + SHARED_PTR cp ( ip ); CPPUNIT_ASSERT( ip == cp.get() ); CPPUNIT_ASSERT( cp.use_count() == 1 ); @@ -36,7 +36,7 @@ public: ck( static_cast(cp.get()), 54321 ); ck( static_cast(ip), *cp ); - RefCountPtr cp2 ( cp ); + SHARED_PTR cp2 ( cp ); CPPUNIT_ASSERT( ip == cp2.get() ); CPPUNIT_ASSERT( cp.use_count() == 2 ); CPPUNIT_ASSERT( cp2.use_count() == 2 ); @@ -46,7 +46,7 @@ public: ck( static_cast(cp2.get()), 54321 ); ck( static_cast(ip), *cp2 ); - RefCountPtr cp3 ( cp ); + SHARED_PTR cp3 ( cp ); CPPUNIT_ASSERT( cp.use_count() == 3 ); CPPUNIT_ASSERT( cp2.use_count() == 3 ); CPPUNIT_ASSERT( cp3.use_count() == 3 ); @@ -76,16 +76,16 @@ public: CPPUNIT_ASSERT( cp.use_count() == 3 ); CPPUNIT_ASSERT( *cp == 87654 ); - RefCountPtr cp4; + SHARED_PTR cp4; swap( cp2, cp4 ); CPPUNIT_ASSERT( cp4.use_count() == 3 ); CPPUNIT_ASSERT( *cp4 == 87654 ); CPPUNIT_ASSERT( cp2.get() == 0 ); - std::set< RefCountPtr > scp; + std::set< SHARED_PTR > scp; scp.insert(cp4); CPPUNIT_ASSERT( scp.find(cp4) != scp.end() ); - CPPUNIT_ASSERT( scp.find(cp4) == scp.find( RefCountPtr(cp4) ) ); + CPPUNIT_ASSERT( scp.find(cp4) == scp.find( SHARED_PTR(cp4) ) ); } private: @@ -130,7 +130,7 @@ public: derivedDestructorCalled = false; { - RefCountPtr p1(new DummyDerived(100)); + SHARED_PTR p1(new DummyDerived(100)); CPPUNIT_ASSERT(p1->getValue() == 100); } @@ -141,8 +141,8 @@ public: derivedDestructorCalled = false; { - RefCountPtr p1(new DummyDerived(100)); - RefCountPtr p2 = p1; + SHARED_PTR p1(new DummyDerived(100)); + SHARED_PTR p2 = p1; CPPUNIT_ASSERT(p1->getValue() == 100); CPPUNIT_ASSERT(p2->getValue() == 100); @@ -155,8 +155,8 @@ public: derivedDestructorCalled = false; { - RefCountPtr p1; - RefCountPtr p2; + SHARED_PTR p1; + SHARED_PTR p2; p1.reset(new DummyDerived(100)); p2 = p1; @@ -171,7 +171,7 @@ public: private: class DummyIncomplete; - RefCountPtr pincomplete; + SHARED_PTR pincomplete; class DummyIncomplete {