From 04e07ad4b05e67f295b04e760b865662d18c8f10 Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Sun, 5 May 2013 19:22:33 +0900 Subject: [PATCH] Moved some macros from taglib_config.h to config.h. --- ConfigureChecks.cmake | 96 ++++++++++++++--------------- config.h.cmake | 6 ++ taglib/CMakeLists.txt | 2 + taglib/mpeg/mpegheader.h | 2 +- taglib/taglib_config.h.cmake | 6 -- taglib/toolkit/tbytevector.h | 2 +- taglib/toolkit/tlist.h | 2 +- taglib/toolkit/tmap.h | 2 +- taglib/toolkit/trefcountptr.cpp | 106 ++++++++++++++++++++++++++++++++ taglib/toolkit/trefcountptr.h | 69 ++++++--------------- taglib/toolkit/tsmartptr.h | 54 ++++++++++++++++ tests/test_smartptr.cpp | 3 +- 12 files changed, 241 insertions(+), 109 deletions(-) create mode 100644 taglib/toolkit/trefcountptr.cpp create mode 100644 taglib/toolkit/tsmartptr.h diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 41be3f76..134d584e 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -118,6 +118,53 @@ if(NOT HAVE_GCC_BYTESWAP_16 OR NOT HAVE_GCC_BYTESWAP_32 OR NOT HAVE_GCC_BYTESWAP endif() endif() +# Determine which kind of atomic operations your compiler supports. + +check_cxx_source_compiles(" + int main() { + volatile int x; + __sync_add_and_fetch(&x, 1); + int y = __sync_sub_and_fetch(&x, 1); + return 0; + } +" HAVE_GCC_ATOMIC) + +if(NOT HAVE_GCC_ATOMIC) + check_cxx_source_compiles(" + #include + int main() { + volatile int32_t x; + OSAtomicIncrement32Barrier(&x); + int32_t y = OSAtomicDecrement32Barrier(&x); + return 0; + } + " HAVE_MAC_ATOMIC) + + if(NOT HAVE_MAC_ATOMIC) + check_cxx_source_compiles(" + #include + int main() { + volatile LONG x; + InterlockedIncrement(&x); + LONG y = InterlockedDecrement(&x); + return 0; + } + " HAVE_WIN_ATOMIC) + + if(NOT HAVE_WIN_ATOMIC) + check_cxx_source_compiles(" + #include + int main() { + volatile int x; + __sync_add_and_fetch(&x, 1); + int y = __sync_sub_and_fetch(&x, 1); + return 0; + } + " HAVE_IA64_ATOMIC) + endif() + endif() +endif() + # Determine whether your compiler supports some safer version of sprintf. check_cxx_source_compiles(" @@ -183,55 +230,6 @@ if(NOT TAGLIB_USE_STD_SHARED_PTR) endif() endif() -# Determine which kind of atomic operations your compiler supports. - -if(NOT TAGLIB_USE_STD_SHARED_PTR AND NOT TAGLIB_USE_TR1_SHARED_PTR AND NOT TAGLIB_USE_BOOST_SHARED_PTR) - check_cxx_source_compiles(" - int main() { - volatile int x; - __sync_add_and_fetch(&x, 1); - int y = __sync_sub_and_fetch(&x, 1); - return 0; - } - " TAGLIB_USE_GCC_ATOMIC) - - if(NOT TAGLIB_USE_GCC_ATOMIC) - check_cxx_source_compiles(" - #include - int main() { - volatile int32_t x; - OSAtomicIncrement32Barrier(&x); - int32_t y = OSAtomicDecrement32Barrier(&x); - return 0; - } - " TAGLIB_USE_MAC_ATOMIC) - - if(NOT TAGLIB_USE_MAC_ATOMIC) - check_cxx_source_compiles(" - #include - int main() { - volatile LONG x; - InterlockedIncrement(&x); - LONG y = InterlockedDecrement(&x); - return 0; - } - " TAGLIB_USE_WIN_ATOMIC) - - if(NOT TAGLIB_USE_WIN_ATOMIC) - check_cxx_source_compiles(" - #include - int main() { - volatile int x; - __sync_add_and_fetch(&x, 1); - int y = __sync_sub_and_fetch(&x, 1); - return 0; - } - " TAGLIB_USE_IA64_ATOMIC) - endif() - endif() - endif() -endif() - # Determine whether CppUnit is installed. set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) diff --git a/config.h.cmake b/config.h.cmake index 9fe798ef..8424abf6 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -18,6 +18,12 @@ #cmakedefine HAVE_MAC_BYTESWAP 1 #cmakedefine HAVE_OPENBSD_BYTESWAP 1 +/* Defined if your compiler supports some atomic operations */ +#cmakedefine HAVE_GCC_ATOMIC 1 +#cmakedefine HAVE_MAC_ATOMIC 1 +#cmakedefine HAVE_WIN_ATOMIC 1 +#cmakedefine HAVE_IA64_ATOMIC 1 + /* Defined if your compiler supports some safer version of sprintf */ #cmakedefine HAVE_SNPRINTF 1 #cmakedefine HAVE_SPRINTF_S 1 diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index 315528fc..56d4d15e 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -53,6 +53,7 @@ set(tag_HDRS toolkit/tmap.h toolkit/tmap.tcc toolkit/tpropertymap.h + toolkit/tsmartptr.h toolkit/trefcountptr.h mpeg/mpegfile.h mpeg/mpegproperties.h @@ -300,6 +301,7 @@ set(toolkit_SRCS toolkit/tfilestream.cpp toolkit/tdebug.cpp toolkit/tpropertymap.cpp + toolkit/trefcountptr.cpp toolkit/unicode.cpp ) diff --git a/taglib/mpeg/mpegheader.h b/taglib/mpeg/mpegheader.h index 5041b01e..56749465 100644 --- a/taglib/mpeg/mpegheader.h +++ b/taglib/mpeg/mpegheader.h @@ -27,7 +27,7 @@ #define TAGLIB_MPEGHEADER_H #include "taglib_export.h" -#include "trefcountptr.h" +#include "tsmartptr.h" namespace TagLib { diff --git a/taglib/taglib_config.h.cmake b/taglib/taglib_config.h.cmake index 8231bff0..036f2cfd 100644 --- a/taglib/taglib_config.h.cmake +++ b/taglib/taglib_config.h.cmake @@ -11,9 +11,3 @@ #cmakedefine TAGLIB_USE_TR1_SHARED_PTR 1 #cmakedefine TAGLIB_USE_BOOST_SHARED_PTR 1 -/* Defined if your compiler supports some atomic operations */ -#cmakedefine TAGLIB_USE_GCC_ATOMIC 1 -#cmakedefine TAGLIB_USE_MAC_ATOMIC 1 -#cmakedefine TAGLIB_USE_WIN_ATOMIC 1 -#cmakedefine TAGLIB_USE_IA64_ATOMIC 1 - diff --git a/taglib/toolkit/tbytevector.h b/taglib/toolkit/tbytevector.h index e564e3d3..613f4306 100644 --- a/taglib/toolkit/tbytevector.h +++ b/taglib/toolkit/tbytevector.h @@ -28,7 +28,7 @@ #include "taglib_export.h" #include "taglib.h" -#include "trefcountptr.h" +#include "tsmartptr.h" #include #include diff --git a/taglib/toolkit/tlist.h b/taglib/toolkit/tlist.h index b8aa6641..51338748 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 "tsmartptr.h" #include namespace TagLib { diff --git a/taglib/toolkit/tmap.h b/taglib/toolkit/tmap.h index 927e9f2b..46d82f99 100644 --- a/taglib/toolkit/tmap.h +++ b/taglib/toolkit/tmap.h @@ -27,7 +27,7 @@ #define TAGLIB_MAP_H #include "taglib.h" -#include "trefcountptr.h" +#include "tsmartptr.h" #include namespace TagLib { diff --git a/taglib/toolkit/trefcountptr.cpp b/taglib/toolkit/trefcountptr.cpp new file mode 100644 index 00000000..cfd469a5 --- /dev/null +++ b/taglib/toolkit/trefcountptr.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + 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/ * + ***************************************************************************/ + +#include "config.h" +#include "trefcountptr.h" + +#if defined(HAVE_STD_ATOMIC) +# include +# define ATOMIC_INT std::atomic +# define ATOMIC_INC(x) x.fetch_add(1) +# define ATOMIC_DEC(x) (x.fetch_sub(1) - 1) +#elif defined(HAVE_BOOST_ATOMIC) +# include +# define ATOMIC_INT boost::atomic +# define ATOMIC_INC(x) x.fetch_add(1) +# define ATOMIC_DEC(x) (x.fetch_sub(1) - 1) +#elif defined(HAVE_GCC_ATOMIC) +# define ATOMIC_INT int +# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1) +# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1) +#elif defined(HAVE_WIN_ATOMIC) +# if !defined(NOMINMAX) +# define NOMINMAX +# endif +# include +# define ATOMIC_INT long +# define ATOMIC_INC(x) InterlockedIncrement(&x) +# define ATOMIC_DEC(x) InterlockedDecrement(&x) +#elif defined(HAVE_MAC_ATOMIC) +# include +# define ATOMIC_INT int32_t +# define ATOMIC_INC(x) OSAtomicIncrement32Barrier(&x) +# define ATOMIC_DEC(x) OSAtomicDecrement32Barrier(&x) +#elif defined(HAVE_IA64_ATOMIC) +# include +# define ATOMIC_INT int +# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1) +# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1) +#else +# define ATOMIC_INT int +# define ATOMIC_INC(x) (++x) +# define ATOMIC_DEC(x) (--x) +#endif + +namespace TagLib +{ + class RefCounter::RefCounterPrivate + { + public: + RefCounterPrivate() : refCount(1) {} + + size_t ref() { return static_cast(ATOMIC_INC(refCount)); } + size_t deref() { return static_cast(ATOMIC_DEC(refCount)); } + size_t count() const { return static_cast(refCount); } + + volatile ATOMIC_INT refCount; + }; + + RefCounter::RefCounter() + : d(new RefCounterPrivate()) + { + } + + RefCounter::~RefCounter() + { + delete d; + } + + size_t RefCounter::ref() + { + return d->ref(); + } + + size_t RefCounter::deref() + { + return d->deref(); + } + + size_t RefCounter::count() const + { + return d->count(); + } +} + diff --git a/taglib/toolkit/trefcountptr.h b/taglib/toolkit/trefcountptr.h index 8868861e..a1c578b4 100644 --- a/taglib/toolkit/trefcountptr.h +++ b/taglib/toolkit/trefcountptr.h @@ -26,44 +26,7 @@ #ifndef TAGLIB_REFCOUNTPTR_H #define TAGLIB_REFCOUNTPTR_H -#include "taglib_config.h" - -#if defined(TAGLIB_USE_STD_SHARED_PTR) -# include -#elif defined(TAGLIB_USE_TR1_SHARED_PTR) -# include -#elif defined(TAGLIB_USE_BOOST_SHARED_PTR) -# include -#else -# include -# if defined(TAGLIB_USE_GCC_ATOMIC) -# define TAGLIB_ATOMIC_INT int -# define TAGLIB_ATOMIC_INC(x) __sync_add_and_fetch(&x, 1) -# define TAGLIB_ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1) -# elif defined(TAGLIB_USE_WIN_ATOMIC) -# if !defined(NOMINMAX) -# define NOMINMAX -# endif -# include -# define TAGLIB_ATOMIC_INT long -# define TAGLIB_ATOMIC_INC(x) InterlockedIncrement(&x) -# define TAGLIB_ATOMIC_DEC(x) InterlockedDecrement(&x) -# elif defined(TAGLIB_USE_MAC_ATOMIC) -# include -# define TAGLIB_ATOMIC_INT int32_t -# define TAGLIB_ATOMIC_INC(x) OSAtomicIncrement32Barrier(&x) -# define TAGLIB_ATOMIC_DEC(x) OSAtomicDecrement32Barrier(&x) -# elif defined(TAGLIB_USE_IA64_ATOMIC) -# include -# define TAGLIB_ATOMIC_INT int -# define TAGLIB_ATOMIC_INC(x) __sync_add_and_fetch(&x, 1) -# define TAGLIB_ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1) -# else -# define TAGLIB_ATOMIC_INT int -# define TAGLIB_ATOMIC_INC(x) (++x) -# define TAGLIB_ATOMIC_DEC(x) (--x) -# endif -#endif +#include #ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class. /*! @@ -87,7 +50,22 @@ namespace TagLib { // Self-implements RefCountPtr if shared_ptr is not available. // I STRONGLY RECOMMEND using standard shared_ptr rather than this class. + + class RefCounter + { + public: + RefCounter(); + ~RefCounter(); + size_t ref(); + size_t deref(); + size_t count() const; + + private: + class RefCounterPrivate; + RefCounterPrivate *d; + }; + template class RefCountPtr { @@ -98,23 +76,18 @@ namespace TagLib { class CounterBase { public: - CounterBase() - : count(1) - { - } - virtual ~CounterBase() { } void addref() { - TAGLIB_ATOMIC_INC(count); + count.ref(); } void release() { - if(TAGLIB_ATOMIC_DEC(count) == 0) { + if(count.deref() == 0) { dispose(); delete this; } @@ -122,13 +95,13 @@ namespace TagLib { long use_count() const { - return static_cast(count); + return static_cast(count.count()); } virtual void dispose() = 0; private: - volatile TAGLIB_ATOMIC_INT count; + RefCounter count; }; // Counter impl class. Provides a dynamic deleter. @@ -287,8 +260,6 @@ namespace TagLib { template friend class RefCountPtr; }; -# define TAGLIB_SHARED_PTR TagLib::RefCountPtr - template void swap(RefCountPtr &a, RefCountPtr &b) { diff --git a/taglib/toolkit/tsmartptr.h b/taglib/toolkit/tsmartptr.h new file mode 100644 index 00000000..a86749d3 --- /dev/null +++ b/taglib/toolkit/tsmartptr.h @@ -0,0 +1,54 @@ +/*************************************************************************** + copyright : (C) 2013 by Tsuda Kageyu + email : tsuda.kageyu@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_SMARTPTR_H +#define TAGLIB_SMARTPTR_H + +#include "taglib_config.h" + +#if defined(TAGLIB_USE_STD_SHARED_PTR) +# include +#elif defined(TAGLIB_USE_TR1_SHARED_PTR) +# include +#elif defined(TAGLIB_USE_BOOST_SHARED_PTR) +# include +#else +# include "trefcountptr.h" +#endif + +#if defined(TAGLIB_USE_STD_SHARED_PTR) || defined(TAGLIB_USE_TR1_SHARED_PTR) + +# define TAGLIB_SHARED_PTR std::tr1::shared_ptr + +#elif defined(TAGLIB_USE_BOOST_SHARED_PTR) + +# define TAGLIB_SHARED_PTR boost::shared_ptr + +#else + +# define TAGLIB_SHARED_PTR TagLib::RefCountPtr + +#endif +#endif diff --git a/tests/test_smartptr.cpp b/tests/test_smartptr.cpp index 4fd9b3bf..cb481684 100644 --- a/tests/test_smartptr.cpp +++ b/tests/test_smartptr.cpp @@ -1,5 +1,6 @@ -#include #include +#include "taglib.h" +#include "tsmartptr.h" #include "utils.h" using namespace std;