diff options
Diffstat (limited to 'include/EASTL/shared_array.h')
-rw-r--r-- | include/EASTL/shared_array.h | 434 |
1 files changed, 0 insertions, 434 deletions
diff --git a/include/EASTL/shared_array.h b/include/EASTL/shared_array.h deleted file mode 100644 index b7d7840..0000000 --- a/include/EASTL/shared_array.h +++ /dev/null @@ -1,434 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Note (March 2014): shared_array is not a full implementation of an array version -// of C++11 shared_ptr, and there currently are no plans to make it so. A future -// version of shared_ptr would likely take on the ability to store arrays, -// same as unique_ptr has array support. This class isn't deprecated, but it -// is frozen until some future decision is made on what to do about arrays. -// -/////////////////////////////////////////////////////////////////////////////// -// This class implements a shared_array template. This is a class which is -// similar to the C++ shared_ptr template, except that it works with arrays -// instead of individual objects. -// -// Important notice: -// As of this writing (9/2003), the implementation provided here has -// limitations that you should be aware of. These limitations will be shortly -// rectified. Most significantly, this implementation has the following -// weaknesses: -// - It cannot safely deal with exceptions that occur during the -// construction of shared_ptr objects. -// - It cannot safely deal with recursive shared_ptr objects. -// If a shared_ptr<A> holds a pointer to an instance of A and -// class A owns an instance of shared_ptr<A> that refers to, -// the original instance, the memory will leak. -// - A template of type shared_ptr<void> will not call the destructor -// for an object that it stores. You thus must declare a shared_ptr -// template specifically for the class type. -// - It doesn't safely handle multiple instances of shared_ptr -// which own the same pointer accessed from multiple threads. -// This weakness is by design, for performance reasons. You should -// use shared_ptr_mt for multi-thread safe access. -// -// The rectification of the above issues are discussed in the C++ standardization -// documents for the next C++ standard (as of 2003): -// http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1450.html#Implementation-difficulty -// -// This current implementation will be eventually (hopefully by 1/2004) rectified -// to be in line with the second generation C++ standard proposal. -// -// The intended design of this class is based somewhat on the design of the Boost -// shared_array template. This design is also being considered for the next C++ -// standard (as of 2003). The C++ standard update proposal is currently available at: -// http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1450.html -// Boost smart pointers, including shared_array are documented at: -// http://www.boost.org/libs/smart_ptr/ -// -// As of this writing (10/2003), this class has received approval from EA legal -// for use. The potential issue is the similarity of the class name and class -// interface to existing open source code. -// -/////////////////////////////////////////////////////////////////////////////// - - -#ifndef EASTL_SHARED_ARRAY_H -#define EASTL_SHARED_ARRAY_H - - -#include <EASTL/internal/config.h> -#include <EASTL/internal/smart_ptr.h> // Defines smart_array_deleter - - -EA_DISABLE_ALL_VC_WARNINGS(); - - #include <new> - #include <stddef.h> - -EA_RESTORE_ALL_VC_WARNINGS(); - -#if defined(EA_PRAGMA_ONCE_SUPPORTED) - #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. -#endif - - - -namespace eastl -{ - - /// EASTL_SHARED_ARRAY_DEFAULT_NAME - /// - /// Defines a default container name in the absence of a user-provided name. - /// - #ifndef EASTL_SHARED_ARRAY_DEFAULT_NAME - #define EASTL_SHARED_ARRAY_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " shared_array" // Unless the user overrides something, this is "EASTL shared_array". - #endif - - - /// EASTL_SHARED_ARRAY_DEFAULT_ALLOCATOR - /// - #ifndef EASTL_SHARED_ARRAY_DEFAULT_ALLOCATOR - #define EASTL_SHARED_ARRAY_DEFAULT_ALLOCATOR allocator_type(EASTL_SHARED_ARRAY_DEFAULT_NAME) - #endif - - - - /// class shared_array - /// A shared_array is the same as shared_ptr but for arrays. - template <typename T, typename Allocator = EASTLAllocatorType, typename Deleter = smart_array_deleter<T> > - class shared_array - { - protected: - /// this_type - /// This is an alias for shared_array<T>, this class. - typedef shared_array<T> this_type; - - /// allocator_type - typedef Allocator allocator_type; - - /// deleter_type - typedef Deleter deleter_type; - - /// ref_count - /// An internal reference count type. Must be convertable to int - /// so that the public use_count function can work. - typedef int ref_count; - - T* mpArray; /// The owned pointer. Points to an array of T. - ref_count* mpRefCount; /// Reference count for owned pointer. - allocator_type mAllocator; /// The allocator used to manage new/delete of mpRefCount. - - public: - typedef T element_type; - - /// shared_array - /// Takes ownership of the pointer and sets the reference count - /// to the pointer to 1. It is OK if the input pointer is null. - /// The shared reference count is allocated on the heap via operator new. - /// If an exception occurs during the allocation of the shared - /// reference count, the owned pointer is deleted and the exception - /// is rethrown. A null pointer is given a reference count of 1. - explicit shared_array(T* pArray = NULL, const allocator_type& allocator = EASTL_SHARED_ARRAY_DEFAULT_ALLOCATOR) - : mpArray(pArray), - mpRefCount(NULL), - mAllocator(allocator) - { - // Allocate memory for the reference count. - void* const pMemory = EASTLAlloc(mAllocator, sizeof(ref_count)); - if(pMemory) - mpRefCount = ::new(pMemory) ref_count(1); - } - - - /// shared_array - /// Shares ownership of a pointer with another instance of shared_array. - /// This function increments the shared reference count on the pointer. - /// If we want a shared_array constructor that is templated on shared_array<U>, - /// then we need to make it in addition to this function, as otherwise - /// the compiler will generate this function and things will go wrong. - shared_array(const shared_array& sharedArray) - : mpArray(sharedArray.mpArray), - mpRefCount(sharedArray.mpRefCount), - mAllocator(sharedArray.mAllocator) - { - ++*mpRefCount; - } - - - /// ~shared_array - /// Decrements the reference count for the owned pointer. If the - /// reference count goes to zero, the owned pointer is deleted and - /// the shared reference count is deleted. - ~shared_array() - { - const ref_count newRefCount(--*mpRefCount); - // assert(newRefCount >= 0); - if(newRefCount == 0) - { - EASTLFree(mAllocator, mpRefCount, sizeof(ref_count)); - Deleter del; - del(mpArray); - } - } - - - /// operator= - /// Copies another shared_array to this object. Note that this object - /// may already own a shared pointer with another different pointer - /// (but still of the same type) before this call. In that case, - /// this function releases the old pointer, decrementing its reference - /// count and deleting it if zero, takes shared ownership of the new - /// pointer and increments its reference count. - /// If we want a shared_array operator= that is templated on shared_array<U>, - /// then we need to make it in addition to this function, as otherwise - /// the compiler will generate this function and things will go wrong. - shared_array& operator=(const shared_array& sharedArray) - { - if(mpArray != sharedArray.mpArray) - { - // The easiest thing to do is to create a temporary and - // copy ourselves ourselves into it. This is a standard - // method for switching pointer ownership in systems like this. - shared_array(sharedArray).swap(*this); - } - return *this; - } - - - /// operator= - /// Assigns a new pointer, while decrementing the reference count on - /// the current pointer. The new pointer can be NULL and the current - /// pointer can NULL. If the new pointer is equivalent to the current - /// pointer, then nothing is done. - shared_array& operator=(T* pValue) - { - reset(pValue); - return *this; - } - - - /// reset - /// Releases the owned pointer and takes ownership of the - /// passed in pointer. If the passed in pointer is the same - /// as the owned pointer, nothing is done. The passed in pointer - /// can be null, in which case the use count is set to 1. - void reset(T* pArray = NULL) - { - if(pArray != mpArray) - { - // The easiest thing to do is to create a temporary and - // copy ourselves ourselves into it. This is a standard - // method for switching pointer ownership in systems like this. - shared_array(pArray, mAllocator).swap(*this); - } - } - - - /// swap - /// Exchanges the owned pointer beween two shared_array objects. - void swap(this_type& sharedArray) - { - // We leave mAllocator as-is. - - // eastl::swap(mpArray, sharedArray.mpArray); - T* const pArray = sharedArray.mpArray; - sharedArray.mpArray = mpArray; - mpArray = pArray; - - // eastl::swap(mpRefCount, sharedArray.mpRefCount); - ref_count* const pRefCount = sharedArray.mpRefCount; - sharedArray.mpRefCount = mpRefCount; - mpRefCount = pRefCount; - } - - - /// operator[] - /// Returns a reference to the specified item in the owned pointer - /// array. - /// Example usage: - /// shared_array<int> ptr = new int[6]; - /// int x = ptr[2]; - T& operator[](ptrdiff_t i) const - { - // assert(mpArray && (i >= 0)); - return mpArray[i]; - } - - /// operator* - /// Returns the owner pointer dereferenced. - /// Example usage: - /// shared_array<int> ptr = new int(3); - /// int x = *ptr; - T& operator*() const - { - // assert(mpArray); - return *mpArray; - } - - /// operator-> - /// Allows access to the owned pointer via operator->() - /// Example usage: - /// struct X{ void DoSomething(); }; - /// shared_array<int> ptr = new X; - /// ptr->DoSomething(); - T* operator->() const EA_NOEXCEPT - { - // assert(mpArray); - return mpArray; - } - - /// get - /// Returns the owned pointer. Note that this class does - /// not provide an operator T() function. This is because such - /// a thing (automatic conversion) is deemed unsafe. - /// Example usage: - /// struct X{ void DoSomething(); }; - /// shared_array<int> ptr = new X; - /// X* pX = ptr.get(); - /// pX->DoSomething(); - T* get() const EA_NOEXCEPT - { - return mpArray; - } - - /// use_count - /// Returns the reference count on the owned pointer. - /// The return value is one if the owned pointer is null. - int use_count() const - { - // assert(mpRefCount); - return (int)*mpRefCount; - } - - /// unique - /// Returns true if the reference count on the owned pointer is one. - /// The return value is true if the owned pointer is null. - bool unique() const - { - // assert(mpRefCount); - return (*mpRefCount == 1); - } - - /// Implicit operator bool - /// Allows for using a scoped_ptr as a boolean. - /// Example usage: - /// shared_array<int> ptr = new int(3); - /// if(ptr) - /// ++*ptr; - /// - /// Note that below we do not use operator bool(). The reason for this - /// is that booleans automatically convert up to short, int, float, etc. - /// The result is that this: if(sharedArray == 1) would yield true (bad). - typedef T* (this_type::*bool_)() const; - operator bool_() const EA_NOEXCEPT - { - if(mpArray) - return &this_type::get; - return NULL; - } - - /// operator! - /// This returns the opposite of operator bool; it returns true if - /// the owned pointer is null. Some compilers require this and some don't. - /// shared_array<int> ptr = new int(3); - /// if(!ptr) - /// assert(false); - bool operator!() const EA_NOEXCEPT - { - return (mpArray == NULL); - } - - /// get_allocator - /// Returns the memory allocator associated with this class. - const allocator_type& get_allocator() const EA_NOEXCEPT - { - return mAllocator; - } - allocator_type& get_allocator() EA_NOEXCEPT - { - return mAllocator; - } - - /// set_allocator - /// Sets the memory allocator associated with this class. - void set_allocator(const allocator_type& allocator) - { - mAllocator = allocator; - } - - }; // class shared_array - - - - /// get_pointer - /// returns shared_array::get() via the input shared_array. - template <typename T, typename A, typename D> - inline T* get_pointer(const shared_array<T, A, D>& sharedArray) - { - return sharedArray.get(); - } - - /// swap - /// Exchanges the owned pointer beween two shared_array objects. - /// This non-member version is useful for compatibility of shared_array - /// objects with the C++ Standard Library and other libraries. - template <typename T, typename A, typename D> - inline void swap(shared_array<T, A, D>& sharedArray1, shared_array<T, A, D>& sharedArray2) - { - sharedArray1.swap(sharedArray2); - } - - - /// operator!= - /// Compares two shared_array objects for equality. Equality is defined as - /// being true when the pointer shared between two shared_array objects is equal. - /// It is debatable what the appropriate definition of equality is between two - /// shared_array objects, but we follow the current 2nd generation C++ standard proposal. - template <typename T, typename TA, typename TD, typename U, typename UA, typename UD> - inline bool operator==(const shared_array<T, TA, TD>& sharedArray1, const shared_array<U, UA, UD>& sharedArray2) - { - // assert((sharedArray1.get() != sharedArray2.get()) || (sharedArray1.use_count() == sharedArray2.use_count())); - return (sharedArray1.get() == sharedArray2.get()); - } - - - /// operator!= - /// Compares two shared_array objects for inequality. Equality is defined as - /// being true when the pointer shared between two shared_array objects is equal. - /// It is debatable what the appropriate definition of equality is between two - /// shared_array objects, but we follow the current 2nd generation C++ standard proposal. - template <typename T, typename TA, typename TD, typename U, typename UA, typename UD> - inline bool operator!=(const shared_array<T, TA, TD>& sharedArray1, const shared_array<U, UA, UD>& sharedArray2) - { - // assert((sharedArray1.get() != sharedArray2.get()) || (sharedArray1.use_count() == sharedArray2.use_count())); - return (sharedArray1.get() != sharedArray2.get()); - } - - - /// operator< - /// Returns which shared_array is 'less' than the other. Useful when storing - /// sorted containers of scoped_ptr objects. - template <typename T, typename TA, typename TD, typename U, typename UA, typename UD> - inline bool operator<(const shared_array<T, TA, TD>& sharedArray1, const shared_array<U, UA, UD>& sharedArray2) - { - return (sharedArray1.get() < sharedArray2.get()); // Alternatively use: std::less<T*>(a.get(), b.get()); - } - - -} // namespace eastl - - -#endif // Header include guard - - - - - - - - - - - |