aboutsummaryrefslogtreecommitdiff
path: root/include/EASTL/linked_array.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/EASTL/linked_array.h')
-rw-r--r--include/EASTL/linked_array.h336
1 files changed, 336 insertions, 0 deletions
diff --git a/include/EASTL/linked_array.h b/include/EASTL/linked_array.h
new file mode 100644
index 0000000..88d9914
--- /dev/null
+++ b/include/EASTL/linked_array.h
@@ -0,0 +1,336 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) Electronic Arts Inc. All rights reserved.
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// This class implements a linked_array template, which is an array version
+// of linked_ptr. See linked_ptr for detailed documentation.
+///////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef EASTL_LINKED_ARRAY_H
+#define EASTL_LINKED_ARRAY_H
+
+
+#include <EASTL/internal/config.h>
+#include <EASTL/internal/smart_ptr.h> // Defines smart_array_deleter
+#include <EASTL/linked_ptr.h> // Defines linked_ptr_base
+#include <stddef.h> // Definition of ptrdiff_t
+
+#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
+{
+
+ /// class linked_array
+ ///
+ /// This class implements a linked_array template, which is an array version
+ /// of linked_ptr. See linked_ptr for detailed documentation.
+ ///
+ template <typename T, typename Deleter = smart_array_deleter<T> >
+ class linked_array
+ {
+
+ protected:
+
+ /// this_type
+ /// This is an alias for linked_array<T>, this class.
+ typedef linked_array<T> this_type;
+
+ /// deleter_type
+ typedef Deleter deleter_type;
+
+ T* mpArray;
+ mutable const this_type* mpPrev;
+ mutable const this_type* mpNext;
+
+ void link(const linked_array& linkedArray)
+ { // This code can only be called when we are in a reset state.
+ // assert(!mpArray && (mpNext == mpPrev));
+ mpNext = linkedArray.mpNext;
+ mpNext->mpPrev = this;
+ mpPrev = &linkedArray;
+ linkedArray.mpNext = this;
+ }
+
+ public:
+ /// element_type
+ /// Synonym for type T, useful for external code to reference the
+ /// type in a generic way.
+ typedef T element_type;
+
+
+ /// linked_array
+ /// Takes ownership of the pointer. It is OK if the input pointer is null.
+ explicit linked_array(T* pArray = NULL)
+ : mpArray(pArray)
+ {
+ mpPrev = mpNext = this;
+ }
+
+
+ /// linked_array
+ /// Shares ownership of a pointer with another instance of linked_array.
+ linked_array(const linked_array& linkedArray)
+ : mpArray(linkedArray.mpArray)
+ {
+ if(mpArray)
+ link(linkedArray);
+ else
+ mpPrev = mpNext = this;
+ }
+
+
+ /// ~linked_array
+ /// Removes this object from the of objects using the shared pointer.
+ /// If this object is the last owner of the shared pointer, the shared
+ /// pointer is deleted.
+ ~linked_array()
+ {
+ reset();
+ }
+
+
+ /// operator=
+ /// Copies another linked_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 removes ownership of the old pointer and takes shared
+ /// ownership of the new pointer and increments its reference count.
+ linked_array& operator=(const linked_array& linkedArray)
+ {
+ if(linkedArray.mpArray != mpArray)
+ {
+ reset(linkedArray.mpArray);
+ if(linkedArray.mpArray)
+ link(linkedArray);
+ }
+ return *this;
+ }
+
+
+ /// operator=
+ /// Assigns a new pointer. If the new pointer is equivalent
+ /// to the current pointer, nothing is done. Otherwise the
+ /// current pointer is unlinked and possibly destroyed.
+ /// The new pointer can be NULL.
+ linked_array& operator=(T* pArray)
+ {
+ reset(pArray);
+ 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)
+ {
+ if(unique())
+ {
+ deleter_type del;
+ del(mpArray);
+ }
+ else
+ {
+ mpPrev->mpNext = mpNext;
+ mpNext->mpPrev = mpPrev;
+ mpPrev = mpNext = this;
+ }
+ mpArray = pArray;
+ }
+ }
+
+
+ /// swap
+ /// Exchanges the owned pointer beween two linkedArray objects.
+ ///
+ /// This function is disabled as it is currently deemed unsafe.
+ /// The problem is that the only way to implement this function
+ /// is to transfer pointers between the objects; you cannot
+ /// transfer the linked list membership between the objects.
+ /// Thus unless both linked_array objects were 'unique()', the
+ /// shared pointers would be duplicated amongst containers,
+ /// resulting in a crash.
+ //void swap(linked_array& linkedArray)
+ //{
+ // if(linkedArray.mpArray != mpArray)
+ // { // This is only safe if both linked_arrays are unique().
+ // linkedArray::element_type* const pArrayTemp = linkedArray.mpArray;
+ // linkedArray.reset(mpArray);
+ // reset(pArrayTemp);
+ // }
+ //}
+
+
+ /// operator[]
+ /// Returns a reference to the specified item in the owned pointer array.
+ T& operator[](ptrdiff_t i) const
+ {
+ // assert(mpArray && (i >= 0));
+ return mpArray[i];
+ }
+
+
+ /// operator*
+ /// Returns the owner pointer dereferenced.
+ T& operator*() const
+ {
+ return *mpArray;
+ }
+
+
+ /// operator->
+ /// Allows access to the owned pointer via operator->()
+ T* operator->() const
+ {
+ 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.
+ T* get() const
+ {
+ return mpArray;
+ }
+
+
+ /// use_count
+ /// Returns the use count of the shared pointer.
+ /// The return value is one if the owned pointer is null.
+ /// This function is provided for compatibility with the
+ /// proposed C++ standard and for debugging purposes. It is not
+ /// intended for runtime use given that its execution time is
+ /// not constant.
+ int use_count() const
+ {
+ int useCount(1);
+
+ for(const linked_ptr_base* pCurrent = this; pCurrent->mpNext != this; pCurrent = pCurrent->mpNext)
+ ++useCount;
+
+ return useCount;
+ }
+
+
+ /// unique
+ /// Returns true if the use count of the owned pointer is one.
+ /// The return value is true if the owned pointer is null.
+ bool unique() const
+ {
+ return (mpNext == this);
+ }
+
+
+ /// Implicit operator bool
+ /// Allows for using a linked_array as a boolean.
+ /// 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(linkedArray == 1) would yield true (bad).
+ typedef T* (this_type::*bool_)() const;
+ operator bool_() const
+ {
+ 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.
+ bool operator!()
+ {
+ return (mpArray == NULL);
+ }
+
+
+ /// force_delete
+ /// Forces deletion of the shared pointer. Fixes all references to the
+ /// pointer by any other owners to be NULL.
+ void force_delete()
+ {
+ T* const pArray = mpArray;
+
+ this_type* p = this;
+ do
+ {
+ this_type* const pNext = const_cast<this_type*>(p->mpNext);
+ p->mpArray = NULL;
+ p->mpNext = p->mpPrev = p;
+ p = pNext;
+ }
+ while(p != this);
+
+ deleter_type del;
+ del(pArray);
+ }
+
+ }; // class linked_array
+
+
+
+ /// get_pointer
+ /// Returns linked_array::get() via the input linked_array. Provided for compatibility
+ /// with certain well-known libraries that use this functionality.
+ template <typename T>
+ inline T* get_pointer(const linked_array<T>& linkedArray)
+ {
+ return linkedArray.get();
+ }
+
+
+ /// operator==
+ /// Compares two linked_array objects for equality. Equality is defined as
+ /// being true when the pointer shared between two linked_array objects is equal.
+ template <typename T, typename TD, typename U, typename UD>
+ inline bool operator==(const linked_array<T, TD>& linkedArray1, const linked_array<U, UD>& linkedArray2)
+ {
+ return (linkedArray1.get() == linkedArray2.get());
+ }
+
+
+ /// operator!=
+ /// Compares two linked_array objects for inequality. Equality is defined as
+ /// being true when the pointer shared between two linked_array objects is equal.
+ template <typename T, typename TD, typename U, typename UD>
+ inline bool operator!=(const linked_array<T, TD>& linkedArray1, const linked_array<U, UD>& linkedArray2)
+ {
+ return (linkedArray1.get() != linkedArray2.get());
+ }
+
+
+ /// operator<
+ /// Returns which linked_array is 'less' than the other. Useful when storing
+ /// sorted containers of linked_array objects.
+ template <typename T, typename TD, typename U, typename UD>
+ inline bool operator<(const linked_array<T, TD>& linkedArray1, const linked_array<U, UD>& linkedArray2)
+ {
+ return (linkedArray1.get() < linkedArray2.get());
+ }
+
+
+} // namespace eastl
+
+
+#endif // Header include guard
+
+
+
+
+
+
+
+
+