From f7e659977e033f491f00d7e8720c8a4acfc62daf Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Wed, 16 May 2018 03:38:54 +0300 Subject: Move smart pointer classes into separated header --- src/adlmidi_ptr.hpp | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 src/adlmidi_ptr.hpp (limited to 'src/adlmidi_ptr.hpp') diff --git a/src/adlmidi_ptr.hpp b/src/adlmidi_ptr.hpp new file mode 100644 index 0000000..bd2b8fb --- /dev/null +++ b/src/adlmidi_ptr.hpp @@ -0,0 +1,195 @@ +/* + * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation + * + * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma + * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov + * + * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: + * http://iki.fi/bisqwit/source/adlmidi.html + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ADLMIDI_PTR_HPP_THING +#define ADLMIDI_PTR_HPP_THING +/* + Smart pointer for C heaps, created with malloc() call. + FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it +*/ +template +class AdlMIDI_CPtr +{ + PTR *m_p; +public: + AdlMIDI_CPtr() : m_p(NULL) {} + ~AdlMIDI_CPtr() + { + reset(NULL); + } + + void reset(PTR *p = NULL) + { + if(p != m_p) { + if(m_p) + free(m_p); + m_p = p; + } + } + + PTR *get() + { + return m_p; + } + PTR &operator*() + { + return *m_p; + } + PTR *operator->() + { + return m_p; + } +private: + AdlMIDI_CPtr(const AdlMIDI_CPtr &); + AdlMIDI_CPtr &operator=(const AdlMIDI_CPtr &); +}; + +template +class AdlMIDI_NArrPtr +{ + PTR *m_p; +public: + AdlMIDI_NArrPtr() : m_p(NULL) {} + AdlMIDI_NArrPtr(PTR *value) + { + reset(value); + } + + ~AdlMIDI_NArrPtr() + { + reset(NULL); + } + + void reset(PTR *p = NULL) + { + if(p != m_p) { + if(m_p) + delete [] m_p; + m_p = p; + } + } + + PTR *get() + { + return m_p; + } + PTR &operator*() + { + return *m_p; + } + PTR *operator->() + { + return m_p; + } + PTR operator[](size_t index) + { + return m_p[index]; + } + const PTR operator[](size_t index) const + { + return m_p[index]; + } + AdlMIDI_NArrPtr(AdlMIDI_NArrPtr &other) + { + m_p = other.m_p; + other.m_p = NULL; + } + AdlMIDI_NArrPtr &operator=(AdlMIDI_NArrPtr &other) + { + m_p = other.m_p; + other.m_p = NULL; + return m_p; + } +}; + +/* + Shared pointer with non-atomic counter + FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it +*/ +template +class AdlMIDI_SPtr +{ + VALUE *m_p; + size_t *m_counter; +public: + AdlMIDI_SPtr() : m_p(NULL), m_counter(NULL) {} + ~AdlMIDI_SPtr() + { + reset(NULL); + } + + AdlMIDI_SPtr(const AdlMIDI_SPtr &other) + : m_p(other.m_p), m_counter(other.m_counter) + { + if(m_counter) + ++*m_counter; + } + + AdlMIDI_SPtr &operator=(const AdlMIDI_SPtr &other) + { + if(this == &other) + return *this; + reset(); + m_p = other.m_p; + m_counter = other.m_counter; + if(m_counter) + ++*m_counter; + return *this; + } + + void reset(VALUE *p = NULL) + { + if(p != m_p) { + if(m_p && --*m_counter == 0) + delete m_p; + m_p = p; + if(!p) { + if(m_counter) { + delete m_counter; + m_counter = NULL; + } + } + else + { + if(!m_counter) + m_counter = new size_t; + *m_counter = 1; + } + } + } + + VALUE *get() + { + return m_p; + } + VALUE &operator*() + { + return *m_p; + } + VALUE *operator->() + { + return m_p; + } +}; + +#endif //ADLMIDI_PTR_HPP_THING -- cgit v1.2.3 From 8cce88f8706ca6fb52592458aa12641c43469a6e Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 03:27:07 +0200 Subject: c++98 support for bank map --- src/adlmidi_ptr.hpp | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'src/adlmidi_ptr.hpp') diff --git a/src/adlmidi_ptr.hpp b/src/adlmidi_ptr.hpp index bd2b8fb..7faacff 100644 --- a/src/adlmidi_ptr.hpp +++ b/src/adlmidi_ptr.hpp @@ -122,11 +122,25 @@ public: } }; +/* + Generic deleters for smart pointers + */ +template +struct ADLMIDI_DefaultDelete +{ + void operator()(T *x) { delete x; } +}; +template +struct ADLMIDI_DefaultArrayDelete +{ + void operator()(T *x) { delete[] x; } +}; + /* Shared pointer with non-atomic counter FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it */ -template +template< class VALUE, class DELETER = ADLMIDI_DefaultDelete > class AdlMIDI_SPtr { VALUE *m_p; @@ -160,8 +174,10 @@ public: void reset(VALUE *p = NULL) { if(p != m_p) { - if(m_p && --*m_counter == 0) - delete m_p; + if(m_p && --*m_counter == 0) { + DELETER del; + del(m_p); + } m_p = p; if(!p) { if(m_counter) { @@ -178,7 +194,7 @@ public: } } - VALUE *get() + VALUE *get() const { return m_p; } @@ -186,10 +202,20 @@ public: { return *m_p; } - VALUE *operator->() + const VALUE &operator*() const + { + return *m_p; + } + VALUE *operator->() const { return m_p; } }; +template +class AdlMIDI_SPtrArray : + public AdlMIDI_SPtr< VALUE, ADLMIDI_DefaultArrayDelete > +{ +}; + #endif //ADLMIDI_PTR_HPP_THING -- cgit v1.2.3 From 5574ad1dbe0195e13eae51b845385d4ed75c0990 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 18:04:48 +0200 Subject: fix a shared pointer bug which destroys a live counter --- src/adlmidi_ptr.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/adlmidi_ptr.hpp') diff --git a/src/adlmidi_ptr.hpp b/src/adlmidi_ptr.hpp index 7faacff..1e1a5f4 100644 --- a/src/adlmidi_ptr.hpp +++ b/src/adlmidi_ptr.hpp @@ -23,6 +23,9 @@ #ifndef ADLMIDI_PTR_HPP_THING #define ADLMIDI_PTR_HPP_THING + +#include + /* Smart pointer for C heaps, created with malloc() call. FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it @@ -177,16 +180,13 @@ public: if(m_p && --*m_counter == 0) { DELETER del; del(m_p); - } - m_p = p; - if(!p) { - if(m_counter) { + if(!p) { delete m_counter; m_counter = NULL; } } - else - { + m_p = p; + if(p) { if(!m_counter) m_counter = new size_t; *m_counter = 1; -- cgit v1.2.3 From 5b6ec1a766ae922f898a942eade2841a828c0ed0 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 18:27:43 +0200 Subject: smart pointers cleanup --- src/adlmidi_ptr.hpp | 176 +++++++++++++++++++++++++--------------------------- 1 file changed, 86 insertions(+), 90 deletions(-) (limited to 'src/adlmidi_ptr.hpp') diff --git a/src/adlmidi_ptr.hpp b/src/adlmidi_ptr.hpp index 1e1a5f4..7d1086b 100644 --- a/src/adlmidi_ptr.hpp +++ b/src/adlmidi_ptr.hpp @@ -24,132 +24,122 @@ #ifndef ADLMIDI_PTR_HPP_THING #define ADLMIDI_PTR_HPP_THING +#include // swap #include +#include /* - Smart pointer for C heaps, created with malloc() call. - FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it + Generic deleters for smart pointers + */ +template +struct ADLMIDI_DefaultDelete +{ + void operator()(T *x) { delete x; } +}; +template +struct ADLMIDI_DefaultArrayDelete +{ + void operator()(T *x) { delete[] x; } +}; +struct ADLMIDI_CDelete +{ + void operator()(void *x) { free(x); } +}; + +/* + Safe unique pointer for C++98, non-copyable but swappable. */ -template -class AdlMIDI_CPtr +template< class T, class Deleter = ADLMIDI_DefaultDelete > +class AdlMIDI_UPtr { - PTR *m_p; + T *m_p; public: - AdlMIDI_CPtr() : m_p(NULL) {} - ~AdlMIDI_CPtr() + explicit AdlMIDI_UPtr(T *p) + : m_p(p) {} + ~AdlMIDI_UPtr() { - reset(NULL); + reset(); } - void reset(PTR *p = NULL) + void reset(T *p = NULL) { if(p != m_p) { - if(m_p) - free(m_p); + if(m_p) { + Deleter del; + del(m_p); + } m_p = p; } } - PTR *get() - { - return m_p; - } - PTR &operator*() - { - return *m_p; - } - PTR *operator->() + void swap(AdlMIDI_UPtr &other) { - return m_p; - } -private: - AdlMIDI_CPtr(const AdlMIDI_CPtr &); - AdlMIDI_CPtr &operator=(const AdlMIDI_CPtr &); -}; - -template -class AdlMIDI_NArrPtr -{ - PTR *m_p; -public: - AdlMIDI_NArrPtr() : m_p(NULL) {} - AdlMIDI_NArrPtr(PTR *value) - { - reset(value); - } - - ~AdlMIDI_NArrPtr() - { - reset(NULL); + std::swap(m_p, other.m_p); } - void reset(PTR *p = NULL) - { - if(p != m_p) { - if(m_p) - delete [] m_p; - m_p = p; - } - } - - PTR *get() + T *get() const { return m_p; } - PTR &operator*() + T &operator*() const { return *m_p; } - PTR *operator->() + T *operator->() const { return m_p; } - PTR operator[](size_t index) + T &operator[](size_t index) const { return m_p[index]; } - const PTR operator[](size_t index) const - { - return m_p[index]; - } - AdlMIDI_NArrPtr(AdlMIDI_NArrPtr &other) - { - m_p = other.m_p; - other.m_p = NULL; - } - AdlMIDI_NArrPtr &operator=(AdlMIDI_NArrPtr &other) - { - m_p = other.m_p; - other.m_p = NULL; - return m_p; - } +private: + AdlMIDI_UPtr(const AdlMIDI_UPtr &); + AdlMIDI_UPtr &operator=(const AdlMIDI_UPtr &); }; -/* - Generic deleters for smart pointers - */ template -struct ADLMIDI_DefaultDelete +void swap(AdlMIDI_UPtr &a, AdlMIDI_UPtr &b) { - void operator()(T *x) { delete x; } + a.swap(b); +} + +/** + Unique pointer for arrays. + */ +template +class AdlMIDI_UPtrArray : + public AdlMIDI_UPtr< T, ADLMIDI_DefaultArrayDelete > +{ +public: + explicit AdlMIDI_UPtrArray(T *p = NULL) + : AdlMIDI_UPtr< T, ADLMIDI_DefaultArrayDelete >(p) {} }; -template -struct ADLMIDI_DefaultArrayDelete + +/** + Unique pointer for C memory. + */ +template +class AdlMIDI_CPtr : + public AdlMIDI_UPtr< T, ADLMIDI_CDelete > { - void operator()(T *x) { delete[] x; } +public: + explicit AdlMIDI_CPtr(T *p = NULL) + : AdlMIDI_UPtr< T, ADLMIDI_CDelete >(p) {} }; /* Shared pointer with non-atomic counter FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it */ -template< class VALUE, class DELETER = ADLMIDI_DefaultDelete > +template< class T, class Deleter = ADLMIDI_DefaultDelete > class AdlMIDI_SPtr { - VALUE *m_p; + T *m_p; size_t *m_counter; public: - AdlMIDI_SPtr() : m_p(NULL), m_counter(NULL) {} + explicit AdlMIDI_SPtr(T *p = NULL) + : m_p(p), m_counter(p ? new size_t(1) : NULL) {} ~AdlMIDI_SPtr() { reset(NULL); @@ -174,11 +164,11 @@ public: return *this; } - void reset(VALUE *p = NULL) + void reset(T *p = NULL) { if(p != m_p) { if(m_p && --*m_counter == 0) { - DELETER del; + Deleter del; del(m_p); if(!p) { delete m_counter; @@ -194,28 +184,34 @@ public: } } - VALUE *get() const + T *get() const { return m_p; } - VALUE &operator*() + T &operator*() const { return *m_p; } - const VALUE &operator*() const + T *operator->() const { - return *m_p; + return m_p; } - VALUE *operator->() const + T &operator[](size_t index) const { - return m_p; + return m_p[index]; } }; -template +/** + Shared pointer for arrays. + */ +template class AdlMIDI_SPtrArray : - public AdlMIDI_SPtr< VALUE, ADLMIDI_DefaultArrayDelete > + public AdlMIDI_SPtr< T, ADLMIDI_DefaultArrayDelete > { +public: + explicit AdlMIDI_SPtrArray(T *p = NULL) + : AdlMIDI_SPtr< T, ADLMIDI_DefaultArrayDelete >(p) {} }; #endif //ADLMIDI_PTR_HPP_THING -- cgit v1.2.3