]> granicus.if.org Git - taglib/commitdiff
Revert changes concerning the smart pointer
authorTsuda kageyu <tsuda.kageyu@gmail.com>
Wed, 17 Apr 2013 13:54:56 +0000 (22:54 +0900)
committerTsuda kageyu <tsuda.kageyu@gmail.com>
Wed, 17 Apr 2013 13:54:56 +0000 (22:54 +0900)
26 files changed:
ConfigureChecks.cmake
config-taglib.h.cmake
taglib/CMakeLists.txt
taglib/asf/asfattribute.cpp
taglib/asf/asfattribute.h
taglib/asf/asfpicture.cpp
taglib/asf/asfpicture.h
taglib/fileref.cpp
taglib/fileref.h
taglib/mp4/mp4coverart.cpp
taglib/mp4/mp4coverart.h
taglib/mp4/mp4item.cpp
taglib/mp4/mp4item.h
taglib/mpeg/mpegheader.cpp
taglib/mpeg/mpegheader.h
taglib/toolkit/taglib.h
taglib/toolkit/tbytevector.cpp
taglib/toolkit/tbytevector.h
taglib/toolkit/tiostream.h
taglib/toolkit/tlist.h
taglib/toolkit/tlist.tcc
taglib/toolkit/tmap.h
taglib/toolkit/tmap.tcc
taglib/toolkit/trefcountptr.h [deleted file]
taglib/toolkit/tstring.cpp
taglib/toolkit/tstring.h

index ec0da6d154d5a9bd596a2528f5c8b4d5e7255c85..e4a6d1fac59c91dafb29d9b30cafffd17b397ec2 100644 (file)
@@ -9,32 +9,15 @@ include(CheckCXXSourceCompiles)
 # check for libz using the cmake supplied FindZLIB.cmake
 find_package(ZLIB)
 if(ZLIB_FOUND)
-    set(HAVE_ZLIB 1)
+       set(HAVE_ZLIB 1)
 else()
-    set(HAVE_ZLIB 0)
+       set(HAVE_ZLIB 0)
 endif()
 
-# Determine where shared_ptr<T> is defined regardless of C++11 support.
-
-check_cxx_source_compiles("
-    #include <memory>
-    int main() { std::tr1::shared_ptr<int> x; return 0; }
-" HAVE_STD_SHARED_PTR)
-
-check_cxx_source_compiles("
-    #include <tr1/memory>
-    int main() { std::tr1::shared_ptr<int> x; return 0; }
-" HAVE_TR1_SHARED_PTR)
-
-check_cxx_source_compiles("
-    #include <boost/shared_ptr.hpp>
-    int main() { boost::shared_ptr<int> x; return 0; }
-" HAVE_BOOST_SHARED_PTR)
-
 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
 find_package(CppUnit)
 if(NOT CppUnit_FOUND AND BUILD_TESTS)
-    message(STATUS "CppUnit not found, disabling tests.")
-    set(BUILD_TESTS OFF)
+       message(STATUS "CppUnit not found, disabling tests.")
+       set(BUILD_TESTS OFF)
 endif()
 
index 8ce6798b3cd3566c1992f095c30af75b8dcfd508..9c2f487d1dea0e501d06f42b7af82c9205e5253a 100644 (file)
@@ -3,10 +3,6 @@
 /* Define if you have libz */
 #cmakedefine   HAVE_ZLIB 1
 
-#cmakedefine   HAVE_STD_SHARED_PTR 1
-#cmakedefine   HAVE_TR1_SHARED_PTR 1
-#cmakedefine   HAVE_BOOST_SHARED_PTR 1
-
 #cmakedefine   NO_ITUNES_HACKS 1
 #cmakedefine   WITH_ASF 1
 #cmakedefine   WITH_MP4 1
index dab3430e8009a2b457f72c5efa8a715b3fef817b..a940caf5def3d2d4a726bfb897b6e0fb68db22ec 100644 (file)
@@ -51,7 +51,6 @@ set(tag_HDRS
   toolkit/tmap.tcc
   toolkit/tpropertymap.h
   toolkit/tbyteswap.h
-  toolkit/trefcountptr.h
   mpeg/mpegfile.h
   mpeg/mpegproperties.h
   mpeg/mpegheader.h
@@ -312,10 +311,6 @@ if(ZLIB_FOUND)
        target_link_libraries(tag ${ZLIB_LIBRARIES})
 endif()
 
-if(WIN32 AND NOT TAGLIB_STATIC)
-       target_link_libraries(tag shlwapi.lib)
-endif()
-
 set_target_properties(tag PROPERTIES
   VERSION ${TAGLIB_SOVERSION_MAJOR}.${TAGLIB_SOVERSION_MINOR}.${TAGLIB_SOVERSION_PATCH}
   SOVERSION ${TAGLIB_SOVERSION_MAJOR}
index 4ba2689bc3e455efb2d879b14d8af315b857210f..2cfada7b0fa3d516321640a63b38bf010a811699 100644 (file)
@@ -34,7 +34,7 @@
 
 using namespace TagLib;
 
-class ASF::Attribute::AttributePrivate
+class ASF::Attribute::AttributePrivate : public RefCounter
 {
 public:
   AttributePrivate()
@@ -60,71 +60,77 @@ public:
 ////////////////////////////////////////////////////////////////////////////////
 
 ASF::Attribute::Attribute()
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = UnicodeType;
 }
 
 ASF::Attribute::Attribute(const ASF::Attribute &other)
   : d(other.d)
 {
+  d->ref();
 }
 
 ASF::Attribute &ASF::Attribute::operator=(const ASF::Attribute &other)
 {
+  if(d->deref())
+    delete d;
   d = other.d;
+  d->ref();
   return *this;
 }
 
 ASF::Attribute::~Attribute()
 {
+  if(d->deref())
+    delete d;
 }
 
 ASF::Attribute::Attribute(const String &value)
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = UnicodeType;
   d->stringValue = value;
 }
 
 ASF::Attribute::Attribute(const ByteVector &value)
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = BytesType;
   d->byteVectorValue = value;
 }
 
 ASF::Attribute::Attribute(const ASF::Picture &value)
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = BytesType;
   d->pictureValue = value;
 }
 
 ASF::Attribute::Attribute(unsigned int value)
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = DWordType;
   d->intValue = value;
 }
 
 ASF::Attribute::Attribute(unsigned long long value)
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = QWordType;
   d->longLongValue = value;
 }
 
 ASF::Attribute::Attribute(unsigned short value)
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = WordType;
   d->shortValue = value;
 }
 
 ASF::Attribute::Attribute(bool value)
