25#ifndef OdVector_H_INCLUDED
26#define OdVector_H_INCLUDED
36template <
class T,
class A = OdObjectsAllocator<T>,
class Mm = OdrxMemoryManager>
class OdVector;
64template <
class T,
class A,
class Mm>
class OdVector
74 using ConstForPtrT =
typename std::conditional<std::is_pointer<T>::value,
75 typename std::add_const<typename std::remove_pointer<T>::type>
::type*, T>
::type;
84 return ((minPhysicalLength + m_growLength - 1) / m_growLength) * m_growLength;
88 size_type newPhysicalLength = m_logicalLength + (-m_growLength)*m_logicalLength / 100;
90 if (newPhysicalLength < minPhysicalLength)
91 newPhysicalLength = minPhysicalLength;
93 return newPhysicalLength;
104 static void riseError(
OdResult res);
651#define VEC_SIZE_TYPE typename OdVector<T, A, Mm>::size_type
652#define VEC_ITERATOR typename OdVector<T, A, Mm>::iterator
653#define VEC_CONST_ITERATOR typename OdVector<T, A, Mm>::const_iterator
655template<
class T,
class A,
class Mm>
657: m_pData(NULL), m_physicalLength(physicalLength), m_logicalLength(0)
658, m_growLength(growLength)
660 if(m_growLength == 0)
665 if (m_physicalLength)
667 m_pData = allocate(m_physicalLength);
671template <
class T,
class A,
class Mm>
673: m_pData(NULL), m_physicalLength(0), m_logicalLength(0), m_growLength(-200)
677template <
class T,
class A,
class Mm>
679: m_pData(NULL), m_physicalLength(vec.m_physicalLength)
680, m_logicalLength(vec.m_logicalLength), m_growLength(vec.m_growLength)
682 static_assert(std::is_copy_constructible<T>::value,
"Can not copy vector with non-copyable argument");
683 if(m_physicalLength > 0)
685 m_pData = allocate(m_physicalLength);
687 A::copyConstructRange(m_pData, vec.m_pData, m_logicalLength);
691template <
class T,
class A,
class Mm>
693 : m_pData(vec.m_pData), m_physicalLength(vec.m_physicalLength)
694 , m_logicalLength(vec.m_logicalLength), m_growLength(vec.m_growLength)
696 vec.m_pData =
nullptr;
697 vec.m_physicalLength = 0;
698 vec.m_logicalLength = 0;
699 vec.m_growLength = -200;
702template <
class T,
class A,
class Mm>
708template <
class T,
class A,
class Mm>
711 static_assert(std::is_copy_constructible<T>::value,
"Can not copy vector with non-copyable argument");
716 if (vec.m_logicalLength > 0)
718 m_pData = allocate(vec.m_logicalLength);
719 m_physicalLength = vec.m_logicalLength;
720 A::copyConstructRange(m_pData, vec.m_pData, vec.m_logicalLength);
721 m_logicalLength = vec.m_logicalLength;
727template <
class T,
class A,
class Mm>
733 m_pData = vec.m_pData;
734 m_physicalLength = vec.m_physicalLength;
735 m_logicalLength = vec.m_logicalLength;
736 m_growLength = vec.m_growLength;
737 vec.m_pData =
nullptr;
738 vec.m_physicalLength = 0;
739 vec.m_logicalLength = 0;
740 vec.m_growLength = -200;
745template <
class T,
class A,
class Mm>
749 const size_type numByte = physicalLength*
sizeof(T);
753 T* pData = ((numByte >= physicalLength)
754 ?
reinterpret_cast<T*
>(Mm::Alloc(numByte))
763template <
class T,
class A,
class Mm>
768 A::destroyRange(m_pData, m_logicalLength);
772 m_physicalLength = 0;
776template <
class T,
class A,
class Mm>
779 T* pOldData = m_pData;
780 size_type newPhysicalLength = physicalLength;
782 if(!isForcePhysicalLength)
783 newPhysicalLength = calcPhysicalLength(physicalLength);
785 if(isUseRealloc && A::useRealloc() && m_logicalLength > 0 && m_pData != NULL)
787 m_pData =
reinterpret_cast<T*
>(Mm::Realloc(pOldData, newPhysicalLength*
sizeof(T), m_physicalLength*
sizeof(T)));
792 m_physicalLength = newPhysicalLength;
794 if(physicalLength < m_logicalLength)
795 m_logicalLength = physicalLength;
799 T* pNewData = allocate(newPhysicalLength);
800 const size_type newLogicalLength =
odmin(m_logicalLength, physicalLength);
802 A::moveConstructRange(pNewData, pOldData, newLogicalLength);
807 m_physicalLength = newPhysicalLength;
808 m_logicalLength = newLogicalLength;
812template <
class T,
class A,
class Mm>
816 return (
index < m_logicalLength);
819template <
class T,
class A,
class Mm>
829template <
class T,
class A,
class Mm>
836template <
class T,
class A,
class Mm>
842template <
class T,
class A,
class Mm>
848template <
class T,
class A,
class Mm>
854template <
class T,
class A,
class Mm>
860template <
class T,
class A,
class Mm>
863 return (!isEmpty() ? m_pData : NULL);
866template <
class T,
class A,
class Mm>
869 return (!isEmpty() ? m_pData : NULL);
872template <
class T,
class A,
class Mm>
875 return (!isEmpty() ? m_pData + m_logicalLength : NULL);
878template <
class T,
class A,
class Mm>
881 return (!isEmpty() ? m_pData + m_logicalLength : NULL);
884template <
class T,
class A,
class Mm>
887#ifdef ODA_DIAGNOSTICS
888 if (first >= begin_const() && first < end_const() && before < afterLast)
889 throw OdError(L
"Inserted iterator range will become invalid while inserting.");
891 const size_type oldLogicalLength = m_logicalLength;
894 if(index <= m_logicalLength && afterLast >= first)
896 if(afterLast > first)
899 const size_type newLogicalLength = oldLogicalLength + numElem;
901 if (newLogicalLength <= m_physicalLength)
903 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
904 m_logicalLength = newLogicalLength;
905 T* pData = m_pData +
index;
907 if (
index != oldLogicalLength)
908 A::moveAssignRange(pData + numElem, pData, oldLogicalLength -
index);
910 A::copyAssignRangeDisjoint(pData, first, numElem);
914 size_type newPhysicalLength = calcPhysicalLength(newLogicalLength);
915 T* pNewData = allocate(newPhysicalLength);
916 A::moveConstructRange(pNewData, m_pData,
index);
917 if (first >= begin_const() && afterLast <= end_const()) {
919 first = pNewData + newBufFirst;
921 A::copyConstructRange(pNewData +
index, first, numElem);
922 A::moveConstructRange(pNewData +
index + numElem, m_pData +
index, m_logicalLength -
index);
925 m_physicalLength = newPhysicalLength;
926 m_logicalLength = newLogicalLength;
931 riseError(eInvalidInput);
934template <
class T,
class A,
class Mm>
937#ifdef ODA_DIAGNOSTICS
938 if (first >= begin_const() && first < end_const() && before < afterLast)
939 throw OdError(L
"Inserted iterator range will become invalid while inserting.");
941 const size_type oldLogicalLength = m_logicalLength;
944 if (index <= m_logicalLength && afterLast >= first)
946 if (afterLast > first)
949 const size_type newLogicalLength = oldLogicalLength + numElem;
951 if (newLogicalLength <= m_physicalLength)
953 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
954 m_logicalLength = newLogicalLength;
955 T* pData = m_pData +
index;
957 if (
index != oldLogicalLength)
958 A::moveAssignRange(pData + numElem, pData, oldLogicalLength -
index);
960 A::moveAssignRange(pData, first, numElem);
964 size_type newPhysicalLength = calcPhysicalLength(newLogicalLength);
965 T* pNewData = allocate(newPhysicalLength);
966 A::moveConstructRange(pNewData, m_pData,
index);
967 if (first >= begin_const() && afterLast <= end_const()) {
969 first = pNewData + newBufFirst;
971 A::moveConstructRange(pNewData +
index, first, numElem);
972 A::moveConstructRange(pNewData +
index + numElem, m_pData +
index, m_logicalLength -
index);
975 m_physicalLength = newPhysicalLength;
976 m_logicalLength = newLogicalLength;
981 riseError(eInvalidInput);
984template <
class T,
class A,
class Mm>
990 const size_type oldLogicalLength = m_logicalLength;
991 const size_type newLogicalLength = oldLogicalLength + numElem;
994 if (
index == oldLogicalLength)
996 if (newLogicalLength <= m_physicalLength)
998 A::copyConstructFill(m_pData + oldLogicalLength, numElem,
value);
1002 const T valueCopy(
value);
1003 reallocate(newLogicalLength,
true);
1004 A::copyConstructFill(m_pData + oldLogicalLength, numElem - 1, valueCopy);
1005 A::copyConstruct(m_pData + oldLogicalLength + numElem - 1, std::move(valueCopy));
1007 m_logicalLength = newLogicalLength;
1009 else if (
index < oldLogicalLength)
1011 const T valueCopy(
value);
1012 if (newLogicalLength > m_physicalLength)
1013 reallocate(newLogicalLength,
true);
1015 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
1017 m_logicalLength = newLogicalLength;
1019 T* pData = m_pData +
index;
1021 A::moveAssignRange(pData + numElem, pData, oldLogicalLength -
index);
1023 while (numElem-- > 1)
1024 pData[numElem] = valueCopy;
1025 pData[0] = std::move(valueCopy);
1028 return (begin_non_const() +
index);
1031template <
class T,
class A,
class Mm>
1038 return (begin_non_const() +
index);
1041template <
class T,
class A,
class Mm>
1048 return (begin_non_const() +
index);
1051template <
class T,
class A,
class Mm>
1054 const size_type oldLogicalLength = m_logicalLength;
1055 const size_type newLogicalLength = oldLogicalLength + 1;
1057 if (
index == oldLogicalLength)
1061 else if (
index < oldLogicalLength)
1063 const T valueCopy(
value);
1064 if (newLogicalLength > m_physicalLength)
1065 reallocate(newLogicalLength,
true);
1067 A::defaultConstruct(m_pData + oldLogicalLength);
1071 T* pData = m_pData +
index;
1073 A::moveAssignRange(pData + 1, pData, oldLogicalLength -
index);
1075 *pData = std::move(valueCopy);
1078 riseError(eInvalidIndex);
1083template <
class T,
class A,
class Mm>
1086 const size_type oldLogicalLength = m_logicalLength;
1087 const size_type newLogicalLength = oldLogicalLength + 1;
1089 if (
index == oldLogicalLength)
1091 push_back(std::move(
value));
1093 else if (
index < oldLogicalLength)
1095 T valueMoved(std::move(
value));
1096 if (newLogicalLength > m_physicalLength)
1097 reallocate(newLogicalLength,
true);
1099 A::defaultConstruct(m_pData + oldLogicalLength);
1103 T* pData = m_pData +
index;
1105 A::moveAssignRange(pData + 1, pData, oldLogicalLength -
index);
1107 *pData = std::move(valueMoved);
1110 riseError(eInvalidIndex);
1115template <
class T,
class A,
class Mm>
1120 const size_type newLogicalLength = m_logicalLength - 1;
1122 if(
index < newLogicalLength)
1124 T* pData = m_pData +
index;
1125 A::moveAssignRange(pData, pData + 1, newLogicalLength -
index);
1128 resize(newLogicalLength);
1132template <
class T,
class A,
class Mm>
1135 if(!isValid(startIndex) || startIndex > endIndex)
1136 riseError(eInvalidIndex);
1138 const size_type oldLogicalLength = m_logicalLength;
1144 const size_type numElem = endIndex - startIndex;
1146 A::moveAssignRange(pData + startIndex, pData + endIndex, oldLogicalLength - endIndex);
1147 A::destroyRange(pData + oldLogicalLength - numElem, numElem);
1149 m_logicalLength -= numElem;
1153template <
class T,
class A,
class Mm>
1165template <
class T,
class A,
class Mm>
1168 const size_type oldLogicalLength = m_logicalLength;
1169 const int lengthDiff = logicalLength - oldLogicalLength;
1173 const T valueCopy(
value);
1174 if (logicalLength > m_physicalLength)
1175 reallocate(logicalLength,
true);
1177 A::copyConstructFill(m_pData + oldLogicalLength, lengthDiff, valueCopy);
1179 else if(lengthDiff < 0)
1180 A::destroyRange(m_pData + logicalLength, -lengthDiff);
1182 m_logicalLength = logicalLength;
1185template <
class T,
class A,
class Mm>
1188 const size_type oldLogicalLength = m_logicalLength;
1189 const int lengthDiff = logicalLength - oldLogicalLength;
1193 if(logicalLength > m_physicalLength)
1194 reallocate(logicalLength,
true);
1195 A::defaultConstructFill(m_pData + oldLogicalLength, lengthDiff);
1197 else if(lengthDiff < 0)
1198 A::destroyRange(m_pData + logicalLength, -lengthDiff);
1200 m_logicalLength = logicalLength;
1203template <
class T,
class A,
class Mm>
1206 return m_logicalLength;
1209template <
class T,
class A,
class Mm>
1212 return (m_logicalLength == 0);
1215template <
class T,
class A,
class Mm>
1218 return m_physicalLength;
1221template <
class T,
class A,
class Mm>
1224 if(m_physicalLength < reserveLength)
1225 setPhysicalLength(reserveLength);
1228template <
class T,
class A,
class Mm>
1231#ifdef ODA_DIAGNOSTICS
1232 if (first >= begin_const() && first < end_const())
1233 throw OdError(L
"Assignment of a subrange from self is not allowed.");
1236 insert(begin_non_const(), first, afterLast);
1239template <
class T,
class A,
class Mm>
1242#ifdef ODA_DIAGNOSTICS
1243 if (first >= begin_const() && first < end_const())
1244 throw OdError(L
"Assignment of a subrange from self is not allowed.");
1247 insertMove(begin_non_const(), first, afterLast);
1250template <
class T,
class A,
class Mm>
1255 if(first != afterLast)
1256 removeSubArray(
index, (
size_type)(afterLast - begin_const() - 1));
1258 return (begin_non_const() +
index);
1261template <
class T,
class A,
class Mm>
1268 return (begin_non_const() +
index);
1271template <
class T,
class A,
class Mm>
1275 A::destroyRange(m_pData, numElem);
1276 m_logicalLength = 0;
1279template <
class T,
class A,
class Mm>
1282 if (m_physicalLength > m_logicalLength)
1284 A::copyConstruct(m_pData + m_logicalLength,
value);
1288 const T valueCopy(
value);
1289 reallocate(m_logicalLength + 1,
true);
1290 A::copyConstruct(m_pData + m_logicalLength, std::move(valueCopy));
1295template <
class T,
class A,
class Mm>
1298 if (m_physicalLength > m_logicalLength)
1300 A::moveConstruct(m_pData + m_logicalLength, std::move(
value));
1304 T valueMoved(std::move(
value));
1305 reallocate(m_logicalLength + 1,
true);
1306 A::moveConstruct(m_pData + m_logicalLength, std::move(valueMoved));
1311template <
class T,
class A,
class Mm>
1319template <
class T,
class A,
class Mm>
1322 return m_logicalLength;
1325template <
class T,
class A,
class Mm>
1328 return (m_logicalLength == 0);
1331template <
class T,
class A,
class Mm>
1334 return m_logicalLength;
1337template <
class T,
class A,
class Mm>
1340 return m_physicalLength;
1343template <
class T,
class A,
class Mm>
1346 return m_growLength;
1349template <
class T,
class A,
class Mm>
1355template <
class T,
class A,
class Mm>
1361template <
class T,
class A,
class Mm>
1365 return (
length()) ? m_pData : NULL;
1368template <
class T,
class A,
class Mm>
1372 return m_pData[
index];
1375template <
class T,
class A,
class Mm>
1379 return m_pData[
index];
1382template <
class T,
class A,
class Mm>
1386 return m_pData[
index];
1389template <
class T,
class A,
class Mm>
1393 return m_pData[
index];
1396template <
class T,
class A,
class Mm>
1406template <
class T,
class A,
class Mm>
1410 return m_pData[
index];
1413template <
class T,
class A,
class Mm>
1419template <
class T,
class A,
class Mm>
1425template <
class T,
class A,
class Mm>
1428 return m_pData[m_logicalLength - 1];
1431template <
class T,
class A,
class Mm>
1434 return m_pData[m_logicalLength - 1];
1437template <
class T,
class A,
class Mm>
1441 return (m_logicalLength - 1);
1443template <
class T,
class A,
class Mm>
1446 push_back(std::move(
value));
1447 return (m_logicalLength - 1);
1450template <
class T,
class A,
class Mm>
1454 return (begin_non_const() +
index);
1457template <
class T,
class A,
class Mm>
1460 insert(end_non_const(), vec.
begin(), vec.
end());
1464template <
class T,
class A,
class Mm>
1467 insertMove(end_non_const(), vec.
begin(), vec.
end());
1471template <
class T,
class A,
class Mm>
1474 return appendMove(vec);
1477template <
class T,
class A,
class Mm>
1483template <
class T,
class A,
class Mm>
1486 return removeAt(m_logicalLength - 1);
1489template <
class T,
class A,
class Mm>
1492 if(m_logicalLength == vec.m_logicalLength)
1494 for(
size_type i = 0; i < m_logicalLength; ++i)
1496 if(m_pData[i] != vec.m_pData[i])
1504template <
class T,
class A,
class Mm>
1507 for(
size_type i = 0; i < m_logicalLength; ++i)
1513template <
class T,
class A,
class Mm>
1518 assertValid(startIndex);
1520 for(
size_type i = startIndex; i < m_logicalLength; ++i)
1522 if(m_pData[i] ==
value)
1532template <
class T,
class A,
class Mm>
1535 resize(logicalLength);
1539template <
class T,
class A,
class Mm>
1542 if(physicalLength == 0)
1547 m_physicalLength = 0;
1549 else if(physicalLength != m_physicalLength)
1550 reallocate(physicalLength,
true,
true);
1552 if(m_physicalLength < m_logicalLength)
1553 m_logicalLength = m_physicalLength;
1558template <
class T,
class A,
class Mm>
1562 m_growLength = growLength;
1569template <
class T,
class A,
class Mm>
1593template <
class T,
class A,
class Mm>
1596 if(!isValid(firstIndex) || !isValid(secondIndex))
1597 riseError(eInvalidIndex);
1599 if(firstIndex != secondIndex)
1601 T
value = std::move(m_pData[firstIndex]);
1602 m_pData[firstIndex] = std::move(m_pData[secondIndex]);
1603 m_pData[secondIndex] = std::move(
value);
1609template <
class T,
class A,
class Mm>
1613 m_pData = other.m_pData;
1614 other.m_pData = ptr;
1616 m_physicalLength = other.m_physicalLength;
1617 other.m_physicalLength = sz;
1618 sz = m_logicalLength;
1619 m_logicalLength = other.m_logicalLength;
1620 other.m_logicalLength = sz;
1621 int tmpi = m_growLength;
1622 m_growLength = other.m_growLength;
1623 other.m_growLength = tmpi;
#define VEC_CONST_ITERATOR
OdVector< bool, OdMemoryAllocator< bool > > OdBoolVector
OdVector< OdUInt8, OdMemoryAllocator< OdUInt8 > > OdUInt8Vector
OdVector< OdUInt64, OdMemoryAllocator< OdUInt64 > > OdUInt64Vector
OdVector< int, OdMemoryAllocator< int > > OdIntVector
OdVector< OdInt32, OdMemoryAllocator< OdInt32 > > OdInt32Vector
OdVector< OdUInt32, OdMemoryAllocator< OdUInt32 > > OdUInt32Vector
const_iterator begin() const
OdVector & setAll(const T &value)
const_iterator end() const
void reserve(size_type reserveLength)
iterator insert(iterator before, size_type numElem, const T &value)
iterator insert(iterator before, T &&value=T())
OdVector & setGrowLength(int growLength)
OdVector & removeSubArray(size_type startIndex, size_type endIndex)
const T & operator[](size_type index) const
typename A::size_type size_type
T & operator[](size_type index)
bool find(const ConstForPtrT &value, size_type &index, size_type startIndex=0) const
iterator erase(iterator where)
bool remove(const T &value, size_type startIndex=0)
iterator insert(iterator before, const T &value=T())
size_type physicalLength() const
iterator erase(iterator first, iterator afterLast)
OdVector & operator=(OdVector &&vec)
void resize(size_type logicalLength, const T &value)
void push_back(T &&value)
OdVector & append(const OdVector &vec)
const T & at(size_type index) const
void push_back(const T &value)
OdVector & insertAt(size_type index, const T &value)
const T & getAt(size_type index) const
void assign(const_iterator first, const_iterator afterLast)
const T * asArrayPtr() const
size_type append(const T &value)
size_type logicalLength() const
size_type capacity() const
void insertMove(iterator before, iterator first, iterator afterLast)
typename std::conditional< std::is_pointer< T >::value, typename std::add_const< typename std::remove_pointer< T >::type >::type *, T >::type ConstForPtrT
OdVector & setLogicalLength(size_type logicalLength)
OdVector & removeAt(size_type index)
OdVector & setPhysicalLength(size_type physicalLength)
size_type append(T &&value)
void resize(size_type logicalLength)
OdVector & swap(size_type firstIndex, size_type secondIndex)
bool operator==(const OdVector &vec) const
OdVector & operator=(const OdVector &vec)
OdVector(size_type physicalLength, int growLength=8)
void swap(OdVector &other)
void insert(iterator before, const_iterator first, const_iterator afterLast)
bool contains(const ConstForPtrT &value, size_type startIndex=0) const
OdVector(const OdVector &vec)
void assignMove(iterator first, iterator afterLast)
OdVector & appendMove(OdVector &vec)
const T & const_reference
OdVector & append(OdVector &&vec)
OdVector & insertAt(size_type index, T &&value)
OdVector & setAt(size_type index, const T &value)
GLuint GLsizei GLsizei GLint GLenum * type
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value