From c44351aab5035ab1bca41855d0780d9cd3eb69fa Mon Sep 17 00:00:00 2001 From: Tsuda kageyu Date: Wed, 17 Apr 2013 06:39:14 +0900 Subject: [PATCH] RefCounter mimics std::shared_ptr --- taglib/CMakeLists.txt | 1 + taglib/asf/asfattribute.cpp | 25 +--- taglib/asf/asfattribute.h | 7 +- taglib/asf/asfpicture.cpp | 27 +--- taglib/asf/asfpicture.h | 7 +- taglib/fileref.cpp | 55 +------ taglib/fileref.h | 7 +- taglib/mp4/mp4coverart.cpp | 29 +--- taglib/mp4/mp4coverart.h | 7 +- taglib/mp4/mp4item.cpp | 29 +--- taglib/mp4/mp4item.h | 7 +- taglib/mpeg/mpegheader.cpp | 29 +--- taglib/mpeg/mpegheader.h | 8 +- taglib/toolkit/taglib.h | 75 ---------- taglib/toolkit/tbytevector.cpp | 159 ++------------------ taglib/toolkit/tbytevector.h | 11 +- taglib/toolkit/tfile.h | 4 +- taglib/toolkit/tfilestream.h | 2 - taglib/toolkit/tiostream.h | 2 - taglib/toolkit/tlist.h | 9 +- taglib/toolkit/tlist.tcc | 38 +---- taglib/toolkit/tmap.h | 11 +- taglib/toolkit/tmap.tcc | 45 +----- taglib/toolkit/trefcountptr.h | 257 +++++++++++++++++++++++++++++++++ taglib/toolkit/tstring.cpp | 152 ++----------------- taglib/toolkit/tstring.h | 11 +- 26 files changed, 318 insertions(+), 696 deletions(-) create mode 100644 taglib/toolkit/trefcountptr.h diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index 0a2676bd..218edf5b 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -52,6 +52,7 @@ set(tag_HDRS toolkit/tmap.tcc toolkit/tpropertymap.h toolkit/tbyteswap.h + toolkit/trefcountptr.h mpeg/mpegfile.h mpeg/mpegproperties.h mpeg/mpegheader.h diff --git a/taglib/asf/asfattribute.cpp b/taglib/asf/asfattribute.cpp index b4d76dbc..b4195133 100644 --- a/taglib/asf/asfattribute.cpp +++ b/taglib/asf/asfattribute.cpp @@ -34,7 +34,7 @@ using namespace TagLib; -class ASF::Attribute::AttributePrivate : public RefCounter +class ASF::Attribute::AttributePrivate { public: AttributePrivate() @@ -68,11 +68,6 @@ ASF::Attribute::Attribute() ASF::Attribute::Attribute(const ASF::Attribute &other) : d(other.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } ASF::Attribute::Attribute(const String &value) @@ -126,29 +121,11 @@ ASF::Attribute::Attribute(bool value) ASF::Attribute::~Attribute() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) - delete d; - -#endif } ASF::Attribute &ASF::Attribute::operator=(const ASF::Attribute &other) { -#ifdef TAGLIB_USE_CXX11 - d = other.d; - -#else - - if(d->deref()) - delete d; - d = other.d; - d->ref(); - -#endif - return *this; } diff --git a/taglib/asf/asfattribute.h b/taglib/asf/asfattribute.h index a77e05ca..d9ea231a 100644 --- a/taglib/asf/asfattribute.h +++ b/taglib/asf/asfattribute.h @@ -205,12 +205,7 @@ namespace TagLib ByteVector render(const String &name, int kind = 0) const; class AttributePrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - AttributePrivate *d; -#endif + RefCountPtr d; }; } diff --git a/taglib/asf/asfpicture.cpp b/taglib/asf/asfpicture.cpp index aee9e073..6f94e29d 100644 --- a/taglib/asf/asfpicture.cpp +++ b/taglib/asf/asfpicture.cpp @@ -35,7 +35,7 @@ using namespace TagLib; -class ASF::Picture::PicturePrivate : public RefCounter +class ASF::Picture::PicturePrivate { public: bool valid; @@ -58,11 +58,6 @@ ASF::Picture::Picture() ASF::Picture::Picture(const Picture& other) : d(other.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } #ifdef TAGLIB_USE_CXX11 @@ -76,12 +71,6 @@ ASF::Picture::Picture(Picture &&other) ASF::Picture::~Picture() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) - delete d; - -#endif } bool ASF::Picture::isValid() const @@ -138,21 +127,7 @@ int ASF::Picture::dataSize() const ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other) { -#ifdef TAGLIB_USE_CXX11 - d = other.d; - -#else - - if(other.d != d) { - if(d->deref()) - delete d; - d = other.d; - d->ref(); - } - -#endif - return *this; } diff --git a/taglib/asf/asfpicture.h b/taglib/asf/asfpicture.h index a3250a11..84fe1a37 100644 --- a/taglib/asf/asfpicture.h +++ b/taglib/asf/asfpicture.h @@ -231,12 +231,7 @@ namespace TagLib #endif private: class PicturePrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - PicturePrivate *d; -#endif + RefCountPtr d; }; } } diff --git a/taglib/fileref.cpp b/taglib/fileref.cpp index cf4a05d3..c188145b 100644 --- a/taglib/fileref.cpp +++ b/taglib/fileref.cpp @@ -61,26 +61,12 @@ using namespace TagLib; -class FileRef::FileRefPrivate : public RefCounter +class FileRef::FileRefPrivate { public: - FileRefPrivate(File *f) - : RefCounter(), file(f) {} + FileRefPrivate(File *f) : file(f) {} - ~FileRefPrivate() - { -#ifndef TAGLIB_USE_CXX11 - - delete file; - -#endif - } - -#ifdef TAGLIB_USE_CXX11 - std::unique_ptr file; -#else - File *file; -#endif + RefCountPtr file; static List fileTypeResolvers; }; @@ -110,11 +96,6 @@ FileRef::FileRef(File *file) FileRef::FileRef(const FileRef &ref) : d(ref.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } #ifdef TAGLIB_USE_CXX11 @@ -128,12 +109,6 @@ FileRef::FileRef(FileRef &&ref) FileRef::~FileRef() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) - delete d; - -#endif } Tag *FileRef::tag() const @@ -156,15 +131,7 @@ AudioProperties *FileRef::audioProperties() const File *FileRef::file() const { -#ifdef TAGLIB_USE_CXX11 - return d->file.get(); - -#else - - return d->file; - -#endif } bool FileRef::save() @@ -224,23 +191,7 @@ bool FileRef::isNull() const FileRef &FileRef::operator=(const FileRef &ref) { -#ifdef TAGLIB_USE_CXX11 - d = ref.d; - -#else - - if(&ref == this) - return *this; - - if(d->deref()) - delete d; - - d = ref.d; - d->ref(); - -#endif - return *this; } diff --git a/taglib/fileref.h b/taglib/fileref.h index bb11178b..a2bd491f 100644 --- a/taglib/fileref.h +++ b/taglib/fileref.h @@ -278,12 +278,7 @@ namespace TagLib { private: class FileRefPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - FileRefPrivate *d; -#endif + RefCountPtr d; }; } // namespace TagLib diff --git a/taglib/mp4/mp4coverart.cpp b/taglib/mp4/mp4coverart.cpp index bcb617b1..7ec52ed2 100644 --- a/taglib/mp4/mp4coverart.cpp +++ b/taglib/mp4/mp4coverart.cpp @@ -33,10 +33,10 @@ using namespace TagLib; -class MP4::CoverArt::CoverArtPrivate : public RefCounter +class MP4::CoverArt::CoverArtPrivate { public: - CoverArtPrivate() : RefCounter(), format(MP4::CoverArt::JPEG) {} + CoverArtPrivate() : format(MP4::CoverArt::JPEG) {} Format format; ByteVector data; @@ -51,30 +51,12 @@ MP4::CoverArt::CoverArt(Format format, const ByteVector &data) MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } MP4::CoverArt & MP4::CoverArt::operator=(const CoverArt &item) { -#ifdef TAGLIB_USE_CXX11 - d = item.d; - -#else - - if(d->deref()) { - delete d; - } - d = item.d; - d->ref(); - -#endif - return *this; } @@ -91,13 +73,6 @@ MP4::CoverArt & MP4::CoverArt::~CoverArt() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) { - delete d; - } - -#endif } MP4::CoverArt::Format diff --git a/taglib/mp4/mp4coverart.h b/taglib/mp4/mp4coverart.h index 9d4618d7..b5424a0c 100644 --- a/taglib/mp4/mp4coverart.h +++ b/taglib/mp4/mp4coverart.h @@ -66,12 +66,7 @@ namespace TagLib { private: class CoverArtPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - CoverArtPrivate *d; -#endif + RefCountPtr d; }; typedef List CoverArtList; diff --git a/taglib/mp4/mp4item.cpp b/taglib/mp4/mp4item.cpp index cb6523e8..9e7b0554 100644 --- a/taglib/mp4/mp4item.cpp +++ b/taglib/mp4/mp4item.cpp @@ -40,10 +40,10 @@ using namespace TagLib; -class MP4::Item::ItemPrivate : public RefCounter +class MP4::Item::ItemPrivate { public: - ItemPrivate() : RefCounter(), valid(true), atomDataType(MP4::TypeUndefined), type(MP4::Item::TypeUndefined) {} + ItemPrivate() : valid(true), atomDataType(MP4::TypeUndefined), type(MP4::Item::TypeUndefined) {} bool valid; AtomDataType atomDataType; @@ -70,11 +70,6 @@ MP4::Item::Item() MP4::Item::Item(const Item &item) : d(item.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } #ifdef TAGLIB_USE_CXX11 @@ -89,20 +84,7 @@ MP4::Item::Item(Item &&item) MP4::Item & MP4::Item::operator=(const Item &item) { -#ifdef TAGLIB_USE_CXX11 - d = item.d; - -#else - - if(d->deref()) { - delete d; - } - d = item.d; - d->ref(); - -#endif - return *this; } @@ -119,13 +101,6 @@ MP4::Item & MP4::Item::~Item() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) { - delete d; - } - -#endif } MP4::Item::Item(bool value) diff --git a/taglib/mp4/mp4item.h b/taglib/mp4/mp4item.h index c9c89142..73ee2f01 100644 --- a/taglib/mp4/mp4item.h +++ b/taglib/mp4/mp4item.h @@ -97,12 +97,7 @@ namespace TagLib { private: class ItemPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - ItemPrivate *d; -#endif + RefCountPtr d; }; } diff --git a/taglib/mpeg/mpegheader.cpp b/taglib/mpeg/mpegheader.cpp index 57b143c0..875de909 100644 --- a/taglib/mpeg/mpegheader.cpp +++ b/taglib/mpeg/mpegheader.cpp @@ -33,7 +33,7 @@ using namespace TagLib; -class MPEG::Header::HeaderPrivate : public RefCounter +class MPEG::Header::HeaderPrivate { public: HeaderPrivate() : @@ -76,11 +76,6 @@ MPEG::Header::Header(const ByteVector &data) MPEG::Header::Header(const Header &h) : d(h.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } #ifdef TAGLIB_USE_CXX11 @@ -94,12 +89,6 @@ MPEG::Header::Header(Header &&h) MPEG::Header::~Header() { -#ifndef TAGLIB_USE_CXX11 - - if (d->deref()) - delete d; - -#endif } bool MPEG::Header::isValid() const @@ -164,23 +153,7 @@ int MPEG::Header::samplesPerFrame() const MPEG::Header &MPEG::Header::operator=(const Header &h) { -#ifdef TAGLIB_USE_CXX11 - d = h.d; - -#else - - if(&h == this) - return *this; - - if(d->deref()) - delete d; - - d = h.d; - d->ref(); - -#endif - return *this; } diff --git a/taglib/mpeg/mpegheader.h b/taglib/mpeg/mpegheader.h index 00a708e7..0f4d8855 100644 --- a/taglib/mpeg/mpegheader.h +++ b/taglib/mpeg/mpegheader.h @@ -27,6 +27,7 @@ #define TAGLIB_MPEGHEADER_H #include "taglib_export.h" +#include "trefcountptr.h" namespace TagLib { @@ -180,12 +181,7 @@ namespace TagLib { void parse(const ByteVector &data); class HeaderPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - HeaderPrivate *d; -#endif + RefCountPtr d; }; } } diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h index ff6a64f2..a03fa9f6 100755 --- a/taglib/toolkit/taglib.h +++ b/taglib/toolkit/taglib.h @@ -53,30 +53,6 @@ #endif -// TAGLIB_USE_CXX11 determines whether or not to enable C++11 features. -// Replaces RefCounter capability with std::shared_ptr if available. - -#ifdef TAGLIB_USE_CXX11 -# include -#endif - -#ifndef TAGLIB_USE_CXX11 -# ifdef __APPLE__ -# include -# define TAGLIB_ATOMIC_MAC -# elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define TAGLIB_ATOMIC_WIN -# elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \ - && (defined(__i386__) || defined(__i486__) || defined(__i586__) || \ - defined(__i686__) || defined(__x86_64) || defined(__ia64)) \ - && !defined(__INTEL_COMPILER) -# define TAGLIB_ATOMIC_GCC -# elif defined(__ia64) && defined(__INTEL_COMPILER) -# include -# define TAGLIB_ATOMIC_GCC -# endif -#endif - // Check the widths of integral types. #if UCHAR_MAX != 255U @@ -161,57 +137,6 @@ namespace TagLib { * so I'm providing something here that should be constant. */ typedef std::basic_string wstring; - -#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class. - /*! - * \internal - * This is just used as a base class for shared classes in TagLib. - * - * \warning This is not part of the TagLib public API! - */ - - - class RefCounter - { - // RefCounter is a mere dummy if std::shared_ptr is available. - -#ifndef TAGLIB_USE_CXX11 - - public: - RefCounter() : refCount(1) {} - -# ifdef TAGLIB_ATOMIC_MAC - void ref() { OSAtomicIncrement32Barrier(const_cast(&refCount)); } - bool deref() { return ! OSAtomicDecrement32Barrier(const_cast(&refCount)); } - int32_t count() { return refCount; } - private: - volatile int32_t refCount; -# elif defined(TAGLIB_ATOMIC_WIN) - void ref() { InterlockedIncrement(&refCount); } - bool deref() { return ! InterlockedDecrement(&refCount); } - long count() { return refCount; } - private: - volatile long refCount; -# elif defined(TAGLIB_ATOMIC_GCC) - void ref() { __sync_add_and_fetch(&refCount, 1); } - bool deref() { return ! __sync_sub_and_fetch(&refCount, 1); } - int count() { return refCount; } - private: - volatile int refCount; -# else - void ref() { refCount++; } - bool deref() { return ! --refCount; } - int count() { return refCount; } - private: - uint refCount; -# endif -#endif - - public: - virtual ~RefCounter() {} - }; -#endif // DO_NOT_DOCUMENT - } /*! diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index 5e074750..15876943 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -28,16 +28,6 @@ #include #include -#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(_M_IX86) || defined(_M_X64)) -# define TAGLIB_MSC_BYTESWAP -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -# define TAGLIB_GCC_BYTESWAP -#endif - -#ifdef TAGLIB_GCC_BYTESWAP -# include -#endif - #include "tbytevector.h" #include "tbyteswap.h" @@ -246,7 +236,7 @@ ByteVector fromNumber(T value, bool mostSignificantByteFirst) return ByteVector(reinterpret_cast(&value), size); } -class DataPrivate : public RefCounter +class DataPrivate { public: DataPrivate() @@ -258,6 +248,12 @@ public: { } + // A char* can be an iterator. + DataPrivate(const char *begin, const char *end) + : data(begin, end) + { + } + DataPrivate(size_t l, char c) : data(l, c) { @@ -266,124 +262,65 @@ public: std::vector data; }; -class ByteVector::ByteVectorPrivate : public RefCounter +class ByteVector::ByteVectorPrivate { public: ByteVectorPrivate() - : RefCounter() - , data(new DataPrivate()) + : data(new DataPrivate()) , offset(0) , length(0) { } -#ifdef TAGLIB_USE_CXX11 - - ByteVectorPrivate(std::shared_ptr d, size_t o, size_t l) - : RefCounter() - , data(d->data) + ByteVectorPrivate(RefCountPtr d, size_t o, size_t l) + : data(d->data) , offset(d->offset + o) , length(l) { } -#else - - ByteVectorPrivate(ByteVectorPrivate *d, size_t o, size_t l) - : RefCounter() - , data(d->data) - , offset(d->offset + o) - , length(l) - { - data->ref(); - } - -#endif - ByteVectorPrivate(const std::vector &v, size_t o, size_t l) - : RefCounter() - , data(new DataPrivate(v, o, l)) + : data(new DataPrivate(v, o, l)) , offset(0) , length(l) { } ByteVectorPrivate(size_t l, char c) - : RefCounter() - , data(new DataPrivate(l, c)) + : data(new DataPrivate(l, c)) , offset(0) , length(l) { } ByteVectorPrivate(const char *s, size_t l) - : RefCounter() - , data(new DataPrivate()) + : data(new DataPrivate(s, s + l)) , offset(0) , length(l) { - data->data.resize(length); - memcpy(DATA(this), s, l); } void detach() { -#ifdef TAGLIB_USE_CXX11 - if(!data.unique()) { data.reset(new DataPrivate(data->data, offset, length)); offset = 0; } - -#else - - if(data->count() > 1) { - data->deref(); - data = new DataPrivate(data->data, offset, length); - offset = 0; - } - -#endif } ~ByteVectorPrivate() { -#ifndef TAGLIB_USE_CXX11 - - if(data->deref()) - delete data; - -#endif } ByteVectorPrivate &operator=(const ByteVectorPrivate &x) { if(&x != this) - { -#ifdef TAGLIB_USE_CXX11 - data = x.data; -#else - - if(data->deref()) - delete data; - - data = x.data; - data->ref(); - -#endif - } - return *this; } -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr data; -#else - DataPrivate *data; -#endif - + RefCountPtr data; size_t offset; size_t length; }; @@ -436,11 +373,6 @@ ByteVector::ByteVector(size_t size, char value) ByteVector::ByteVector(const ByteVector &v) : d(v.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } ByteVector::ByteVector(const ByteVector &v, size_t offset, size_t length) @@ -474,12 +406,6 @@ ByteVector::ByteVector(const char *data) ByteVector::~ByteVector() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) - delete d; - -#endif } ByteVector &ByteVector::setData(const char *data, size_t length) @@ -630,19 +556,8 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit } // replace private data: -#ifdef TAGLIB_USE_CXX11 - d.reset(newData); -#else - - if(d->deref()) - delete d; - - d = newData; - -#endif - return *this; } @@ -842,23 +757,8 @@ ByteVector ByteVector::operator+(const ByteVector &v) const ByteVector &ByteVector::operator=(const ByteVector &v) { -#ifdef TAGLIB_USE_CXX11 - d = v.d; -#else - - if(&v == this) - return *this; - - if(d->deref()) - delete d; - - d = v.d; - d->ref(); - -#endif - return *this; } @@ -874,31 +774,13 @@ ByteVector &ByteVector::operator=(ByteVector &&v) ByteVector &ByteVector::operator=(char c) { -#ifdef TAGLIB_USE_CXX11 - d = ByteVector(c).d; - -#else - - *this = ByteVector(c); - -#endif - return *this; } ByteVector &ByteVector::operator=(const char *data) { -#ifdef TAGLIB_USE_CXX11 - d = ByteVector(data).d; - -#else - - *this = ByteVector(data); - -#endif - return *this; } @@ -924,19 +806,8 @@ void ByteVector::detach() { d->detach(); -#ifdef TAGLIB_USE_CXX11 - if(!d.unique()) d.reset(new ByteVectorPrivate(d->data->data, d->offset, d->length)); - -#else - - if(d->count() > 1) { - d->deref(); - d = new ByteVectorPrivate(d->data->data, d->offset, d->length); - } - -#endif } //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/toolkit/tbytevector.h b/taglib/toolkit/tbytevector.h index df885864..21f63f33 100644 --- a/taglib/toolkit/tbytevector.h +++ b/taglib/toolkit/tbytevector.h @@ -26,9 +26,9 @@ #ifndef TAGLIB_BYTEVECTOR_H #define TAGLIB_BYTEVECTOR_H -#include "taglib.h" #include "taglib_export.h" - +#include "taglib.h" +#include "trefcountptr.h" #include #include @@ -478,12 +478,7 @@ namespace TagLib { private: class ByteVectorPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - ByteVectorPrivate *d; -#endif + RefCountPtr d; }; /*! diff --git a/taglib/toolkit/tfile.h b/taglib/toolkit/tfile.h index d9b0a46f..af55bd67 100644 --- a/taglib/toolkit/tfile.h +++ b/taglib/toolkit/tfile.h @@ -26,10 +26,8 @@ #ifndef TAGLIB_FILE_H #define TAGLIB_FILE_H -#include "taglib_export.h" -#include "taglib.h" -#include "tag.h" #include "tbytevector.h" +#include "tag.h" #include "tiostream.h" namespace TagLib { diff --git a/taglib/toolkit/tfilestream.h b/taglib/toolkit/tfilestream.h index f5b5190b..413245c3 100644 --- a/taglib/toolkit/tfilestream.h +++ b/taglib/toolkit/tfilestream.h @@ -26,8 +26,6 @@ #ifndef TAGLIB_FILESTREAM_H #define TAGLIB_FILESTREAM_H -#include "taglib_export.h" -#include "taglib.h" #include "tbytevector.h" #include "tiostream.h" diff --git a/taglib/toolkit/tiostream.h b/taglib/toolkit/tiostream.h index 5448487d..ff223468 100644 --- a/taglib/toolkit/tiostream.h +++ b/taglib/toolkit/tiostream.h @@ -26,8 +26,6 @@ #ifndef TAGLIB_IOSTREAM_H #define TAGLIB_IOSTREAM_H -#include "taglib_export.h" -#include "taglib.h" #include "tbytevector.h" #ifdef _WIN32 diff --git a/taglib/toolkit/tlist.h b/taglib/toolkit/tlist.h index 0d3a0d3a..a2749215 100644 --- a/taglib/toolkit/tlist.h +++ b/taglib/toolkit/tlist.h @@ -27,7 +27,7 @@ #define TAGLIB_LIST_H #include "taglib.h" - +#include "trefcountptr.h" #include namespace TagLib { @@ -305,12 +305,7 @@ namespace TagLib { private: #ifndef DO_NOT_DOCUMENT template class ListPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr> d; -#else - ListPrivate *d; -#endif + RefCountPtr > d; #endif }; diff --git a/taglib/toolkit/tlist.tcc b/taglib/toolkit/tlist.tcc index 69421f69..83051bec 100644 --- a/taglib/toolkit/tlist.tcc +++ b/taglib/toolkit/tlist.tcc @@ -38,7 +38,7 @@ namespace TagLib { // A base for the generic and specialized private class types. New // non-templatized members should be added here. -class ListPrivateBase : public RefCounter +class ListPrivateBase { public: ListPrivateBase() : autoDelete(false) {} @@ -118,11 +118,6 @@ template List::List(const List &l) : d(l.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } #ifdef TAGLIB_USE_CXX11 @@ -138,12 +133,6 @@ List::List(List &&l) template List::~List() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) - delete d; - -#endif } template @@ -371,21 +360,7 @@ const T &List::operator[](size_t i) const template List &List::operator=(const List &l) { - #ifdef TAGLIB_USE_CXX11 - d = l.d; - - #else - - if(&l == this) - return *this; - - if(d->deref()) - delete d; - d = l.d; - d->ref(); -#endif - return *this; } @@ -419,19 +394,8 @@ bool List::operator!=(const List &l) const template void List::detach() { -#ifdef TAGLIB_USE_CXX11 - if(!d.unique()) d.reset(new ListPrivate(d->list)); - -#else - - if(d->count() > 1) { - d->deref(); - d = new ListPrivate(d->list); - } - -#endif } } // namespace TagLib diff --git a/taglib/toolkit/tmap.h b/taglib/toolkit/tmap.h index 93b7bb95..0928cf57 100644 --- a/taglib/toolkit/tmap.h +++ b/taglib/toolkit/tmap.h @@ -26,9 +26,9 @@ #ifndef TAGLIB_MAP_H #define TAGLIB_MAP_H -#include - #include "taglib.h" +#include "trefcountptr.h" +#include namespace TagLib { @@ -219,12 +219,7 @@ namespace TagLib { private: #ifndef DO_NOT_DOCUMENT template class MapPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr> d; -#else - MapPrivate *d; -#endif + RefCountPtr > d; #endif }; diff --git a/taglib/toolkit/tmap.tcc b/taglib/toolkit/tmap.tcc index 09130c18..480be764 100644 --- a/taglib/toolkit/tmap.tcc +++ b/taglib/toolkit/tmap.tcc @@ -31,10 +31,10 @@ namespace TagLib { template template -class Map::MapPrivate : public RefCounter +class Map::MapPrivate { public: - MapPrivate() : RefCounter() {} + MapPrivate() {} #ifdef WANT_CLASS_INSTANTIATION_OF_MAP @@ -54,11 +54,11 @@ public: #else - MapPrivate(const std::map& m) : RefCounter(), map(m) {} + MapPrivate(const std::map& m) : map(m) {} # ifdef TAGLIB_USE_CXX11 - MapPrivate(std::map &&m) : RefCounter(), map(m) {} + MapPrivate(std::map &&m) : map(m) {} # endif @@ -81,11 +81,6 @@ template Map::Map(const Map &m) : d(m.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } #ifdef TAGLIB_USE_CXX11 @@ -101,12 +96,6 @@ TagLib::Map::Map(Map &&m) template Map::~Map() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) - delete(d); - -#endif } template @@ -228,22 +217,7 @@ T &Map::operator[](const Key &key) template Map &Map::operator=(const Map &m) { -#ifdef TAGLIB_USE_CXX11 - d = m.d; - -#else - - if(&m == this) - return *this; - - if(d->deref()) - delete(d); - d = m.d; - d->ref(); - -#endif - return *this; } @@ -265,19 +239,8 @@ Map &Map::operator=(Map &&m) template void Map::detach() { -#ifdef TAGLIB_USE_CXX11 - if(!d.unique()) d.reset(new MapPrivate(d->map)); - -#else - - if(d->count() > 1) { - d->deref(); - d = new MapPrivate(d->map); - } - -#endif } } // namespace TagLib diff --git a/taglib/toolkit/trefcountptr.h b/taglib/toolkit/trefcountptr.h new file mode 100644 index 00000000..e4ed2b9a --- /dev/null +++ b/taglib/toolkit/trefcountptr.h @@ -0,0 +1,257 @@ +/*************************************************************************** + 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_REFCOUNTPTR_H +#define TAGLIB_REFCOUNTPTR_H + +// TAGLIB_USE_CXX11 determines whether or not to enable C++11 features. + +#include "tdebug.h" + +#ifdef TAGLIB_USE_CXX11 +# include + +#else +# ifdef __APPLE__ +# include +# define TAGLIB_ATOMIC_MAC +# elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define TAGLIB_ATOMIC_WIN +# elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \ + && (defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(__x86_64) || defined(__ia64)) \ + && !defined(__INTEL_COMPILER) +# define TAGLIB_ATOMIC_GCC +# elif defined(__ia64) && defined(__INTEL_COMPILER) +# include +# define TAGLIB_ATOMIC_GCC +# endif +#endif + +#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class. + +/*! + * \internal + * This is just used as a smart pointer for shared classes in TagLib. + * + * \warning This is not part of the TagLib public API! + */ + +#ifdef TAGLIB_USE_CXX11 + + // RefCountPtr is just an alias of std::shared_ptr if C++11 is available. +# define RefCountPtr std::shared_ptr + + // Workaround for the fact that some compilers don't support the template aliases. + +#else + +namespace TagLib { + + // RefCountPtr mimics std::shared_ptr if C++11 is not available. + + template + class RefCountPtr + { + private: + + // Counter base class. Provides a reference counter. + + class counter_base + { + public: + counter_base() + : count(1) + { + } + + virtual ~counter_base() + { + } + + void addref() + { + increment(&count); + } + + void release() + { + if(decrement(&count) == 0) { + dispose(); + delete this; + } + } + + long use_count() const + { + return static_cast(count); + } + + virtual void dispose() = 0; + + private: +# if defined(TAGLIB_ATOMIC_MAC) + typedef volatile int32_t counter_t; + + inline static void increment(counter_t *c) { OSAtomicIncrement32Barrier(c); } + inline static counter_t decrement(counter_t *c) { return OSAtomicDecrement32Barrier(c); } + +# elif defined(TAGLIB_ATOMIC_WIN) + typedef volatile long counter_t; + + inline static void increment(counter_t *c) { InterlockedIncrement(c); } + inline static counter_t decrement(counter_t *c) { return InterlockedDecrement(c); } + +# elif defined(TAGLIB_ATOMIC_GCC) + typedef volatile int counter_t; + + inline static void increment(counter_t *c) { __sync_add_and_fetch(c, 1); } + inline static counter_t decrement(counter_t *c) { return __sync_sub_and_fetch(c, 1); } + +# else + typedef uint counter_t; + + inline static void increment(counter_t *c) { ++(*c) } + inline static counter_t decrement(counter_t *c) { return --(*c); } + +# endif + + counter_t count; + }; + + // Counter impl class. Provides a dynamic deleter. + + template + class counter_impl : public counter_base + { + public: + counter_impl(U *p) + : p(p) + { + } + + virtual void dispose() + { + delete p; + } + + U *get() const + { + return p; + } + + private: + U *p; + }; + + public: + template + explicit RefCountPtr(U *p) + : counter(new counter_impl(p)) + { + } + + RefCountPtr(const RefCountPtr &x) + { + counter = x.counter; + counter->addref(); + } + + ~RefCountPtr() + { + counter->release(); + } + + T *get() const + { + return static_cast*>(counter)->get(); + } + + long use_count() const + { + return counter->use_count(); + } + + bool unique() const + { + return (use_count() == 1); + } + + template + void reset(U *p) + { + if(get() != p) + { + counter->release(); + counter = new counter_impl(p); + } + } + + RefCountPtr &operator=(const RefCountPtr &x) + { + if(get() != x.get()) + { + counter->release(); + + counter = x.counter; + counter->addref(); + } + return *this; + } + + T& operator*() const + { + return *get(); + } + + T* operator->() const + { + return get(); + } + + bool operator==(const RefCountPtr &x) const + { + return (get() == x.get()); + } + + bool operator!=(const RefCountPtr &x) const + { + return !operator==(x); + } + + operator bool() const + { + return (get() != 0); + } + + private: + counter_base *counter; + }; +} +#endif // TAGLIB_USE_CXX11 + +#endif // DO_NOT_DOCUMENT + +#endif diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index d7d3b4c1..3130e382 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -46,10 +46,6 @@ # include "unicode.h" #endif -#if defined(__GNUC__) -# include -#endif - namespace { inline unsigned short combine(unsigned char c1, unsigned char c2) @@ -60,25 +56,24 @@ namespace { namespace TagLib { -class String::StringPrivate : public RefCounter +class String::StringPrivate { public: + StringPrivate() + { + } + + StringPrivate(const wstring &s) + : data(s) + { + } #ifdef TAGLIB_USE_CXX11 - StringPrivate() {} - StringPrivate(const wstring &s) : data(s) {} - StringPrivate(wstring &&s) : data(s) {} - -#else - -public: - StringPrivate(const wstring &s) : - RefCounter(), - data(s) {} - - StringPrivate() : - RefCounter() {} + StringPrivate(wstring &&s) + : data(s) + { + } #endif @@ -108,11 +103,6 @@ String::String() String::String(const String &s) : d(s.d) { -#ifndef TAGLIB_USE_CXX11 - - d->ref(); - -#endif } #ifdef TAGLIB_USE_CXX11 @@ -208,12 +198,6 @@ String::String(const ByteVector &v, Type t) String::~String() { -#ifndef TAGLIB_USE_CXX11 - - if(d->deref()) - delete d; - -#endif } std::string String::to8Bit(bool unicode) const @@ -660,22 +644,7 @@ String &String::operator+=(char c) String &String::operator=(const String &s) { -#ifdef TAGLIB_USE_CXX11 - d = s.d; - -#else - - if(&s == this) - return *this; - - if(d->deref()) - delete d; - d = s.d; - d->ref(); - -#endif - return *this; } @@ -691,19 +660,7 @@ String &String::operator=(String &&s) String &String::operator=(const std::string &s) { -#ifdef TAGLIB_USE_CXX11 - d.reset(new StringPrivate()); - -#else - - if(d->deref()) - delete d; - - d = new StringPrivate; - -#endif - copyFromLatin1(s.c_str(), s.length()); return *this; @@ -711,19 +668,7 @@ String &String::operator=(const std::string &s) String &String::operator=(const wstring &s) { -#ifdef TAGLIB_USE_CXX11 - d.reset(new StringPrivate(s)); - -#else - - if(d->deref()) - delete d; - - d = new StringPrivate(s); - -#endif - return *this; } @@ -739,19 +684,7 @@ String &String::operator=(wstring &&s) String &String::operator=(const wchar_t *s) { -#ifdef TAGLIB_USE_CXX11 - d.reset(new StringPrivate()); - -#else - - if(d->deref()) - delete d; - - d = new StringPrivate; - -#endif - copyFromUTF16(s, ::wcslen(s), WCharByteOrder); return *this; @@ -759,19 +692,7 @@ String &String::operator=(const wchar_t *s) String &String::operator=(char c) { -#ifdef TAGLIB_USE_CXX11 - d.reset(new StringPrivate()); - -#else - - if(d->deref()) - delete d; - - d = new StringPrivate; - -#endif - d->data.resize(1); d->data[0] = static_cast(c); @@ -780,19 +701,7 @@ String &String::operator=(char c) String &String::operator=(wchar_t c) { -#ifdef TAGLIB_USE_CXX11 - d.reset(new StringPrivate()); - -#else - - if(d->deref()) - delete d; - - d = new StringPrivate; - -#endif - d->data.resize(1); d->data[0] = c; @@ -801,19 +710,7 @@ String &String::operator=(wchar_t c) String &String::operator=(const char *s) { -#ifdef TAGLIB_USE_CXX11 - d.reset(new StringPrivate()); - -#else - - if(d->deref()) - delete d; - - d = new StringPrivate; - -#endif - copyFromLatin1(s, ::strlen(s)); return *this; @@ -821,19 +718,7 @@ String &String::operator=(const char *s) String &String::operator=(const ByteVector &v) { -#ifdef TAGLIB_USE_CXX11 - d.reset(new StringPrivate()); - -#else - - if(d->deref()) - delete d; - - d = new StringPrivate; - -#endif - copyFromLatin1(v.data(), v.size()); // If we hit a null in the ByteVector, shrink the string again. @@ -853,19 +738,8 @@ bool String::operator<(const String &s) const void String::detach() { -#ifdef TAGLIB_USE_CXX11 - if(!d.unique()) d.reset(new StringPrivate(d->data)); - -#else - - if(d->count() > 1) { - d->deref(); - d = new StringPrivate(d->data); - } - -#endif } //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index e1665fd5..4bd014db 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -26,12 +26,8 @@ #ifndef TAGLIB_STRING_H #define TAGLIB_STRING_H -#include "taglib_export.h" -#include "taglib.h" #include "tbytevector.h" - #include -#include /*! * \relates TagLib::String @@ -527,12 +523,7 @@ namespace TagLib { static const Type WCharByteOrder; class StringPrivate; - -#ifdef TAGLIB_USE_CXX11 - std::shared_ptr d; -#else - StringPrivate *d; -#endif + RefCountPtr d; }; /*!