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);
244 template<
class... Args>
258 template<
class... Args>
405 template<
class... Args>
683#define VEC_SIZE_TYPE typename OdVector<T, A, Mm>::size_type
684#define VEC_ITERATOR typename OdVector<T, A, Mm>::iterator
685#define VEC_CONST_ITERATOR typename OdVector<T, A, Mm>::const_iterator
687template<
class T,
class A,
class Mm>
689: m_pData(NULL), m_physicalLength(
physicalLength), m_logicalLength(0)
692 if(m_growLength == 0)
697 if (m_physicalLength)
699 m_pData = allocate(m_physicalLength);
703template <
class T,
class A,
class Mm>
705: m_pData(NULL), m_physicalLength(0), m_logicalLength(0), m_growLength(-200)
709template <
class T,
class A,
class Mm>
711: m_pData(NULL), m_physicalLength(vec.m_physicalLength)
712, m_logicalLength(vec.m_logicalLength), m_growLength(vec.m_growLength)
714 static_assert(std::is_copy_constructible<T>::value,
"Can not copy vector with non-copyable argument");
715 if(m_physicalLength > 0)
717 m_pData = allocate(m_physicalLength);
719 A::copyConstructRange(m_pData, vec.m_pData, m_logicalLength);
723template <
class T,
class A,
class Mm>
725 : m_pData(vec.m_pData), m_physicalLength(vec.m_physicalLength)
726 , m_logicalLength(vec.m_logicalLength), m_growLength(vec.m_growLength)
728 vec.m_pData =
nullptr;
729 vec.m_physicalLength = 0;
730 vec.m_logicalLength = 0;
731 vec.m_growLength = -200;
734template <
class T,
class A,
class Mm>
740template <
class T,
class A,
class Mm>
743 static_assert(std::is_copy_constructible<T>::value,
"Can not copy vector with non-copyable argument");
748 if (vec.m_logicalLength > 0)
750 m_pData = allocate(vec.m_logicalLength);
751 m_physicalLength = vec.m_logicalLength;
752 A::copyConstructRange(m_pData, vec.m_pData, vec.m_logicalLength);
753 m_logicalLength = vec.m_logicalLength;
759template <
class T,
class A,
class Mm>
765 m_pData = vec.m_pData;
766 m_physicalLength = vec.m_physicalLength;
767 m_logicalLength = vec.m_logicalLength;
768 m_growLength = vec.m_growLength;
769 vec.m_pData =
nullptr;
770 vec.m_physicalLength = 0;
771 vec.m_logicalLength = 0;
772 vec.m_growLength = -200;
777template <
class T,
class A,
class Mm>
778inline T* OdVector<T, A, Mm>::allocate(
size_type physicalLength)
782 ODA_ASSERT(nBytes2Allocate >= physicalLength);
783 size_t nBytes2AllocateSize_t = (size_t)nBytes2Allocate;
785 if (nBytes2Allocate >= physicalLength && (
OdUInt64)nBytes2AllocateSize_t == nBytes2Allocate)
786 pData =
static_cast<T*
>(Mm::Alloc(nBytes2AllocateSize_t));
794template <
class T,
class A,
class Mm>
795inline void OdVector<T, A, Mm>::release()
799 A::destroyRange(m_pData, m_logicalLength);
803 m_physicalLength = 0;
807template <
class T,
class A,
class Mm>
808inline void OdVector<T, A, Mm>::reallocate(
size_type physicalLength,
bool isUseRealloc,
bool isForcePhysicalLength)
810 T* pOldData = m_pData;
811 size_type newPhysicalLength = physicalLength;
813 if(!isForcePhysicalLength)
814 newPhysicalLength = calcPhysicalLength(physicalLength);
816 if(isUseRealloc && A::useRealloc() && m_logicalLength > 0 && m_pData != NULL)
818 m_pData =
reinterpret_cast<T*
>(Mm::Realloc(pOldData, newPhysicalLength*
sizeof(T), m_physicalLength*
sizeof(T)));
823 m_physicalLength = newPhysicalLength;
825 if(physicalLength < m_logicalLength)
826 m_logicalLength = physicalLength;
830 T* pNewData = allocate(newPhysicalLength);
831 const size_type newLogicalLength =
odmin(m_logicalLength, physicalLength);
833 A::moveConstructRange(pNewData, pOldData, newLogicalLength);
838 m_physicalLength = newPhysicalLength;
839 m_logicalLength = newLogicalLength;
843template <
class T,
class A,
class Mm>
847 return (
index < m_logicalLength);
850template <
class T,
class A,
class Mm>
860template <
class T,
class A,
class Mm>
861inline void OdVector<T, A, Mm>::riseError(
OdResult res)
867template <
class T,
class A,
class Mm>
873template <
class T,
class A,
class Mm>
874inline VEC_ITERATOR OdVector<T, A, Mm>::begin_non_const()
879template <
class T,
class A,
class Mm>
885template <
class T,
class A,
class Mm>
891template <
class T,
class A,
class Mm>
894 return (!
isEmpty() ? m_pData : NULL);
897template <
class T,
class A,
class Mm>
900 return (!
isEmpty() ? m_pData : NULL);
903template <
class T,
class A,
class Mm>
906 return (!
isEmpty() ? m_pData + m_logicalLength : NULL);
909template <
class T,
class A,
class Mm>
912 return (!
isEmpty() ? m_pData + m_logicalLength : NULL);
915template <
class T,
class A,
class Mm>
918#ifdef ODA_DIAGNOSTICS
919 if (
first >= begin_const() &&
first < end_const() && before < afterLast)
920 throw OdError(L
"Inserted iterator range will become invalid while inserting.");
922 const size_type oldLogicalLength = m_logicalLength;
927 if(afterLast >
first)
930 const size_type newLogicalLength = oldLogicalLength + numElem;
932 if (newLogicalLength <= m_physicalLength)
934 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
935 m_logicalLength = newLogicalLength;
936 T* pData = m_pData +
index;
938 if (
index != oldLogicalLength)
939 A::moveAssignRange(pData + numElem, pData, oldLogicalLength -
index);
941 A::copyAssignRangeDisjoint(pData,
first, numElem);
945 size_type newPhysicalLength = calcPhysicalLength(newLogicalLength);
946 T* pNewData = allocate(newPhysicalLength);
947 A::copyConstructRange(pNewData +
index,
first, numElem);
948 A::moveConstructRange(pNewData, m_pData,
index);
949 A::moveConstructRange(pNewData +
index + numElem, m_pData +
index, m_logicalLength -
index);
952 m_physicalLength = newPhysicalLength;
953 m_logicalLength = newLogicalLength;
958 riseError(eInvalidInput);
961template <
class T,
class A,
class Mm>
964#ifdef ODA_DIAGNOSTICS
965 if (
first >= begin_const() &&
first < end_const() && before < afterLast)
966 throw OdError(L
"Inserted iterator range will become invalid while inserting.");
968 const size_type oldLogicalLength = m_logicalLength;
973 if (afterLast >
first)
976 const size_type newLogicalLength = oldLogicalLength + numElem;
978 if (newLogicalLength <= m_physicalLength)
980 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
981 m_logicalLength = newLogicalLength;
982 T* pData = m_pData +
index;
984 if (
index != oldLogicalLength)
985 A::moveAssignRange(pData + numElem, pData, oldLogicalLength -
index);
987 A::moveAssignRange(pData,
first, numElem);
991 size_type newPhysicalLength = calcPhysicalLength(newLogicalLength);
992 T* pNewData = allocate(newPhysicalLength);
993 A::moveConstructRange(pNewData +
index,
first, numElem);
994 A::moveConstructRange(pNewData, m_pData,
index);
995 A::moveConstructRange(pNewData +
index + numElem, m_pData +
index, m_logicalLength -
index);
998 m_physicalLength = newPhysicalLength;
999 m_logicalLength = newLogicalLength;
1004 riseError(eInvalidInput);
1007template <
class T,
class A,
class Mm>
1013 const size_type oldLogicalLength = m_logicalLength;
1014 const size_type newLogicalLength = oldLogicalLength + numElem;
1017 if (
index == oldLogicalLength)
1019 if (newLogicalLength <= m_physicalLength)
1021 A::copyConstructFill(m_pData + oldLogicalLength, numElem,
value);
1025 const T valueCopy(
value);
1026 reallocate(newLogicalLength,
true);
1027 A::copyConstructFill(m_pData + oldLogicalLength, numElem - 1, valueCopy);
1028 A::copyConstruct(m_pData + oldLogicalLength + numElem - 1, std::move(valueCopy));
1030 m_logicalLength = newLogicalLength;
1032 else if (
index < oldLogicalLength)
1034 const T valueCopy(
value);
1035 if (newLogicalLength > m_physicalLength)
1036 reallocate(newLogicalLength,
true);
1038 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
1040 m_logicalLength = newLogicalLength;
1042 T* pData = m_pData +
index;
1044 A::moveAssignRange(pData + numElem, pData, oldLogicalLength -
index);
1046 while (numElem-- > 1)
1047 pData[numElem] = valueCopy;
1048 pData[0] = std::move(valueCopy);
1051 return (begin_non_const() +
index);
1054template <
class T,
class A,
class Mm>
1061 return (begin_non_const() +
index);
1064template <
class T,
class A,
class Mm>
1071 return (begin_non_const() +
index);
1074template <
class T,
class A,
class Mm>
1077 const size_type oldLogicalLength = m_logicalLength;
1078 const size_type newLogicalLength = oldLogicalLength + 1;
1080 if (
index == oldLogicalLength)
1084 else if (
index < oldLogicalLength)
1086 const T valueCopy(
value);
1087 if (newLogicalLength > m_physicalLength)
1088 reallocate(newLogicalLength,
true);
1090 A::defaultConstruct(m_pData + oldLogicalLength);
1094 T* pData = m_pData +
index;
1096 A::moveAssignRange(pData + 1, pData, oldLogicalLength -
index);
1098 *pData = std::move(valueCopy);
1101 riseError(eInvalidIndex);
1106template <
class T,
class A,
class Mm>
1109 const size_type oldLogicalLength = m_logicalLength;
1110 const size_type newLogicalLength = oldLogicalLength + 1;
1112 if (
index == oldLogicalLength)
1116 else if (
index < oldLogicalLength)
1118 T valueMoved(std::move(
value));
1119 if (newLogicalLength > m_physicalLength)
1120 reallocate(newLogicalLength,
true);
1122 A::defaultConstruct(m_pData + oldLogicalLength);
1126 T* pData = m_pData +
index;
1128 A::moveAssignRange(pData + 1, pData, oldLogicalLength -
index);
1130 *pData = std::move(valueMoved);
1133 riseError(eInvalidIndex);
1138template <
class T,
class A,
class Mm>
1139template <
class... Args>
1146 return (begin_non_const() +
index);
1149template <
class T,
class A,
class Mm>
1150template <
class... Args>
1153 const size_type oldLogicalLength = m_logicalLength;
1154 const size_type newLogicalLength = oldLogicalLength + 1;
1156 if (
index == oldLogicalLength)
1160 else if (
index < oldLogicalLength)
1162 size_type newPhysicalLength = calcPhysicalLength(newLogicalLength);
1163 T* pNewData = allocate(newPhysicalLength);
1164 A::construct(pNewData +
index, std::forward<Args>(args)...);
1165 A::moveConstructRange(pNewData, m_pData,
index);
1166 A::moveConstructRange(pNewData +
index + 1, m_pData +
index, m_logicalLength -
index);
1169 m_physicalLength = newPhysicalLength;
1170 m_logicalLength = newLogicalLength;
1173 riseError(eInvalidIndex);
1178template <
class T,
class A,
class Mm>
1183 const size_type newLogicalLength = m_logicalLength - 1;
1185 if(
index < newLogicalLength)
1187 T* pData = m_pData +
index;
1188 A::moveAssignRange(pData, pData + 1, newLogicalLength -
index);
1191 resize(newLogicalLength);
1195template <
class T,
class A,
class Mm>
1198 if(!isValid(startIndex) || startIndex > endIndex)
1199 riseError(eInvalidIndex);
1201 const size_type oldLogicalLength = m_logicalLength;
1207 const size_type numElem = endIndex - startIndex;
1209 A::moveAssignRange(pData + startIndex, pData + endIndex, oldLogicalLength - endIndex);
1210 A::destroyRange(pData + oldLogicalLength - numElem, numElem);
1212 m_logicalLength -= numElem;
1216template <
class T,
class A,
class Mm>
1228template <
class T,
class A,
class Mm>
1231 const size_type oldLogicalLength = m_logicalLength;
1236 const T valueCopy(
value);
1240 A::copyConstructFill(m_pData + oldLogicalLength, lengthDiff, valueCopy);
1242 else if(lengthDiff < 0)
1248template <
class T,
class A,
class Mm>
1251 const size_type oldLogicalLength = m_logicalLength;
1257 A::defaultConstructFill(m_pData + oldLogicalLength,
logicalLength - oldLogicalLength);
1265template <
class T,
class A,
class Mm>
1268 return m_logicalLength;
1271template <
class T,
class A,
class Mm>
1274 return (m_logicalLength == 0);
1277template <
class T,
class A,
class Mm>
1280 return m_physicalLength;
1283template <
class T,
class A,
class Mm>
1286 if(m_physicalLength < reserveLength)
1290template <
class T,
class A,
class Mm>
1293#ifdef ODA_DIAGNOSTICS
1294 if (
first >= begin_const() &&
first < end_const())
1295 throw OdError(L
"Assignment of a subrange from self is not allowed.");
1301template <
class T,
class A,
class Mm>
1304#ifdef ODA_DIAGNOSTICS
1305 if (
first >= begin_const() &&
first < end_const())
1306 throw OdError(L
"Assignment of a subrange from self is not allowed.");
1312template <
class T,
class A,
class Mm>
1317 if(
first != afterLast)
1320 return (begin_non_const() +
index);
1323template <
class T,
class A,
class Mm>
1330 return (begin_non_const() +
index);
1333template <
class T,
class A,
class Mm>
1337 A::destroyRange(m_pData, numElem);
1338 m_logicalLength = 0;
1341template <
class T,
class A,
class Mm>
1344 if (m_physicalLength > m_logicalLength)
1346 A::copyConstruct(m_pData + m_logicalLength,
value);
1350 const T valueCopy(
value);
1351 reallocate(m_logicalLength + 1,
true);
1352 A::copyConstruct(m_pData + m_logicalLength, std::move(valueCopy));
1357template <
class T,
class A,
class Mm>
1360 if (m_physicalLength > m_logicalLength)
1362 A::moveConstruct(m_pData + m_logicalLength, std::move(
value));
1366 T valueMoved(std::move(
value));
1367 reallocate(m_logicalLength + 1,
true);
1368 A::moveConstruct(m_pData + m_logicalLength, std::move(valueMoved));
1373template <
class T,
class A,
class Mm>
1374template<
class... Args>
1377 if (m_physicalLength > m_logicalLength)
1379 A::construct(m_pData + m_logicalLength, std::forward<Args>(args)...);
1383 size_type newPhysicalLength = calcPhysicalLength(m_logicalLength + 1);
1384 T* pNewData = allocate(newPhysicalLength);
1385 A::construct(pNewData + m_logicalLength, std::forward<Args>(args)...);
1386 A::moveConstructRange(pNewData, m_pData, m_logicalLength);
1389 m_physicalLength = newPhysicalLength;
1394template <
class T,
class A,
class Mm>
1402template <
class T,
class A,
class Mm>
1405 return m_logicalLength;
1408template <
class T,
class A,
class Mm>
1411 return (m_logicalLength == 0);
1414template <
class T,
class A,
class Mm>
1417 return m_logicalLength;
1420template <
class T,
class A,
class Mm>
1423 return m_physicalLength;
1426template <
class T,
class A,
class Mm>
1429 return m_growLength;
1432template <
class T,
class A,
class Mm>
1438template <
class T,
class A,
class Mm>
1444template <
class T,
class A,
class Mm>
1448 return (
length()) ? m_pData : NULL;
1451template <
class T,
class A,
class Mm>
1455 return m_pData[
index];
1458template <
class T,
class A,
class Mm>
1462 return m_pData[
index];
1465template <
class T,
class A,
class Mm>
1469 return m_pData[
index];
1472template <
class T,
class A,
class Mm>
1476 return m_pData[
index];
1479template <
class T,
class A,
class Mm>
1489template <
class T,
class A,
class Mm>
1493 return m_pData[
index];
1496template <
class T,
class A,
class Mm>
1502template <
class T,
class A,
class Mm>
1508template <
class T,
class A,
class Mm>
1511 return m_pData[m_logicalLength - 1];
1514template <
class T,
class A,
class Mm>
1517 return m_pData[m_logicalLength - 1];
1520template <
class T,
class A,
class Mm>
1524 return (m_logicalLength - 1);
1526template <
class T,
class A,
class Mm>
1530 return (m_logicalLength - 1);
1533template <
class T,
class A,
class Mm>
1537 return (begin_non_const() +
index);
1540template <
class T,
class A,
class Mm>
1547template <
class T,
class A,
class Mm>
1554template <
class T,
class A,
class Mm>
1560template <
class T,
class A,
class Mm>
1566template <
class T,
class A,
class Mm>
1569 return removeAt(m_logicalLength - 1);
1572template <
class T,
class A,
class Mm>
1575 if(m_logicalLength == vec.m_logicalLength)
1577 for(
size_type i = 0; i < m_logicalLength; ++i)
1579 if(m_pData[i] != vec.m_pData[i])
1587template <
class T,
class A,
class Mm>
1590 for(
size_type i = 0; i < m_logicalLength; ++i)
1596template <
class T,
class A,
class Mm>
1601 assertValid(startIndex);
1603 for(
size_type i = startIndex; i < m_logicalLength; ++i)
1605 if(m_pData[i] ==
value)
1615template <
class T,
class A,
class Mm>
1622template <
class T,
class A,
class Mm>
1630 m_physicalLength = 0;
1635 if(m_physicalLength < m_logicalLength)
1636 m_logicalLength = m_physicalLength;
1641template <
class T,
class A,
class Mm>
1652template <
class T,
class A,
class Mm>
1676template <
class T,
class A,
class Mm>
1679 if(!isValid(firstIndex) || !isValid(secondIndex))
1680 riseError(eInvalidIndex);
1682 if(firstIndex != secondIndex)
1684 T
value = std::move(m_pData[firstIndex]);
1685 m_pData[firstIndex] = std::move(m_pData[secondIndex]);
1686 m_pData[secondIndex] = std::move(
value);
1692template <
class T,
class A,
class Mm>
1696 m_pData = other.m_pData;
1697 other.m_pData = ptr;
1699 m_physicalLength = other.m_physicalLength;
1700 other.m_physicalLength = sz;
1701 sz = m_logicalLength;
1702 m_logicalLength = other.m_logicalLength;
1703 other.m_logicalLength = sz;
1704 int tmpi = m_growLength;
1705 m_growLength = other.m_growLength;
1706 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)
iterator emplace(iterator before, Args &&... args)
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 OdMemoryAllocator< OdGiTriangleForIntersectTest >::size_type size_type
T & operator[](size_type index)
bool find(const ConstForPtrT &value, size_type &index, size_type startIndex=0) const
void emplace_back(Args &&... args)
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 & emplaceAt(size_type index, Args &&... args)
OdVector & insertAt(size_type index, const T &value)
const T & getAt(size_type index) const
const OdGiTriangleForIntersectTest * const_iterator
void assign(const_iterator first, const_iterator afterLast)
OdGiTriangleForIntersectTest & first()
const T * asArrayPtr() const
size_type append(const T &value)
size_type logicalLength() const
typename std::conditional< std::is_pointer< OdGiTriangleForIntersectTest >::value, typename std::add_const< typename std::remove_pointer< OdGiTriangleForIntersectTest >::type >::type *, OdGiTriangleForIntersectTest >::type ConstForPtrT
size_type capacity() const
void insertMove(iterator before, iterator first, iterator afterLast)
OdVector & setLogicalLength(size_type logicalLength)
OdVector & removeAt(size_type index)
OdVector & setPhysicalLength(size_type physicalLength)
OdGiTriangleForIntersectTest * iterator
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)
OdGiTriangleForIntersectTest & reference
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)
OdGiTriangleForIntersectTest value_type
const OdGiTriangleForIntersectTest & 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