-  : d(new AttributePrivate())
 {
+  d = new AttributePrivate;
   d->type = BoolType;
   d->boolValue = value;
 }
index ca26aec3f40da6c5bfc824da3147d03995d35902..54eb0c7d104a07bcb3005e4276741e84926dfc27 100644 (file)
@@ -194,7 +194,7 @@ namespace TagLib
       ByteVector render(const String &name, int kind = 0) const;
 
       class AttributePrivate;
-      RefCountPtr<AttributePrivate> d;
+      AttributePrivate *d;
     };
   }
 
index 82a38b6bc3e9cab0be880a9e082b9a3cd089be33..c36ffa3a92411df9b189b242b52108e1bae9a865 100644 (file)
@@ -35,7 +35,7 @@
 
 using namespace TagLib;
 
-class ASF::Picture::PicturePrivate
+class ASF::Picture::PicturePrivate : public RefCounter
 {
 public:
   bool valid;
@@ -50,18 +50,21 @@ public:
 ////////////////////////////////////////////////////////////////////////////////
 
 ASF::Picture::Picture()
-  : d(new PicturePrivate())
 {
+  d = new PicturePrivate();
   d->valid = true;
 }
 
 ASF::Picture::Picture(const Picture& other)
   : d(other.d)
 {
+  d->ref();
 }
 
 ASF::Picture::~Picture()
 {
+  if(d->deref())
+    delete d;
 }
 
 bool ASF::Picture::isValid() const
@@ -118,7 +121,12 @@ int ASF::Picture::dataSize() const
 
 ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other)
 {
-  d = other.d;
+  if(other.d != d) {
+    if(d->deref())
+      delete d;
+    d = other.d;
+    d->ref();
+  }
   return *this;
 }
 
index aa838974639079dcb7c8314f38fd87272b1203f8..aa0a060c19f2eac21833b3ab7137f4dd7ca62bb2 100644 (file)
@@ -207,10 +207,10 @@ namespace TagLib
       static Picture fromInvalid();
       friend class Attribute;
 #endif
-    private:
-      class PicturePrivate;
-      RefCountPtr<PicturePrivate> d;
-    };
+      private:
+        class PicturePrivate;
+        PicturePrivate *d;
+      };
   }
 }
 
index f3b4ef3cd6237ddfb523f2c01a9e6bccc6cafe0e..859f3155bd72993f824e5f6e46db320086d8c11a 100644 (file)
 #include <config.h>
 #endif
 
-#ifdef _WIN32
-# include <Shlwapi.h>
-#endif
-
 #include <tfile.h>
 #include <tstring.h>
 #include <tdebug.h>
 
 using namespace TagLib;
 
-class FileRef::FileRefPrivate 
+class FileRef::FileRefPrivate : public RefCounter
 {
 public:
-  FileRefPrivate(File *f) : file(f) {}
+  FileRefPrivate(File *f) : RefCounter(), file(f) {}
+  ~FileRefPrivate() {
+    delete file;
+  }
 
-  RefCountPtr<File> file;
+  File *file;
   static List<const FileTypeResolver *> fileTypeResolvers;
 };
 
@@ -77,28 +76,30 @@ List<const FileRef::FileTypeResolver *> FileRef::FileRefPrivate::fileTypeResolve
 ////////////////////////////////////////////////////////////////////////////////
 
 FileRef::FileRef()
-  : d(new FileRefPrivate(0))
 {
+  d = new FileRefPrivate(0);
 }
 
-FileRef::FileRef(
-  FileName fileName, bool readAudioProperties,  AudioProperties::ReadStyle audioPropertiesStyle)
-  : d(new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle)))
+FileRef::FileRef(FileName fileName, bool readAudioProperties,
+                 AudioProperties::ReadStyle audioPropertiesStyle)
 {
+  d = new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle));
 }
 
 FileRef::FileRef(File *file)
-  : d(new FileRefPrivate(file))
 {
+  d = new FileRefPrivate(file);
 }
 
