27 #ifndef ODARRAY_H_INCLUDED
28 #define ODARRAY_H_INCLUDED
67 memcpy(pDestination, pSource, numElements *
sizeof(T));
88 memmove(pDestination, pSource, numElements *
sizeof(T));
120 pDestination[numElements] =
value;
139 copy(pDestination, pSource, numElements);
157 memset(pDestination, 0, numElements *
sizeof(T));
230 *pDestination = *pSource;
254 if (pDestination <= pSource || pDestination >= pSource + numObjects)
256 copy(pDestination, pSource, numObjects);
262 pDestination[numObjects] = pSource[numObjects];
292 ::new (pObject) T(
value);
412 memcpy(pDestination, pSource, numObjects *
sizeof(T));
433 memmove(pDestination, pSource, numObjects *
sizeof(T));
462 ::new (pObject) T(
value);
602 T*
data()
const {
return (T*)(
this+1); }
604 static Buffer* allocate(
size_type nLength2Allocate,
int nGrowBy)
606 size_type nBytes2Allocate =
sizeof(Buffer) + nLength2Allocate *
sizeof(T);
607 ODA_ASSERT(nBytes2Allocate > nLength2Allocate);
608 if(nBytes2Allocate > nLength2Allocate)
610 Buffer* pBuffer = (Buffer*)::
odrxAlloc(nBytes2Allocate);
613 pBuffer->m_nRefCounter = 1;
614 pBuffer->m_nGrowBy = nGrowBy;
615 pBuffer->m_nAllocated = nLength2Allocate;
616 pBuffer->m_nLength = 0;
622 static Buffer* _default()
624 return (Buffer*)&g_empty_array_buffer;
629 if((--m_nRefCounter)==0 &&
this != _default())
631 A::destroy(
data(), m_nLength);
635 void addref()
const { ++m_nRefCounter; }
639 bool _may_use_realloc;
642 inline reallocator(
bool may_use_realloc =
false ) : _may_use_realloc(may_use_realloc), m_pBuffer(
NULL)
644 if ( !_may_use_realloc )
646 m_pBuffer = Buffer::_default();
652 if(!pArray->referenced())
656 if ( !_may_use_realloc )
658 m_pBuffer->release();
659 m_pBuffer = pArray->buffer();
662 pArray->copy_buffer(nNewLen, _may_use_realloc);
667 pArray->copy_buffer(nNewLen);
672 if ( !_may_use_realloc ) m_pBuffer->release();
680 void copy_before_write(
size_type len,
bool may_use_realloc =
false )
685 copy_buffer( len, may_use_realloc );
687 void copy_if_referenced() {
if(referenced()) { copy_buffer(
physicalLength()); } }
688 void copy_buffer(
size_type len,
bool may_use_realloc =
false,
bool force_size =
false )
690 Buffer* pOldBuffer =
buffer();
691 int nGrowBy = pOldBuffer->m_nGrowBy;
698 len2 = ((len2 - 1) / nGrowBy) * nGrowBy;
702 len2 = pOldBuffer->m_nLength;
703 len2 = len2 + -nGrowBy * len2 / 100;
710 if ( may_use_realloc && A::useRealloc() && !
empty() )
712 Buffer* pNewBuffer =
reinterpret_cast<Buffer*
>(
::odrxRealloc(
713 pOldBuffer, len2 *
sizeof(T) +
sizeof(Buffer), pOldBuffer->m_nAllocated *
sizeof(T) +
sizeof(Buffer) ) );
716 pNewBuffer->m_nAllocated = len2;
717 pNewBuffer->m_nLength =
odmin(pNewBuffer->m_nLength, len);
718 m_pData = pNewBuffer->data();
722 Buffer* pNewBuffer = Buffer::allocate(len2, nGrowBy);
725 len =
odmin(pOldBuffer->m_nLength, len);
726 A::constructn(pNewBuffer->data(), pOldBuffer->data(), len);
727 pNewBuffer->m_nLength = len;
728 m_pData = pNewBuffer->data();
729 pOldBuffer->release();
740 static inline void rise_error(
OdResult e)
755 copy_if_referenced();
776 copy_if_referenced();
809 if(afterLast >
first)
813 r.reallocate(
this, len + num2copy);
814 A::constructn(m_pData + len,
first, num2copy);
815 buffer()->m_nLength = len + num2copy;
816 T* pDestination = m_pData +
index;
819 A::move(pDestination + num2copy, pDestination, len -
index);
826 rise_error(eInvalidInput);
844 A::constructn(m_pData + len, d,
value);
872 copy_before_write( len + d,
true );
873 A::constructn(m_pData + len, d);
895 return buffer()->m_nLength;
911 return buffer()->m_nAllocated;
943 erase(begin_non_const(), end_non_const());
958 if(
first != afterLast)
962 return begin_non_const()+i;
974 return begin_non_const()+i;
981 erase(begin_non_const(), end_non_const());
1008 r.reallocate(
this, len + numElements);
1009 A::constructn(m_pData + len, numElements,
value);
1010 buffer()->m_nLength = len + numElements;
1015 A::move(pData + numElements, pData, len -
index);
1017 while(numElements--)
1019 pData[numElements] =
value;
1021 return begin_non_const()+
index;
1030 const T&
value = T())
1034 return (begin_non_const() +
index);
1056 return buffer()->m_nLength;
1080 return buffer()->m_nAllocated;
1088 return buffer()->m_nGrowBy;
1112 copy_if_referenced();
1123 return m_pData[
index];
1132 copy_if_referenced();
1133 return m_pData[
index];
1142 assertValid(arrayIndex);
1143 copy_if_referenced();
1144 return *(
data() + arrayIndex);
1153 assertValid(arrayIndex);
1154 return *(
data() + arrayIndex);
1166 assertValid(arrayIndex);
1167 copy_if_referenced();
1168 m_pData[arrayIndex] =
value;
1179 assertValid(arrayIndex);
1180 return *(
data() + arrayIndex);
1228 return begin_non_const() + i;
1256 copy_if_referenced();
1301 source.buffer()->addref();
1303 m_pData =
source.m_pData;
1314 if(
at(i) != array[i])
1331 copy_if_referenced();
1379 if( arrayIndex == len )
1383 else if ( arrayIndex < len )
1386 r.reallocate(
this, len+1 );
1387 A::construct( m_pData + len );
1389 A::move(m_pData + arrayIndex + 1, m_pData + arrayIndex, len - arrayIndex);
1390 m_pData[arrayIndex] =
value;
1394 rise_error(eInvalidIndex);
1414 assertValid(arrayIndex);
1416 if(arrayIndex < --len)
1418 copy_if_referenced();
1420 A::move(pData + arrayIndex, pData + arrayIndex + 1, len - arrayIndex);
1441 if(!isValid(startIndex) || startIndex > endIndex)
1443 rise_error(eInvalidIndex);
1446 copy_if_referenced();
1449 size_type n2remove = endIndex - startIndex;
1450 A::move(pData + startIndex, pData + endIndex, len - endIndex);
1451 A::destroy(pData + len - n2remove, n2remove);
1452 buffer()->m_nLength -= n2remove;
1475 const T* pData =
data();
1478 if(pData[i] ==
value)
1516 copy_buffer(physLength, !referenced(),
true);
1528 copy_if_referenced();
1530 iterator iter1 = begin_non_const();
1533 while(iter1 < iter2)
1554 if(!isValid(firstIndex) || !isValid(secondIndex))
1556 rise_error(eInvalidIndex);
1558 if(firstIndex != secondIndex)
1560 const T tmp =
at(firstIndex);
1561 at(firstIndex) =
at(secondIndex);
1562 at(secondIndex) = tmp;
1600 return (
length() ? m_pData : 0);
1603 const T*
data()
const
1610 return (
reinterpret_cast<Buffer*
>(
const_cast<OdArray*
>(
this)->m_pData) - 1);
1612 bool referenced()
const
1614 return (
buffer()->m_nRefCounter>1);
1618 template <
class T,
class A>
1623 return !( a.operator == (b) );
1628 #endif // ODARRAY_H_INCLUDED