/* **============================================================================== ** ** Open Management Infrastructure (OMI) ** ** Copyright (c) Microsoft Corporation ** ** Licensed under the Apache License, Version 2.0 (the "License"); you may not ** use this file except in compliance with the License. You may obtain a copy ** of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABLITY OR NON-INFRINGEMENT. ** ** See the Apache 2 License for the specific language governing permissions ** and limitations under the License. ** **============================================================================== */ #ifndef _micxx_array_h #define _micxx_array_h #include #include "atomic.h" #include "memory.h" #include "arraytraits.h" MI_BEGIN_NAMESPACE template class Array { public: Array(); Array(const Array& x); Array(const TYPE* data, MI_Uint32 size); ~Array(); Array& operator=(const Array& x); MI_Uint32 GetSize() const; const TYPE* GetData() const; TYPE* GetWritableData(); const TYPE& operator[](MI_Uint32 index) const; TYPE& operator[](MI_Uint32 index); void Clear(); void Resize(MI_Uint32 size, const TYPE& item = TYPE()); /* ATTN: Can we rename of "Remove" */ void Delete(MI_Uint32 index); /* ATTN: Can we rename of "PushBack" */ void PushBack(const TYPE& item); private: void cow(); struct Header { AtomicType m_refCounter; MI_Uint32 m_capacity; }; static Header* GetHeader(TYPE* buf) { return reinterpret_cast( reinterpret_cast(buf) - sizeof(Header)); } static const ArrayTraits* traits() { return GetArrayTraits(); } // for compatability with "C", it must have only one pointer and a size // field - NO CHANGES ALLOWED! TYPE* m_data; MI_Uint32 m_size; }; MI_EXTERN_C MICXX_LINKAGE void __ArrayCopyCtor(void* v_this, const ArrayTraits* v_traits, const void* v_obj, MI_Uint32 size); MI_EXTERN_C MICXX_LINKAGE void __ArrayAssign(void* v_this, const ArrayTraits* v_traits, const void* v_other); MI_EXTERN_C MICXX_LINKAGE void __ArrayCOW(void* v_this, const ArrayTraits* v_traits); MI_EXTERN_C MICXX_LINKAGE void __ArrayResize(void* v_this, const ArrayTraits* v_traits, const void* v_obj, MI_Uint32 new_size); MI_EXTERN_C MICXX_LINKAGE void __ArrayDelete(void* v_this, const ArrayTraits* v_traits, MI_Uint32 index); template inline Array::Array() : m_data(0), m_size(0) { } template inline MI_Uint32 Array::GetSize() const { return m_size; } template inline const TYPE* Array::GetData() const { return m_data; } template inline TYPE* Array::GetWritableData() { cow(); return m_data; } template inline const TYPE& Array::operator[](MI_Uint32 index) const { return m_data[index]; } template inline TYPE& Array::operator[](MI_Uint32 index) { cow(); return m_data[index]; } template inline void Array::Clear() { __ArrayAssign(this,traits(),0); m_data = 0; m_size = 0; } template inline Array::Array(const TYPE* data, MI_Uint32 size) { if (!size) { m_data = 0; m_size = 0; } else { __ArrayCopyCtor(this, traits(), data, size); } } template inline Array::~Array() { __ArrayAssign(this,traits(),0); } template inline Array::Array(const Array& x): m_data(0), m_size(0) { *this = x; } template inline Array& Array::operator=(const Array& x) { if (m_data != x.m_data) { __ArrayAssign(this,traits(),&x); } return *this; } template inline void Array::cow() { if ( m_data && AtomicGet(GetHeader(m_data)->m_refCounter) != 1 ) __ArrayCOW(this,traits()); } template inline void Array::PushBack(const TYPE& item) { Resize(GetSize() + 1, item); } template inline void Array::Resize(MI_Uint32 size, const TYPE& item) { if (GetSize() == size) return; __ArrayResize(this, traits(), &item, size); } template inline void Array::Delete(MI_Uint32 index) { /* ATTN: what does this do? */ if (GetSize() == 1) { Clear(); return; } __ArrayDelete(this, traits(), index); } MI_END_NAMESPACE #endif /* _micxx_array_h */