-FileRef::FileRef(const FileRef &ref) 
-  : d(ref.d)
+FileRef::FileRef(const FileRef &ref) : d(ref.d)
 {
+  d->ref();
 }
 
 FileRef::~FileRef()
 {
+  if(d->deref())
+    delete d;
 }
 
 Tag *FileRef::tag() const
@@ -121,7 +122,7 @@ AudioProperties *FileRef::audioProperties() const
 
 File *FileRef::file() const
 {
-  return d->file.get();
+  return d->file;
 }
 
 bool FileRef::save()
@@ -181,7 +182,15 @@ bool FileRef::isNull() const
 
 FileRef &FileRef::operator=(const FileRef &ref)
 {
+  if(&ref == this)
+    return *this;
+
+  if(d->deref())
+    delete d;
+
   d = ref.d;
+  d->ref();
+
   return *this;
 }
 
@@ -209,36 +218,21 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
 
   // Ok, this is really dumb for now, but it works for testing.
 
-  String ext;
+  String s;
 
 #ifdef _WIN32
-  // Avoids direct conversion from FileName to String
-  // because String can't accept non-Latin-1 string in char array.
-
-  if(!fileName.wstr().empty()) {
-    const wchar_t *pext = PathFindExtensionW(fileName.wstr().c_str());
-    if(*pext == L'.')
-      ext = String(pext + 1).upper();
-  }
-  else {
-    const char *pext = PathFindExtensionA(fileName.str().c_str());
-    if(*pext == '.')
-      ext = String(pext + 1).upper();
-  }
+  s = (wcslen((const wchar_t *) fileName) > 0) ? String((const wchar_t *) fileName) : String((const char *) fileName);
 #else
-  {
-    String s = fileName;
-    const int pos = s.rfind(".");
-    if(pos != -1)
-      ext = s.substr(pos + 1).upper();
-  }
+  s = fileName;
 #endif
 
   // If this list is updated, the method defaultFileExtensions() should also be
   // updated.  However at some point that list should be created at the same time
   // that a default file type resolver is created.
 
-  if(!ext.isEmpty()) {
+  int pos = s.rfind(".");
+  if(pos != -1) {
+    String ext = s.substr(pos + 1).upper();
     if(ext == "MP3")
       return new MPEG::File(fileName, readAudioProperties, audioPropertiesStyle);
     if(ext == "OGG")
index 907727c7e0d5307042d72b9025c7ed65b8fd7acc..0f0c21a4dc77f917f9d5cd10657fcb80c9f05ffe 100644 (file)
@@ -255,7 +255,7 @@ namespace TagLib {
 
   private:
     class FileRefPrivate;
-    RefCountPtr<FileRefPrivate> d;
+    FileRefPrivate *d;
   };
 
 } // namespace TagLib
index 5b6e6e230ac3e0d0c92a7d0a4301c0d7eff34af7..928e3c4aa2f22f94f8ec0fdf4cfb2a066de5e8a9 100644 (file)
 
 using namespace TagLib;
 
-class MP4::CoverArt::CoverArtPrivate
+class MP4::CoverArt::CoverArtPrivate : public RefCounter
 {
 public:
-  CoverArtPrivate() : format(MP4::CoverArt::JPEG) {}
+  CoverArtPrivate() : RefCounter(), format(MP4::CoverArt::JPEG) {}
 
   Format format;
   ByteVector data;
 };
 
 MP4::CoverArt::CoverArt(Format format, const ByteVector &data)
-  : d(new CoverArtPrivate())
 {
+  d = new CoverArtPrivate;
   d->format = format;
   d->data = data;
 }
 
 MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d)
 {
+  d->ref();
 }
 
 MP4::CoverArt &
 MP4::CoverArt::operator=(const CoverArt &item)
 {
+  if(d->deref()) {
+    delete d;
+  }
   d = item.d;
+  d->ref();
   return *this;
 }
 
 MP4::CoverArt::~CoverArt()
 {
+  if(d->deref()) {
+    delete d;
+  }
 }
 
 MP4::CoverArt::Format
index b6b44c4968381bd6c9066e7113d95d9a5a73e85b..64115b458ed8fafcb9c0adfb6e37783b0d96ea5b 100644 (file)
@@ -63,7 +63,7 @@ namespace TagLib {
 
     private:
       class CoverArtPrivate;
-      RefCountPtr<CoverArtPrivate> d;
+      CoverArtPrivate *d;
     };
 
     typedef List<CoverArt> CoverArtList;
index 6a303652c58230348d9bd97e42e93cea7a170aaa..af2cc65c80de9f06e3da1fcf27b50679c2004ba3 100644 (file)
 
 using namespace TagLib;
 
