Revert changes concerning the smart pointer

This commit is contained in:
Tsuda kageyu 2013-04-17 22:54:56 +09:00
parent b6c9fb2da1
commit 1f4e06ea7c
26 changed files with 329 additions and 463 deletions

View 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()

View 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

View 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}

View 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;
}

View File

@ -194,7 +194,7 @@ namespace TagLib
ByteVector render(const String &name, int kind = 0) const;
class AttributePrivate;
RefCountPtr<AttributePrivate> d;
AttributePrivate *d;
};
}

View 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;
}

View 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;
};
}
}

View File

@ -31,10 +31,6 @@
#include <config.h>
#endif
#ifdef _WIN32
# include <Shlwapi.h>
#endif
#include <tfile.h>
#include <tstring.h>
#include <tdebug.h>
@ -61,12 +57,15 @@
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")

View File

@ -255,7 +255,7 @@ namespace TagLib {
private:
class FileRefPrivate;
RefCountPtr<FileRefPrivate> d;
FileRefPrivate *d;
};
} // namespace TagLib

View File

@ -33,35 +33,43 @@
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

View File

@ -63,7 +63,7 @@ namespace TagLib {
private:
class CoverArtPrivate;
RefCountPtr<CoverArtPrivate> d;
CoverArtPrivate *d;
};
typedef List<CoverArt> CoverArtList;

View File

@ -33,10 +33,10 @@
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;
}

View File

@ -73,7 +73,7 @@ namespace TagLib {
private:
class ItemPrivate;
RefCountPtr<ItemPrivate> d;
ItemPrivate *d;
};
}

View 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;
}

View 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;
};
}
}

View File

@ -45,11 +45,23 @@
#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
}
/*!

View 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);
}
}
}

View 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;
};
}

View 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;

View 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
};

View 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

View File

@ -26,10 +26,9 @@
#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
};

View 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
} // namespace TagLib

View File

@ -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

View 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);
}
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -26,8 +26,12 @@
#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;
};
}