summaryrefslogtreecommitdiff
path: root/libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h')
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h508
1 files changed, 508 insertions, 0 deletions
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h b/libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h
new file mode 100644
index 0000000000..2da241506c
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h
@@ -0,0 +1,508 @@
+/*
+ File: CAAutoDisposer.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAPtr_h__)
+#define __CAPtr_h__
+
+#include <stdlib.h> // for malloc
+#include <new> // for bad_alloc
+#include <string.h> // for memset
+
+inline void* CA_malloc(size_t size)
+{
+ void* p = malloc(size);
+ if (!p && size) throw std::bad_alloc();
+ return p;
+}
+
+inline void* CA_realloc(void* old, size_t size)
+{
+#if TARGET_OS_WIN32
+ void* p = realloc(old, size);
+#else
+ void* p = reallocf(old, size); // reallocf ensures the old pointer is freed if memory is full (p is NULL).
+#endif
+ if (!p && size) throw std::bad_alloc();
+ return p;
+}
+
+#ifndef UINTPTR_MAX
+#if __LP64__
+#define UINTPTR_MAX 18446744073709551615ULL
+#else
+#define UINTPTR_MAX 4294967295U
+#endif
+#endif
+
+inline void* CA_calloc(size_t n, size_t size)
+{
+ // ensure that multiplication will not overflow
+ if (n && UINTPTR_MAX / n < size) throw std::bad_alloc();
+
+ size_t nsize = n*size;
+ void* p = malloc(nsize);
+ if (!p && nsize) throw std::bad_alloc();
+
+ memset(p, 0, nsize);
+ return p;
+}
+
+
+// helper class for automatic conversions
+template <typename T>
+struct CAPtrRef
+{
+ T* ptr_;
+
+ explicit CAPtrRef(T* ptr) : ptr_(ptr) {}
+};
+
+template <typename T>
+class CAAutoFree
+{
+private:
+ T* ptr_;
+
+public:
+
+ CAAutoFree() : ptr_(0) {}
+
+ explicit CAAutoFree(T* ptr) : ptr_(ptr) {}
+
+ template<typename U>
+ CAAutoFree(CAAutoFree<U>& that) : ptr_(that.release()) {} // take ownership
+
+ // C++ std says: a template constructor is never a copy constructor
+ CAAutoFree(CAAutoFree<T>& that) : ptr_(that.release()) {} // take ownership
+
+ CAAutoFree(size_t n, bool clear = false)
+ // this becomes an ambiguous call if n == 0
+ : ptr_(0)
+ {
+ size_t maxItems = ~size_t(0) / sizeof(T);
+ if (n > maxItems)
+ throw std::bad_alloc();
+
+ ptr_ = static_cast<T*>(clear ? CA_calloc(n, sizeof(T)) : CA_malloc(n * sizeof(T)));
+ }
+
+ ~CAAutoFree() { free(); }
+
+ void alloc(size_t numItems, bool clear = false)
+ {
+ size_t maxItems = ~size_t(0) / sizeof(T);
+ if (numItems > maxItems) throw std::bad_alloc();
+
+ free();
+ ptr_ = static_cast<T*>(clear ? CA_calloc(numItems, sizeof(T)) : CA_malloc(numItems * sizeof(T)));
+ }
+
+ void allocBytes(size_t numBytes, bool clear = false)
+ {
+ free();
+ ptr_ = static_cast<T*>(clear ? CA_calloc(1, numBytes) : CA_malloc(numBytes));
+ }
+
+ void reallocBytes(size_t numBytes)
+ {
+ ptr_ = static_cast<T*>(CA_realloc(ptr_, numBytes));
+ }
+
+ void reallocItems(size_t numItems)
+ {
+ size_t maxItems = ~size_t(0) / sizeof(T);
+ if (numItems > maxItems) throw std::bad_alloc();
+
+ ptr_ = static_cast<T*>(CA_realloc(ptr_, numItems * sizeof(T)));
+ }
+
+ template <typename U>
+ CAAutoFree& operator=(CAAutoFree<U>& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoFree& operator=(CAAutoFree& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoFree& operator=(T* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ template <typename U>
+ CAAutoFree& operator=(U* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+
+ T* operator()() const { return ptr_; }
+ T* get() const { return ptr_; }
+ operator T*() const { return ptr_; }
+
+ bool operator==(CAAutoFree const& that) const { return ptr_ == that.ptr_; }
+ bool operator!=(CAAutoFree const& that) const { return ptr_ != that.ptr_; }
+ bool operator==(T* ptr) const { return ptr_ == ptr; }
+ bool operator!=(T* ptr) const { return ptr_ != ptr; }
+
+ T* release()
+ {
+ // release ownership
+ T* result = ptr_;
+ ptr_ = 0;
+ return result;
+ }
+
+ void set(T* ptr)
+ {
+ if (ptr != ptr_)
+ {
+ ::free(ptr_);
+ ptr_ = ptr;
+ }
+ }
+
+ void free()
+ {
+ set(0);
+ }
+
+
+ // automatic conversions to allow assignment from results of functions.
+ // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+ CAAutoFree(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+ CAAutoFree& operator=(CAPtrRef<T> ref)
+ {
+ set(ref.ptr_);
+ return *this;
+ }
+
+ template<typename U>
+ operator CAPtrRef<U>()
+ { return CAPtrRef<U>(release()); }
+
+ template<typename U>
+ operator CAAutoFree<U>()
+ { return CAAutoFree<U>(release()); }
+
+};
+
+
+template <typename T>
+class CAAutoDelete
+{
+private:
+ T* ptr_;
+
+public:
+ CAAutoDelete() : ptr_(0) {}
+
+ explicit CAAutoDelete(T* ptr) : ptr_(ptr) {}
+
+ template<typename U>
+ CAAutoDelete(CAAutoDelete<U>& that) : ptr_(that.release()) {} // take ownership
+
+ // C++ std says: a template constructor is never a copy constructor
+ CAAutoDelete(CAAutoDelete<T>& that) : ptr_(that.release()) {} // take ownership
+
+ ~CAAutoDelete() { free(); }
+
+ template <typename U>
+ CAAutoDelete& operator=(CAAutoDelete<U>& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoDelete& operator=(CAAutoDelete& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoDelete& operator=(T* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ template <typename U>
+ CAAutoDelete& operator=(U* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+
+ T* operator()() const { return ptr_; }
+ T* get() const { return ptr_; }
+ operator T*() const { return ptr_; }
+
+ bool operator==(CAAutoDelete const& that) const { return ptr_ == that.ptr_; }
+ bool operator!=(CAAutoDelete const& that) const { return ptr_ != that.ptr_; }
+ bool operator==(T* ptr) const { return ptr_ == ptr; }
+ bool operator!=(T* ptr) const { return ptr_ != ptr; }
+
+ T* release()
+ {
+ // release ownership
+ T* result = ptr_;
+ ptr_ = 0;
+ return result;
+ }
+
+ void set(T* ptr)
+ {
+ if (ptr != ptr_)
+ {
+ delete ptr_;
+ ptr_ = ptr;
+ }
+ }
+
+ void free()
+ {
+ set(0);
+ }
+
+
+ // automatic conversions to allow assignment from results of functions.
+ // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+ CAAutoDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+ CAAutoDelete& operator=(CAPtrRef<T> ref)
+ {
+ set(ref.ptr_);
+ return *this;
+ }
+
+ template<typename U>
+ operator CAPtrRef<U>()
+ { return CAPtrRef<U>(release()); }
+
+ template<typename U>
+ operator CAAutoFree<U>()
+ { return CAAutoFree<U>(release()); }
+
+};
+
+
+template <typename T>
+class CAAutoArrayDelete
+{
+private:
+ T* ptr_;
+
+public:
+ CAAutoArrayDelete() : ptr_(0) {}
+
+ explicit CAAutoArrayDelete(T* ptr) : ptr_(ptr) {}
+
+ template<typename U>
+ CAAutoArrayDelete(CAAutoArrayDelete<U>& that) : ptr_(that.release()) {} // take ownership
+
+ // C++ std says: a template constructor is never a copy constructor
+ CAAutoArrayDelete(CAAutoArrayDelete<T>& that) : ptr_(that.release()) {} // take ownership
+
+ // this becomes an ambiguous call if n == 0
+ CAAutoArrayDelete(size_t n) : ptr_(new T[n]) {}
+
+ ~CAAutoArrayDelete() { free(); }
+
+ void alloc(size_t numItems)
+ {
+ free();
+ ptr_ = new T [numItems];
+ }
+
+ template <typename U>
+ CAAutoArrayDelete& operator=(CAAutoArrayDelete<U>& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoArrayDelete& operator=(CAAutoArrayDelete& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoArrayDelete& operator=(T* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ template <typename U>
+ CAAutoArrayDelete& operator=(U* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+
+ T* operator()() const { return ptr_; }
+ T* get() const { return ptr_; }
+ operator T*() const { return ptr_; }
+
+ bool operator==(CAAutoArrayDelete const& that) const { return ptr_ == that.ptr_; }
+ bool operator!=(CAAutoArrayDelete const& that) const { return ptr_ != that.ptr_; }
+ bool operator==(T* ptr) const { return ptr_ == ptr; }
+ bool operator!=(T* ptr) const { return ptr_ != ptr; }
+
+ T* release()
+ {
+ // release ownership
+ T* result = ptr_;
+ ptr_ = 0;
+ return result;
+ }
+
+ void set(T* ptr)
+ {
+ if (ptr != ptr_)
+ {
+ delete [] ptr_;
+ ptr_ = ptr;
+ }
+ }
+
+ void free()
+ {
+ set(0);
+ }
+
+
+ // automatic conversions to allow assignment from results of functions.
+ // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+ CAAutoArrayDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+ CAAutoArrayDelete& operator=(CAPtrRef<T> ref)
+ {
+ set(ref.ptr_);
+ return *this;
+ }
+
+ template<typename U>
+ operator CAPtrRef<U>()
+ { return CAPtrRef<U>(release()); }
+
+ template<typename U>
+ operator CAAutoArrayDelete<U>()
+ { return CAAutoFree<U>(release()); }
+
+};
+
+
+
+
+
+// convenience function
+template <typename T>
+void free(CAAutoFree<T>& p)
+{
+ p.free();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if 0
+// example program showing ownership transfer
+
+CAAutoFree<char> source()
+{
+ // source allocates and returns ownership to the caller.
+ const char* str = "this is a test";
+ size_t size = strlen(str) + 1;
+ CAAutoFree<char> captr(size, false);
+ strlcpy(captr(), str, size);
+ printf("source %08X %08X '%s'\n", &captr, captr(), captr());
+ return captr;
+}
+
+void user(CAAutoFree<char> const& captr)
+{
+ // passed by const reference. user can access the pointer but does not take ownership.
+ printf("user: %08X %08X '%s'\n", &captr, captr(), captr());
+}
+
+void sink(CAAutoFree<char> captr)
+{
+ // passed by value. sink takes ownership and frees the pointer on return.
+ printf("sink: %08X %08X '%s'\n", &captr, captr(), captr());
+}
+
+
+int main (int argc, char * const argv[])
+{
+
+ CAAutoFree<char> captr(source());
+ printf("main captr A %08X %08X\n", &captr, captr());
+ user(captr);
+ sink(captr);
+ printf("main captr B %08X %08X\n", &captr, captr());
+ return 0;
+}
+#endif
+
+#endif