-class MP4::Item::ItemPrivate 
+class MP4::Item::ItemPrivate : public RefCounter
 {
 public:
-  ItemPrivate() : valid(true), atomDataType(TypeUndefined) {}
+  ItemPrivate() : RefCounter(), valid(true), atomDataType(TypeUndefined) {}
 
   bool valid;
   AtomDataType atomDataType;
@@ -54,78 +54,86 @@ public:
 };
 
 MP4::Item::Item()
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->valid = false;
 }
 
 MP4::Item::Item(const Item &item) : d(item.d)
 {
+  d->ref();
 }
 
 MP4::Item &
 MP4::Item::operator=(const Item &item)
 {
+  if(d->deref()) {
+    delete d;
+  }
   d = item.d;
+  d->ref();
   return *this;
 }
 
 MP4::Item::~Item()
 {
+  if(d->deref()) {
+    delete d;
+  }
 }
 
 MP4::Item::Item(bool value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_bool = value;
 }
 
 MP4::Item::Item(int value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_int = value;
 }
 
 MP4::Item::Item(uchar value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_byte = value;
 }
 
 MP4::Item::Item(uint value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_uint = value;
 }
 
 MP4::Item::Item(long long value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_longlong = value;
 }
 
 MP4::Item::Item(int value1, int value2)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_intPair.first = value1;
   d->m_intPair.second = value2;
 }
 
 MP4::Item::Item(const ByteVectorList &value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_byteVectorList = value;
 }
 
 MP4::Item::Item(const StringList &value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_stringList = value;
 }
 
 MP4::Item::Item(const MP4::CoverArtList &value)
-  : d(new ItemPrivate())
 {
+  d = new ItemPrivate;
   d->m_coverArtList = value;
 }
 
index 3b4e23cd91ff1013813794aff3b7406de8e9fc49..be7aa1a17fc11760f424d8f2fc8bdf9922b367d4 100644 (file)
@@ -73,7 +73,7 @@ namespace TagLib {
 
     private:
       class ItemPrivate;
-      RefCountPtr<ItemPrivate> d;
+      ItemPrivate *d;
     };
 
   }
index bc98f4c979cad4d7b9d3b145e3ed346d56a1bf12..c715dbc1435bf7884ab8fbb8e221c454c666a05a 100644 (file)
@@ -33,7 +33,7 @@
 
 using namespace TagLib;
 
-class MPEG::Header::HeaderPrivate
+class MPEG::Header::HeaderPrivate : public RefCounter
 {
 public:
   HeaderPrivate() :
@@ -68,18 +68,20 @@ public:
 ////////////////////////////////////////////////////////////////////////////////
 
 MPEG::Header::Header(const ByteVector &data)
-  : d(new HeaderPrivate())
 {
+  d = new HeaderPrivate;
   parse(data);
 }
 
-MPEG::Header::Header(const Header &h) 
-  : d(h.d)
+MPEG::Header::Header(const Header &h) : d(h.d)
 {
+  d->ref();
 }
 
 MPEG::Header::~Header()
 {
+  if (d->deref())
+    delete d;
 }
 
 bool MPEG::Header::isValid() const
@@ -144,7 +146,14 @@ int MPEG::Header::samplesPerFrame() const
 
 MPEG::Header &MPEG::Header::operator=(const Header &h)
 {
+  if(&h == this)
+    return *this;
+
+  if(d->deref())
+    delete d;
+
   d = h.d;
+  d->ref();
   return *this;
 }
 
index 7a352ed70811932d37b94c4bc2ff0e90d2227ef9..020ebd060302cd7ec4883aa94f5c4243b074bc00 100644 (file)
@@ -27,7 +27,6 @@
 #define TAGLIB_MPEGHEADER_H
 
 #include "taglib_export.h"
-#include "trefcountptr.h"
 
 namespace TagLib {
 
@@ -159,7 +158,7 @@ namespace TagLib {
       void parse(const ByteVector &data);
 
       class HeaderPrivate;
-      RefCountPtr<HeaderPrivate> d;
+      HeaderPrivate *d;
     };
   }
 }
index 03d16724f3200976916c893784496487e16516e3..dd4ee69da8b050b341f58bb681435369545cc9cc 100755 (executable)
 #include <string>
 #include <climits>
 
-#ifdef _WIN32
-# if !defined(NOMINMAX)
-#   define NOMINMAX
-# endif
-# include <windows.h>
+#ifdef __APPLE__
+#  include <libkern/OSAtomic.h>
+#  define TAGLIB_ATOMIC_MAC
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#  if !defined(NOMINMAX)
+#    define NOMINMAX
+#  endif
+#  include <windows.h>
+#  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 <ia64intrin.h>
+#  define TAGLIB_ATOMIC_GCC
 #endif
 
 // Check the widths of integral types.
@@ -104,6 +116,50 @@ namespace TagLib {
    * so I'm providing something here that should be constant.
    */
   typedef std::basic_string<wchar> 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 <b>is not</b> part of the TagLib public API!
+   */
+
+  class RefCounter
+  {
+  public:
+    RefCounter() : refCount(1) {}
+
+#ifdef TAGLIB_ATOMIC_MAC
+    void ref() { OSAtomicIncrement32Barrier(const_cast<int32_t*>(&refCount)); }
+    bool deref() { return ! OSAtomicDecrement32Barrier(const_cast<int32_t*>(&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 // DO_NOT_DOCUMENT
+
 }
 
 /*!
index aa76d6bff1b215a6471ec5baed589784a513127a..ca65cfaa8b2c1b7812565eff9ec4d10936021e69 100644 (file)
@@ -236,7 +236,7 @@ ByteVector fromNumber(T value, bool mostSignificantByteFirst)
   return ByteVector(reinterpret_cast<const char *>(&value), size);
 }
 
-class DataPrivate
+class DataPrivate : public RefCounter
 {
 public:
   DataPrivate()
@@ -262,39 +262,45 @@ public:
   std::vector<char> data;
 };
 
-class ByteVector::ByteVectorPrivate 
+class ByteVector::ByteVectorPrivate : public RefCounter
 {
 public:
   ByteVectorPrivate() 
-    : data(new DataPrivate())
+    : RefCounter()
+    , data(new DataPrivate())
     , offset(0)
     , length(0) 
   {
   }
 
-  ByteVectorPrivate(RefCountPtr<ByteVectorPrivate> d, uint o, uint l)
-    : data(d->data)
+  ByteVectorPrivate(ByteVectorPrivate *d, uint o, uint l)
+    : RefCounter()
+    , data(d->data)
     , offset(d->offset + o)
     , length(l)
   {
+    data->ref();
   }
 
   ByteVectorPrivate(const std::vector<char> &v, uint o, uint l)
-    : data(new DataPrivate(v, o, l))
+    : RefCounter()
+    , data(new DataPrivate(v, o, l))
     , offset(0)
     , length(l)
   {
   }
 
   ByteVectorPrivate(uint l, char c) 
-    : data(new DataPrivate(l, c))
+    : RefCounter()
+    , data(new DataPrivate(l, c))
     , offset(0)
     , length(l)
   {
   }
 
   ByteVectorPrivate(const char *s, uint l) 
-    : data(new DataPrivate(s, s + l))
+    : RefCounter()
+    , data(new DataPrivate(s, s + l))
     , offset(0)
     , length(l)
   {
@@ -302,25 +308,34 @@ public:
   
   void detach()
   {
-    if(!data.unique()) {
-      data.reset(new DataPrivate(data->data, offset, length));
+    if(data->count() > 1) {
+      data->deref();
+      data = new DataPrivate(data->data, offset, length);
       offset = 0;
     }
   }
 
   ~ByteVectorPrivate()
   {
+    if(data->deref())
+      delete data;
   }
 
   ByteVectorPrivate &operator=(const ByteVectorPrivate &x)
   {
     if(&x != this)
+    {
+      if(data->deref())
+        delete data;
+
       data = x.data;
+      data->ref();
+    }
 
     return *this;
   }
 
-  RefCountPtr<DataPrivate> data;
+  DataPrivate *data;
   uint offset;
   uint length;
 };
@@ -371,11 +386,13 @@ ByteVector::ByteVector(uint size, char value)
 ByteVector::ByteVector(const ByteVector &v) 
   : d(v.d)
 {
+  d->ref();
 }
 
 ByteVector::ByteVector(const ByteVector &v, uint offset, uint length)
   : d(new ByteVectorPrivate(v.d, offset, length))
 {
+  d->ref();
 }
 
 ByteVector::ByteVector(char c)
@@ -395,6 +412,8 @@ ByteVector::ByteVector(const char *data)
 
 ByteVector::~ByteVector()
 {
+  if(d->deref())
+    delete d;
 }
 
 ByteVector &ByteVector::setData(const char *s, uint length)
@@ -544,7 +563,10 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit
   }
 
   // replace private data:
-  d.reset(newData);
+  if(d->deref())
+    delete d;
+
+  d = newData;
 
   return *this;
 }
@@ -743,7 +765,14 @@ ByteVector ByteVector::operator+(const ByteVector &v) const
 
 ByteVector &ByteVector::operator=(const ByteVector &v)
 {
+  if(&v == this)
+    return *this;
+
+  if(d->deref())
+    delete d;
+
   d = v.d;
+  d->ref();
   return *this;
 }
 
@@ -779,10 +808,16 @@ ByteVector ByteVector::toHex() const
 
 void ByteVector::detach()
 {
-  d->detach();
+  if(d->data->count() > 1) {
+    d->data->deref();
+    d->data = new DataPrivate(d->data->data, d->offset, d->length);
+    d->offset = 0;
+  }
 
-  if(!d.unique())
-    d.reset(new ByteVectorPrivate(d->data->data, d->offset, d->length));
+  if(d->count() > 1) {
+    d->deref();
+    d = new ByteVectorPrivate(d->data->data, d->offset, d->length);
+  }
 }
 }
 
index cf7f66d5f0801f125da983b63da0e1fd96c6b0cc..ca810130f11244a46efe5d8ae9c7a2c9ce8245ef 100644 (file)
@@ -26,9 +26,9 @@
 #ifndef TAGLIB_BYTEVECTOR_H
 #define TAGLIB_BYTEVECTOR_H
 
-#include "taglib_export.h"
 #include "taglib.h"
-#include "trefcountptr.h"
+#include "taglib_export.h"
+
 #include <vector>
 #include <iostream>
 
@@ -446,7 +446,7 @@ namespace TagLib {
 
   private:
     class ByteVectorPrivate;
-    RefCountPtr<ByteVectorPrivate> d;
+    ByteVectorPrivate *d;
   };
 }
 
index ce1a0d0db3de44c6da90feaca1bd82c12d77c2b7..3e7de22aa5189b9419c81c79250101211d4129bc 100644 (file)
@@ -38,13 +38,8 @@ namespace TagLib {
   public:
     FileName(const wchar_t *name) : m_wname(name) {}
     FileName(const char *name) : m_name(name) {}
-    
     operator const wchar_t *() const { return m_wname.c_str(); }
     operator const char *() const { return m_name.c_str(); }
-  
-    const std::wstring &wstr() const { return m_wname; }
-    const std::string  &str()  const { return m_name; }  
-  
   private:
     std::string m_name;
     std::wstring m_wname;
index 535b374f1db722c7e1952381591a627fc1c6ac37..0099dad56d03584a996900b32f4f538703603661 100644 (file)
@@ -27,7 +27,7 @@
 #define TAGLIB_LIST_H
 
 #include "taglib.h"
-#include "trefcountptr.h"
+
 #include <list>
 
 namespace TagLib {
@@ -243,7 +243,7 @@ namespace TagLib {
   private:
 #ifndef DO_NOT_DOCUMENT
     template <class TP> class ListPrivate;
-    RefCountPtr<ListPrivate<T> > d;
+    ListPrivate<T> *d;
 #endif
   };
 
index 17d68a5a35b0acad98d64de58fc31b517a30a388..37817f0592cf72ed3ba7f8627d43d99e397dea8e 100644 (file)
@@ -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
+class ListPrivateBase : public RefCounter
 {
 public:
   ListPrivateBase() : autoDelete(false) {}
@@ -53,9 +53,8 @@ template <class TP> class List<T>::ListPrivate  : public ListPrivateBase
 public:
   ListPrivate() : ListPrivateBase() {}
   ListPrivate(const std::list<TP> &l) : ListPrivateBase(), list(l) {}
-
   void clear() {
-    std::list<TP>().swap(list);
+    list.clear();
   }
   std::list<TP> list;
 };
@@ -69,27 +68,18 @@ template <class TP> class List<T>::ListPrivate<TP *>  : public ListPrivateBase
 public:
   ListPrivate() : ListPrivateBase() {}
   ListPrivate(const std::list<TP *> &l) : ListPrivateBase(), list(l) {}
-
   ~ListPrivate() {
-    deletePointers();
+    clear();
   }
-
   void clear() {
-    deletePointers();
-    std::list<TP *>().swap(list);
+    if(autoDelete) {
+      typename std::list<TP *>::const_iterator it = list.begin();
+      for(; it != list.end(); ++it)
+        delete *it;
+    }
+    list.clear();
   }
-
   std::list<TP *> list;
-
-private:
-  void deletePointers() {
-    if(!autoDelete)
-      return;
-    
-    typename std::list<TP *>::const_iterator it = list.begin();
-    for(; it != list.end(); ++it)
-    delete *it;
-  }
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -98,19 +88,21 @@ private:
 
 template <class T>
 List<T>::List()
-  : d(new ListPrivate<T>())
 {
+  d = new ListPrivate<T>;
 }
 
 template <class T>
-List<T>::List(const List<T> &l) 
-  : d(l.d)
+List<T>::List(const List<T> &l) : d(l.d)
 {
+  d->ref();
 }
 
 template <class T>
 List<T>::~List()
 {
+  if(d->deref())
+    delete d;
 }
 
 template <class T>
@@ -187,7 +179,7 @@ template <class T>
 List<T> &List<T>::prepend(const List<T> &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;
 }
 
@@ -200,7 +192,7 @@ List<T> &List<T>::clear()
 }
 
 template <class T>
-uint List<T>::size() const
+TagLib::uint List<T>::size() const
 {
   return d->list.size();
 }
@@ -292,7 +284,13 @@ const T &List<T>::operator[](uint i) const
 template <class T>
 List<T> &List<T>::operator=(const List<T> &l)
 {
+  if(&l == this)
+    return *this;
+
+  if(d->deref())
+    delete d;
   d = l.d;
+  d->ref();
   return *this;
 }
 
@@ -315,8 +313,10 @@ bool List<T>::operator!=(const List<T> &l) const
 template <class T>
 void List<T>::detach()
 {
-  if(!d.unique())
-    d.reset(new ListPrivate<T>(d->list));
+  if(d->count() > 1) {
+    d->deref();
+    d = new ListPrivate<T>(d->list);
+  }
 }
 
 } // namespace TagLib
index b5748e66c45f5101b5931b253437001bf89a8da1..a7d99303572bac6fca801fa7f43d8d6653cfcf37 100644 (file)
 #ifndef TAGLIB_MAP_H
 #define TAGLIB_MAP_H
 
-#include "taglib.h"
-#include "trefcountptr.h"
 #include <map>
 
+#include "taglib.h"
 
 namespace TagLib {
 
@@ -186,7 +185,7 @@ namespace TagLib {
   private:
 #ifndef DO_NOT_DOCUMENT
     template <class KeyP, class TP> class MapPrivate;
-    RefCountPtr<MapPrivate<Key, T> > d;
+    MapPrivate<Key, T> *d;
 #endif
   };
 
index 783f99ccf353ea15084ee0e9070c49c761404e4f..0f2b99332e55bc5a48b4a44753784965f10d66d4 100644 (file)
@@ -31,49 +31,36 @@ namespace TagLib {
 
 template <class Key, class T>
 template <class KeyP, class TP>
-class Map<Key, T>::MapPrivate
+class Map<Key, T>::MapPrivate : public RefCounter
 {
 public:
-  MapPrivate() {}
-
+  MapPrivate() : RefCounter() {}
 #ifdef WANT_CLASS_INSTANTIATION_OF_MAP
-
-  MapPrivate(const std::map<class KeyP, class TP> &m) : RefCounter(), map(m) {}
-
-  void clear() {
-    std::map<class KeyP, class TP>().swap(map);
-  }
-
+  MapPrivate(const std::map<class KeyP, class TP>& m) : RefCounter(), map(m) {}
   std::map<class KeyP, class TP> map;
-
 #else
-
-  MapPrivate(const std::map<KeyP, TP>& m) : map(m) {}
-
-  void clear() {
-    std::map<KeyP, TP>().swap(map);
-  }
-
+  MapPrivate(const std::map<KeyP, TP>& m) : RefCounter(), map(m) {}
   std::map<KeyP, TP> map;
-
 #endif
 };
 
 template <class Key, class T>
 Map<Key, T>::Map()
-  : d(new MapPrivate<Key, T>())
 {
+  d = new MapPrivate<Key, T>;
 }
 
 template <class Key, class T>
-Map<Key, T>::Map(const Map<Key, T> &m) 
-  : d(m.d)
+Map<Key, T>::Map(const Map<Key, T> &m) : d(m.d)
 {
+  d->ref();
 }
 
 template <class Key, class T>
 Map<Key, T>::~Map()
 {
+  if(d->deref())
+    delete(d);
 }
 
 template <class Key, class T>
@@ -162,7 +149,7 @@ Map<Key, T> &Map<Key,T>::erase(const Key &key)
 }
 
 template <class Key, class T>
-uint Map<Key, T>::size() const
+TagLib::uint Map<Key, T>::size() const
 {
   return d->map.size();
 }
@@ -183,7 +170,13 @@ T &Map<Key, T>::operator[](const Key &key)
 template <class Key, class T>
 Map<Key, T> &Map<Key, T>::operator=(const Map<Key, T> &m)
 {
+  if(&m == this)
+    return *this;
+
+  if(d->deref())
+    delete(d);
   d = m.d;
+  d->ref();
   return *this;
 }
 
@@ -194,8 +187,10 @@ Map<Key, T> &Map<Key, T>::operator=(const Map<Key, T> &m)
 template <class Key, class T>
 void Map<Key, T>::detach()
 {
-  if(!d.unique())
-    d.reset(new MapPrivate<Key, T>(d->map));
+  if(d->count() > 1) {
+    d->deref();
+    d = new MapPrivate<Key, T>(d->map);
+  }
 }
 
-} // namespace TagLib
\ No newline at end of file
+} // namespace TagLib
diff --git a/taglib/toolkit/trefcountptr.h b/taglib/toolkit/trefcountptr.h
deleted file mode 100644 (file)
index 492afcd..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/***************************************************************************
-    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
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#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 <b>is not</b> part of the TagLib public API!
- */
-
-// RefCountPtr<T> is just an alias of shared_ptr<T> if it is available.
-
-#if defined(HAVE_STD_SHARED_PTR)
-# include <memory>
-# define RefCountPtr std::tr1::shared_ptr
-
-#elif defined(HAVE_TR1_SHARED_PTR) 
-# include <tr1/memory>
-# define RefCountPtr std::tr1::shared_ptr
-
-#elif defined(HAVE_BOOST_SHARED_PTR) 
-# include <boost/shared_ptr.hpp>
-# define RefCountPtr boost::shared_ptr
-
-#else
-# ifdef __APPLE__
-#   include <libkern/OSAtomic.h>
-#   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 <ia64intrin.h>
-#   define TAGLIB_ATOMIC_GCC
-# endif
-
-namespace TagLib {
-
-  // RefCountPtr<T> mimics std::shared_ptr<T> if it is not available.
-
-  template<typename T>
-  class RefCountPtr
-  {
-  private:
-
-    // Counter base class. Provides a reference counter.
-
-    class CounterBase
-    {
-    public:
-      CounterBase() 
-        : count(1) 
-      {
-      }
-
-      virtual ~CounterBase()
-      {
-      }
-
-      void addref() 
-      { 
-        increment(&count); 
-      }
-
-      void release()
-      {
-        if(decrement(&count) == 0) {
-          dispose();
-          delete this;
-        }
-      }
-
-      long use_count() const
-      {
-        return static_cast<long>(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 <typename U>
-    class CounterImpl : public CounterBase
-    {
-    public:
-      CounterImpl(U *p)
-        : p(p)
-      {
-      }
-
-      virtual void dispose() 
-      { 
-        delete p; 
-      }
-
-      U *get() const
-      {
-        return p;
-      }
-
-    private:
-      U *p;
-    };
-
-  public:
-    template <typename U>
-    explicit RefCountPtr(U *p)
-      : counter(new CounterImpl<U>(p))
-    {
-    }
-
-    RefCountPtr(const RefCountPtr &x)
-    {
-      counter = x.counter;
-      counter->addref();
-    }
-
-    ~RefCountPtr()
-    {
-      counter->release();
-    }
-
-    T *get() const
-    {
-      return static_cast<CounterImpl<T>*>(counter)->get();
-    }
-
-    long use_count() const
-    {
-      return counter->use_count();
-    }
-
-    bool unique() const 
-    { 
-      return (use_count() == 1);
-    }
-
-    template <typename U>
-    void reset(U *p)
-    {
-      if(get() != p)
-      {
-        counter->release();
-        counter = new CounterImpl<U>(p);
-      }
-    }
-
-    RefCountPtr<T> &operator=(const RefCountPtr<T> &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<T> &x) const 
-    {
-      return (get() == x.get());
-    }
-
-    bool operator!=(const RefCountPtr<T> &x) const
-    {
-      return !operator==(x);
-    }
-
-    operator bool() const
-    {
-      return (get() != 0);
-    }
-
-  private:
-    CounterBase *counter;
-  };
-}
-#endif // TAGLIB_USE_CXX11
-
-#endif // DO_NOT_DOCUMENT
-
-#endif
\ No newline at end of file
index 14abae2f3d0504f0ca8fc9885742e4fb03f0c856..219d3daf6ceb48fed46f8926bb818236b694072d 100644 (file)
@@ -30,6 +30,7 @@
 #include "tstringlist.h"
 #include "tbyteswap.h"
 
+#include <iostream>
 #include <string.h>
 
 // Determine if the compiler supports codecvt.
@@ -55,20 +56,23 @@ namespace {
 
 namespace TagLib {
 
-class String::StringPrivate
+class String::StringPrivate : public RefCounter
 {
 public:
   StringPrivate() 
+    : RefCounter() 
   {
   }
 
   StringPrivate(const wstring &s) 
-    : data(s) 
+    : RefCounter()
+    , data(s) 
   {
   }
   
   StringPrivate(uint n, wchar_t c) 
-    : data(static_cast<size_t>(n), c) 
+    : RefCounter()
+    , data(static_cast<size_t>(n), c) 
   {
   }
 
@@ -95,6 +99,7 @@ String::String()
 String::String(const String &s) 
   : d(s.d)
 {
+  d->ref();
 }
 
 String::String(const std::string &s, Type t)
@@ -177,6 +182,8 @@ String::String(const ByteVector &v, Type t)
 
 String::~String()
 {
+  if(d->deref())
+    delete d;
 }
 
 std::string String::to8Bit(bool unicode) const
@@ -609,13 +616,22 @@ String &String::operator+=(char c)
 
 String &String::operator=(const String &s)
 {
+  if(&s == this)
+    return *this;
+
+  if(d->deref())
+    delete d;
   d = s.d;
+  d->ref();
   return *this;
 }
 
 String &String::operator=(const std::string &s)
 {
-  d.reset(new StringPrivate());
+  if(d->deref())
+    delete d;
+
+  d = new StringPrivate;
   copyFromLatin1(s.c_str(), s.length());
 
   return *this;
@@ -623,33 +639,45 @@ String &String::operator=(const std::string &s)
 
 String &String::operator=(const wstring &s)
 {
-  d.reset(new StringPrivate(s));
+  if(d->deref())
+    delete d;
+  d = new StringPrivate(s);
   return *this;
 }
 
 String &String::operator=(const wchar_t *s)
 {
-  d.reset(new StringPrivate());
-  copyFromUTF16(s, ::wcslen(s), WCharByteOrder);
+  if(d->deref())
+    delete d;
 
+  d = new StringPrivate(s);
   return *this;
 }
 
 String &String::operator=(char c)
 {
-  d.reset(new StringPrivate(1, static_cast<uchar>(c)));
+  if(d->deref())
+    delete d;
+
+  d = new StringPrivate(1, static_cast<uchar>(c));
   return *this;
 }
 
 String &String::operator=(wchar_t c)
 {
-  d.reset(new StringPrivate(1, static_cast<uchar>(c)));
+  if(d->deref())
+    delete d;
+
+  d = new StringPrivate(1, static_cast<uchar>(c));
   return *this;
 }
 
 String &String::operator=(const char *s)
 {
-  d.reset(new StringPrivate());
+  if(d->deref())
+    delete d;
+
+  d = new StringPrivate;
   copyFromLatin1(s, ::strlen(s));
 
   return *this;
@@ -657,7 +685,10 @@ String &String::operator=(const char *s)
 
 String &String::operator=(const ByteVector &v)
 {
-  d.reset(new StringPrivate());
+  if(d->deref())
+    delete d;
+
+  d = new StringPrivate;
   copyFromLatin1(v.data(), v.size());
 
   // If we hit a null in the ByteVector, shrink the string again.
@@ -677,8 +708,10 @@ bool String::operator<(const String &s) const
 
 void String::detach()
 {
-  if(!d.unique())
-    d.reset(new StringPrivate(d->data));
+  if(d->count() > 1) {
+    d->deref();
+    d = new StringPrivate(d->data);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index 652c6ca74189c81fe8647223e15c5cbf59fe596c..150d7c37a61765003f38f470aea6e562cb921cbe 100644 (file)
 #ifndef TAGLIB_STRING_H
 #define TAGLIB_STRING_H
 
+#include "taglib_export.h"
+#include "taglib.h"
 #include "tbytevector.h"
+
 #include <string>
+#include <iostream>
 
 /*!
  * \relates TagLib::String
@@ -481,7 +485,7 @@ namespace TagLib {
     static const Type WCharByteOrder;
 
     class StringPrivate;
-    RefCountPtr<StringPrivate> d;
+    StringPrivate *d;
   };
 }