CFx SDK Documentation 2026 SP0
Loading...
Searching...
No Matches
OdVector.h
Go to the documentation of this file.
1// FELIX_CHANGE_BEGIN file was take from ODA gitlab repository https://gitlab.opendesign.com/
3// Copyright (C) 2002-2024, Open Design Alliance (the "Alliance").
4// All rights reserved.
5//
6// This software and its documentation and related materials are owned by
7// the Alliance. The software may only be incorporated into application
8// programs owned by members of the Alliance, subject to a signed
9// Membership Agreement and Supplemental Software License Agreement with the
10// Alliance. The structure and organization of this software are the valuable
11// trade secrets of the Alliance and its suppliers. The software is also
12// protected by copyright law and international treaty provisions. Application
13// programs incorporating this software must include the following statement
14// with their copyright notices:
15//
16// This application incorporates Open Design Alliance software pursuant to a license
17// agreement with Open Design Alliance.
18// Open Design Alliance Copyright (C) 2002-2024 by Open Design Alliance.
19// All rights reserved.
20//
21// By use of this software, its documentation or related materials, you
22// acknowledge and accept the above terms.
24
25#ifndef OdVector_H_INCLUDED
26#define OdVector_H_INCLUDED
27
28#include <new>
29#include <utility>
30
31#include "TD_PackPush.h"
32
33#include "OdArrayMemAlloc.h"
34#include "OdAlloc.h"
35
36template <class T, class A = OdObjectsAllocator<T>, class Mm = OdrxMemoryManager> class OdVector;
37
64template <class T, class A, class Mm> class OdVector
65{
66public:
67 using size_type = typename A::size_type;
68 using iterator = T*;
69 using const_iterator = const T*;
70 // compatibility with OdArray
71 using value_type = T;
72 using const_reference = const T&;
73 using reference = T&;
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;
76
77private:
78 static T* allocate(size_type physicalLength);
79
80 size_type calcPhysicalLength(size_type minPhysicalLength)
81 {
82 if (m_growLength > 0)
83 {
84 return ((minPhysicalLength + m_growLength - 1) / m_growLength) * m_growLength;
85 }
86 else
87 {
88 size_type newPhysicalLength = m_logicalLength + (-m_growLength)*m_logicalLength / 100;
89
90 if (newPhysicalLength < minPhysicalLength)
91 newPhysicalLength = minPhysicalLength;
92
93 return newPhysicalLength;
94 }
95 }
96
97 void release();
98
99 void reallocate(size_type physicalLength, bool isUseRealloc = false, bool isForcePhysicalLength = false);
100
101 bool isValid(size_type index) const;
102 void assertValid(size_type index) const;
103
104 static void riseError(OdResult res);
105
106 const_iterator begin_const() const;
107 iterator begin_non_const();
108 const_iterator end_const() const;
109 iterator end_non_const();
110
111public:
119
124
130 OdVector(const OdVector& vec);
131
138
143
146
151
156
161
166
177
187 void insertMove(iterator before, iterator first, iterator afterLast);
188
196 iterator insert(iterator before, size_type numElem, const T& value);
197
204 iterator insert(iterator before, const T& value = T());
211 iterator insert(iterator before, T&& value = T());
212
224
236
244 template<class... Args>
245 iterator emplace(iterator before, Args&&... args);
246
258 template<class... Args>
260
271
282
292 bool remove(const T& value, size_type startIndex = 0);
293
303
312
320
326 bool empty() const;
327
335
342 void reserve(size_type reserveLength);
343
354
365
373
380
384 void clear();
385
391 void push_back(const T& value);
392
398 void push_back(T&& value);
399
405 template<class... Args>
406 void emplace_back(Args&&... args);
407
415 bool contains(const ConstForPtrT& value, size_type startIndex = 0) const;
416
423
429 bool isEmpty() const;
430
437
444
450 int growLength() const;
451
457 const T* asArrayPtr() const;
458
464 const T* getPtr() const;
465
472
476 const T& operator[](size_type index) const;
477
482
490
497 const T& at(size_type index) const;
498
507
514 const T& getAt(size_type index) const;
515
521 T& first();
522
528 const T& first() const;
529
535 T& last();
536
542 const T& last() const;
543
551
559
567
575
583
591
596
601
602 bool operator==(const OdVector& vec) const;
603
611
620 bool find(const ConstForPtrT& value, size_type& index, size_type startIndex = 0) const;
621
632
643
653
660
668 OdVector& swap(size_type firstIndex, size_type secondIndex);
669
674 void swap(OdVector &other);
675
676private:
677 T* m_pData;
678 size_type m_physicalLength;
679 size_type m_logicalLength;
680 int m_growLength;
681};
682
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
686
687template<class T, class A, class Mm>
689: m_pData(NULL), m_physicalLength(physicalLength), m_logicalLength(0)
690, m_growLength(growLength)
691{
692 if(m_growLength == 0)
693 {
694 ODA_FAIL();
695 m_growLength = -200;
696 }
697 if (m_physicalLength)
698 {
699 m_pData = allocate(m_physicalLength);
700 }
701}
702
703template <class T, class A, class Mm>
705: m_pData(NULL), m_physicalLength(0), m_logicalLength(0), m_growLength(-200)
706{
707}
708
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)
713{
714 static_assert(std::is_copy_constructible<T>::value, "Can not copy vector with non-copyable argument");
715 if(m_physicalLength > 0)
716 {
717 m_pData = allocate(m_physicalLength);
718
719 A::copyConstructRange(m_pData, vec.m_pData, m_logicalLength);
720 }
721}
722
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)
727{
728 vec.m_pData = nullptr;
729 vec.m_physicalLength = 0;
730 vec.m_logicalLength = 0;
731 vec.m_growLength = -200;
732}
733
734template <class T, class A, class Mm>
736{
737 release();
738}
739
740template <class T, class A, class Mm>
742{
743 static_assert(std::is_copy_constructible<T>::value, "Can not copy vector with non-copyable argument");
744 if(this != &vec)
745 {
746 release();
747 m_logicalLength = 0;
748 if (vec.m_logicalLength > 0)
749 {
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;
754 }
755 }
756 return *this;
757}
758
759template <class T, class A, class Mm>
761{
762 if(this != &vec)
763 {
764 release();
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;
773 }
774 return *this;
775}
776
777template <class T, class A, class Mm>
778inline T* OdVector<T, A, Mm>::allocate(size_type physicalLength)
779{
780 ODA_ASSERT(physicalLength != 0);
781 OdUInt64 nBytes2Allocate = (OdUInt64)physicalLength * sizeof(T);
782 ODA_ASSERT(nBytes2Allocate >= physicalLength); // size_type overflow
783 size_t nBytes2AllocateSize_t = (size_t)nBytes2Allocate;//size_t overflow on x32
784 T* pData = NULL;
785 if (nBytes2Allocate >= physicalLength && (OdUInt64)nBytes2AllocateSize_t == nBytes2Allocate)
786 pData = static_cast<T*>(Mm::Alloc(nBytes2AllocateSize_t));
787
788 if (pData == NULL)
789 throw OdError(eOutOfMemory);
790
791 return pData;
792}
793
794template <class T, class A, class Mm>
795inline void OdVector<T, A, Mm>::release()
796{
797 if (m_pData != NULL)
798 {
799 A::destroyRange(m_pData, m_logicalLength);
800
801 Mm::Free(m_pData);
802 m_pData = NULL;
803 m_physicalLength = 0;
804 }
805}
806
807template <class T, class A, class Mm>
808inline void OdVector<T, A, Mm>::reallocate(size_type physicalLength, bool isUseRealloc, bool isForcePhysicalLength)
809{
810 T* pOldData = m_pData;
811 size_type newPhysicalLength = physicalLength;
812
813 if(!isForcePhysicalLength)
814 newPhysicalLength = calcPhysicalLength(physicalLength);
815
816 if(isUseRealloc && A::useRealloc() && m_logicalLength > 0 && m_pData != NULL)
817 {
818 m_pData = reinterpret_cast<T*>(Mm::Realloc(pOldData, newPhysicalLength*sizeof(T), m_physicalLength*sizeof(T)));
819
820 if (!m_pData)
821 throw OdError(eOutOfMemory);
822
823 m_physicalLength = newPhysicalLength;
824
825 if(physicalLength < m_logicalLength)
826 m_logicalLength = physicalLength;
827 }
828 else
829 {
830 T* pNewData = allocate(newPhysicalLength);
831 const size_type newLogicalLength = odmin(m_logicalLength, physicalLength);
832
833 A::moveConstructRange(pNewData, pOldData, newLogicalLength);
834
835 release();
836
837 m_pData = pNewData;
838 m_physicalLength = newPhysicalLength;
839 m_logicalLength = newLogicalLength;
840 }
841}
842
843template <class T, class A, class Mm>
844inline bool OdVector<T, A, Mm>::isValid(size_type index) const
845{
846 // index is unsigned here, no need >= 0 check
847 return (index < m_logicalLength);
848}
849
850template <class T, class A, class Mm>
851inline void OdVector<T, A, Mm>::assertValid(size_type index) const
852{
853 if(!isValid(index))
854 {
855 ODA_FAIL();
856 throw OdError_InvalidIndex();
857 }
858}
859
860template <class T, class A, class Mm>
861inline void OdVector<T, A, Mm>::riseError(OdResult res)
862{
863 ODA_FAIL();
864 throw OdError(res);
865}
866
867template <class T, class A, class Mm>
868inline VEC_CONST_ITERATOR OdVector<T, A, Mm>::begin_const() const
869{
870 return begin();
871}
872
873template <class T, class A, class Mm>
874inline VEC_ITERATOR OdVector<T, A, Mm>::begin_non_const()
875{
876 return begin();
877}
878
879template <class T, class A, class Mm>
880inline VEC_CONST_ITERATOR OdVector<T, A, Mm>::end_const() const
881{
882 return end();
883}
884
885template <class T, class A, class Mm>
886inline VEC_ITERATOR OdVector<T, A, Mm>::end_non_const()
887{
888 return end();
889}
890
891template <class T, class A, class Mm>
893{
894 return (!isEmpty() ? m_pData : NULL);
895}
896
897template <class T, class A, class Mm>
899{
900 return (!isEmpty() ? m_pData : NULL);
901}
902
903template <class T, class A, class Mm>
905{
906 return (!isEmpty() ? m_pData + m_logicalLength : NULL);
907}
908
909template <class T, class A, class Mm>
911{
912 return (!isEmpty() ? m_pData + m_logicalLength : NULL);
913}
914
915template <class T, class A, class Mm>
917{
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.");
921#endif
922 const size_type oldLogicalLength = m_logicalLength;
923 const size_type index = (size_type)(before - begin_const());
924
926 {
927 if(afterLast > first)
928 {
929 const size_type numElem = (size_type)(afterLast - first);
930 const size_type newLogicalLength = oldLogicalLength + numElem;
931
932 if (newLogicalLength <= m_physicalLength)
933 {
934 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
935 m_logicalLength = newLogicalLength;
936 T* pData = m_pData + index;
937
938 if (index != oldLogicalLength)
939 A::moveAssignRange(pData + numElem, pData, oldLogicalLength - index);
940
941 A::copyAssignRangeDisjoint(pData, first, numElem);
942 }
943 else
944 {
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);
950 release();
951 m_pData = pNewData;
952 m_physicalLength = newPhysicalLength;
953 m_logicalLength = newLogicalLength;
954 }
955 }
956 }
957 else
958 riseError(eInvalidInput);
959}
960
961template <class T, class A, class Mm>
963{
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.");
967#endif
968 const size_type oldLogicalLength = m_logicalLength;
969 const size_type index = (size_type)(before - begin_const());
970
972 {
973 if (afterLast > first)
974 {
975 const size_type numElem = (size_type)(afterLast - first);
976 const size_type newLogicalLength = oldLogicalLength + numElem;
977
978 if (newLogicalLength <= m_physicalLength)
979 {
980 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
981 m_logicalLength = newLogicalLength;
982 T* pData = m_pData + index;
983
984 if (index != oldLogicalLength)
985 A::moveAssignRange(pData + numElem, pData, oldLogicalLength - index);
986
987 A::moveAssignRange(pData, first, numElem);
988 }
989 else
990 {
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);
996 release();
997 m_pData = pNewData;
998 m_physicalLength = newPhysicalLength;
999 m_logicalLength = newLogicalLength;
1000 }
1001 }
1002 }
1003 else
1004 riseError(eInvalidInput);
1005}
1006
1007template <class T, class A, class Mm>
1009{
1010 if (numElem == 0)
1011 return before;
1012
1013 const size_type oldLogicalLength = m_logicalLength;
1014 const size_type newLogicalLength = oldLogicalLength + numElem;
1015 const size_type index = (size_type)(before - begin_const());
1016
1017 if (index == oldLogicalLength)
1018 {
1019 if (newLogicalLength <= m_physicalLength)
1020 {
1021 A::copyConstructFill(m_pData + oldLogicalLength, numElem, value);
1022 }
1023 else
1024 {
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));
1029 }
1030 m_logicalLength = newLogicalLength;
1031 }
1032 else if (index < oldLogicalLength)
1033 {
1034 const T valueCopy(value);
1035 if (newLogicalLength > m_physicalLength)
1036 reallocate(newLogicalLength, true);
1037
1038 A::defaultConstructFill(m_pData + oldLogicalLength, numElem);
1039
1040 m_logicalLength = newLogicalLength;
1041
1042 T* pData = m_pData + index;
1043
1044 A::moveAssignRange(pData + numElem, pData, oldLogicalLength - index);
1045
1046 while (numElem-- > 1)
1047 pData[numElem] = valueCopy;
1048 pData[0] = std::move(valueCopy);
1049 }
1050
1051 return (begin_non_const() + index);
1052}
1053
1054template <class T, class A, class Mm>
1056{
1057 const size_type index = (size_type)(before - begin_const());
1058
1060
1061 return (begin_non_const() + index);
1062}
1063
1064template <class T, class A, class Mm>
1066{
1067 const size_type index = (size_type)(before - begin_const());
1068
1069 insertAt(index, std::move(value));
1070
1071 return (begin_non_const() + index);
1072}
1073
1074template <class T, class A, class Mm>
1076{
1077 const size_type oldLogicalLength = m_logicalLength;
1078 const size_type newLogicalLength = oldLogicalLength + 1;
1079
1080 if (index == oldLogicalLength)
1081 {
1083 }
1084 else if (index < oldLogicalLength)
1085 {
1086 const T valueCopy(value);
1087 if (newLogicalLength > m_physicalLength)
1088 reallocate(newLogicalLength, true);
1089
1090 A::defaultConstruct(m_pData + oldLogicalLength);
1091
1092 ++m_logicalLength;
1093
1094 T* pData = m_pData + index;
1095
1096 A::moveAssignRange(pData + 1, pData, oldLogicalLength - index);
1097
1098 *pData = std::move(valueCopy);
1099 }
1100 else
1101 riseError(eInvalidIndex);
1102
1103 return *this;
1104}
1105
1106template <class T, class A, class Mm>
1108{
1109 const size_type oldLogicalLength = m_logicalLength;
1110 const size_type newLogicalLength = oldLogicalLength + 1;
1111
1112 if (index == oldLogicalLength)
1113 {
1114 push_back(std::move(value));
1115 }
1116 else if (index < oldLogicalLength)
1117 {
1118 T valueMoved(std::move(value));
1119 if (newLogicalLength > m_physicalLength)
1120 reallocate(newLogicalLength, true);
1121
1122 A::defaultConstruct(m_pData + oldLogicalLength);
1123
1124 ++m_logicalLength;
1125
1126 T* pData = m_pData + index;
1127
1128 A::moveAssignRange(pData + 1, pData, oldLogicalLength - index);
1129
1130 *pData = std::move(valueMoved);
1131 }
1132 else
1133 riseError(eInvalidIndex);
1134
1135 return *this;
1136}
1137
1138template <class T, class A, class Mm>
1139template <class... Args>
1141{
1142 const size_type index = (size_type)(before - begin_const());
1143
1144 emplaceAt(index, std::forward<Args>(args)...);
1145
1146 return (begin_non_const() + index);
1147}
1148
1149template <class T, class A, class Mm>
1150template <class... Args>
1152{
1153 const size_type oldLogicalLength = m_logicalLength;
1154 const size_type newLogicalLength = oldLogicalLength + 1;
1155
1156 if (index == oldLogicalLength)
1157 {
1158 emplace_back(std::forward<Args>(args)...);
1159 }
1160 else if (index < oldLogicalLength)
1161 {
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);
1167 release();
1168 m_pData = pNewData;
1169 m_physicalLength = newPhysicalLength;
1170 m_logicalLength = newLogicalLength;
1171 }
1172 else
1173 riseError(eInvalidIndex);
1174
1175 return *this;
1176}
1177
1178template <class T, class A, class Mm>
1180{
1181 assertValid(index);
1182
1183 const size_type newLogicalLength = m_logicalLength - 1;
1184
1185 if(index < newLogicalLength)
1186 {
1187 T* pData = m_pData + index;
1188 A::moveAssignRange(pData, pData + 1, newLogicalLength - index);
1189 }
1190
1191 resize(newLogicalLength);
1192 return *this;
1193}
1194
1195template <class T, class A, class Mm>
1197{
1198 if(!isValid(startIndex) || startIndex > endIndex)
1199 riseError(eInvalidIndex);
1200
1201 const size_type oldLogicalLength = m_logicalLength;
1202
1203 T* pData = m_pData;
1204
1205 ++endIndex;
1206
1207 const size_type numElem = endIndex - startIndex;
1208
1209 A::moveAssignRange(pData + startIndex, pData + endIndex, oldLogicalLength - endIndex);
1210 A::destroyRange(pData + oldLogicalLength - numElem, numElem);
1211
1212 m_logicalLength -= numElem;
1213 return *this;
1214}
1215
1216template <class T, class A, class Mm>
1217inline bool OdVector<T, A, Mm>::remove(const T& value, size_type startIndex)
1218{
1219 size_type index = 0;
1220 if(find(value, index, startIndex))
1221 {
1222 removeAt(index);
1223 return true;
1224 }
1225 return false;
1226}
1227
1228template <class T, class A, class Mm>
1230{
1231 const size_type oldLogicalLength = m_logicalLength;
1232 const int lengthDiff = logicalLength - oldLogicalLength;
1233
1234 if(lengthDiff > 0)
1235 {
1236 const T valueCopy(value);
1237 if (logicalLength > m_physicalLength)
1238 reallocate(logicalLength, true);
1239
1240 A::copyConstructFill(m_pData + oldLogicalLength, lengthDiff, valueCopy);
1241 }
1242 else if(lengthDiff < 0)
1243 A::destroyRange(m_pData + logicalLength, -lengthDiff);
1244
1245 m_logicalLength = logicalLength;
1246}
1247
1248template <class T, class A, class Mm>
1250{
1251 const size_type oldLogicalLength = m_logicalLength;
1252
1253 if(logicalLength > oldLogicalLength)
1254 {
1255 if(logicalLength > m_physicalLength)
1256 reallocate(logicalLength, true);
1257 A::defaultConstructFill(m_pData + oldLogicalLength, logicalLength - oldLogicalLength);
1258 }
1259 else if(logicalLength < oldLogicalLength)
1260 A::destroyRange(m_pData + logicalLength, oldLogicalLength - logicalLength);
1261
1262 m_logicalLength = logicalLength;
1263}
1264
1265template <class T, class A, class Mm>
1267{
1268 return m_logicalLength;
1269}
1270
1271template <class T, class A, class Mm>
1272inline bool OdVector<T, A, Mm>::empty() const
1273{
1274 return (m_logicalLength == 0);
1275}
1276
1277template <class T, class A, class Mm>
1279{
1280 return m_physicalLength;
1281}
1282
1283template <class T, class A, class Mm>
1284inline void OdVector<T, A, Mm>::reserve(size_type reserveLength)
1285{
1286 if(m_physicalLength < reserveLength)
1287 setPhysicalLength(reserveLength);
1288}
1289
1290template <class T, class A, class Mm>
1292{
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.");
1296#endif
1297 clear();
1298 insert(begin_non_const(), first, afterLast);
1299}
1300
1301template <class T, class A, class Mm>
1303{
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.");
1307#endif
1308 clear();
1309 insertMove(begin_non_const(), first, afterLast);
1310}
1311
1312template <class T, class A, class Mm>
1314{
1315 const size_type index = (size_type)(first - begin_const());
1316
1317 if(first != afterLast)
1318 removeSubArray(index, (size_type)(afterLast - begin_const() - 1));
1319
1320 return (begin_non_const() + index);
1321}
1322
1323template <class T, class A, class Mm>
1325{
1326 const size_type index = (size_type)(it - begin_const());
1327
1328 removeAt(index);
1329
1330 return (begin_non_const() + index);
1331}
1332
1333template <class T, class A, class Mm>
1335{
1336 const size_type numElem = (size_type)(end_const() - begin_const());
1337 A::destroyRange(m_pData, numElem);
1338 m_logicalLength = 0;
1339}
1340
1341template <class T, class A, class Mm>
1343{
1344 if (m_physicalLength > m_logicalLength)
1345 {
1346 A::copyConstruct(m_pData + m_logicalLength, value);
1347 }
1348 else
1349 {
1350 const T valueCopy(value);
1351 reallocate(m_logicalLength + 1, true);
1352 A::copyConstruct(m_pData + m_logicalLength, std::move(valueCopy));
1353 }
1354 ++m_logicalLength;
1355}
1356
1357template <class T, class A, class Mm>
1359{
1360 if (m_physicalLength > m_logicalLength)
1361 {
1362 A::moveConstruct(m_pData + m_logicalLength, std::move(value));
1363 }
1364 else
1365 {
1366 T valueMoved(std::move(value));
1367 reallocate(m_logicalLength + 1, true);
1368 A::moveConstruct(m_pData + m_logicalLength, std::move(valueMoved));
1369 }
1370 ++m_logicalLength;
1371}
1372
1373template <class T, class A, class Mm>
1374template<class... Args>
1375inline void OdVector<T, A, Mm>::emplace_back(Args&&... args)
1376{
1377 if (m_physicalLength > m_logicalLength)
1378 {
1379 A::construct(m_pData + m_logicalLength, std::forward<Args>(args)...);
1380 }
1381 else
1382 {
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);
1387 release();
1388 m_pData = pNewData;
1389 m_physicalLength = newPhysicalLength;
1390 }
1391 ++m_logicalLength;
1392}
1393
1394template <class T, class A, class Mm>
1395inline bool OdVector<T, A, Mm>::contains(const ConstForPtrT& value, size_type startIndex) const
1396{
1398
1399 return find(value, index, startIndex);
1400}
1401
1402template <class T, class A, class Mm>
1404{
1405 return m_logicalLength;
1406}
1407
1408template <class T, class A, class Mm>
1410{
1411 return (m_logicalLength == 0);
1412}
1413
1414template <class T, class A, class Mm>
1416{
1417 return m_logicalLength;
1418}
1419
1420template <class T, class A, class Mm>
1422{
1423 return m_physicalLength;
1424}
1425
1426template <class T, class A, class Mm>
1428{
1429 return m_growLength;
1430}
1431
1432template <class T, class A, class Mm>
1433inline const T* OdVector<T, A, Mm>::asArrayPtr() const
1434{
1435 return m_pData;
1436}
1437
1438template <class T, class A, class Mm>
1439inline const T* OdVector<T, A, Mm>::getPtr() const
1440{
1441 return m_pData;
1442}
1443
1444template <class T, class A, class Mm>
1446{ // OdArray::asArrayPtr invokes non-const version of data() method which checks length and return null.
1447 // Constant version of asArrayPtr and getPtr will return m_pData as is for OdArray too.
1448 return (length()) ? m_pData : NULL;
1449}
1450
1451template <class T, class A, class Mm>
1453{
1454 assertValid(index);
1455 return m_pData[index];
1456}
1457
1458template <class T, class A, class Mm>
1460{
1461 assertValid(index);
1462 return m_pData[index];
1463}
1464
1465template <class T, class A, class Mm>
1467{
1468 assertValid(index);
1469 return m_pData[index];
1470}
1471
1472template <class T, class A, class Mm>
1474{
1475 assertValid(index);
1476 return m_pData[index];
1477}
1478
1479template <class T, class A, class Mm>
1481{
1482 assertValid(index);
1483
1484 m_pData[index] = value;
1485
1486 return *this;
1487}
1488
1489template <class T, class A, class Mm>
1491{
1492 assertValid(index);
1493 return m_pData[index];
1494}
1495
1496template <class T, class A, class Mm>
1498{
1499 return m_pData[0];
1500}
1501
1502template <class T, class A, class Mm>
1503inline const T& OdVector<T, A, Mm>::first() const
1504{
1505 return m_pData[0];
1506}
1507
1508template <class T, class A, class Mm>
1510{
1511 return m_pData[m_logicalLength - 1];
1512}
1513
1514template <class T, class A, class Mm>
1515inline const T& OdVector<T, A, Mm>::last() const
1516{
1517 return m_pData[m_logicalLength - 1];
1518}
1519
1520template <class T, class A, class Mm>
1522{
1524 return (m_logicalLength - 1);
1525}
1526template <class T, class A, class Mm>
1528{
1529 push_back(std::move(value));
1530 return (m_logicalLength - 1);
1531}
1532
1533template <class T, class A, class Mm>
1535{
1536 const size_type index = append(T());
1537 return (begin_non_const() + index);
1538}
1539
1540template <class T, class A, class Mm>
1542{
1543 insert(end_non_const(), vec.begin(), vec.end());
1544 return *this;
1545}
1546
1547template <class T, class A, class Mm>
1549{
1550 insertMove(end_non_const(), vec.begin(), vec.end());
1551 return *this;
1552}
1553
1554template <class T, class A, class Mm>
1559
1560template <class T, class A, class Mm>
1565
1566template <class T, class A, class Mm>
1568{
1569 return removeAt(m_logicalLength - 1);
1570}
1571
1572template <class T, class A, class Mm>
1574{
1575 if(m_logicalLength == vec.m_logicalLength)
1576 {
1577 for(size_type i = 0; i < m_logicalLength; ++i)
1578 {
1579 if(m_pData[i] != vec.m_pData[i])
1580 return false;
1581 }
1582 return true;
1583 }
1584 return false;
1585}
1586
1587template <class T, class A, class Mm>
1589{
1590 for(size_type i = 0; i < m_logicalLength; ++i)
1591 m_pData[i] = value;
1592
1593 return *this;
1594}
1595
1596template <class T, class A, class Mm>
1598{
1599 if(!isEmpty())
1600 {
1601 assertValid(startIndex);
1602
1603 for(size_type i = startIndex; i < m_logicalLength; ++i)
1604 {
1605 if(m_pData[i] == value)
1606 {
1607 index = i;
1608 return true;
1609 }
1610 }
1611 }
1612 return false;
1613}
1614
1615template <class T, class A, class Mm>
1621
1622template <class T, class A, class Mm>
1624{
1625 if(physicalLength == 0)
1626 {
1627 release();
1628
1629 m_pData = NULL;
1630 m_physicalLength = 0;
1631 }
1632 else if(physicalLength != m_physicalLength)
1633 reallocate(physicalLength, true, true);
1634
1635 if(m_physicalLength < m_logicalLength)
1636 m_logicalLength = m_physicalLength;
1637
1638 return *this;
1639}
1640
1641template <class T, class A, class Mm>
1643{
1644 if(growLength != 0)
1645 m_growLength = growLength;
1646 else
1647 ODA_FAIL();
1648
1649 return *this;
1650}
1651
1652template <class T, class A, class Mm>
1654{
1655 if(!isEmpty())
1656 {
1657 T value;
1658 iterator it1 = begin_non_const();
1659 iterator it2 = end_non_const();
1660
1661 --it2;
1662
1663 while(it1 < it2)
1664 {
1665 value = *it1;
1666 *it1 = *it2;
1667 *it2 = value;
1668
1669 ++it1;
1670 --it2;
1671 }
1672 }
1673 return *this;
1674}
1675
1676template <class T, class A, class Mm>
1678{
1679 if(!isValid(firstIndex) || !isValid(secondIndex))
1680 riseError(eInvalidIndex);
1681
1682 if(firstIndex != secondIndex)
1683 {
1684 T value = std::move(m_pData[firstIndex]);
1685 m_pData[firstIndex] = std::move(m_pData[secondIndex]);
1686 m_pData[secondIndex] = std::move(value);
1687 }
1688
1689 return *this;
1690}
1691
1692template <class T, class A, class Mm>
1694{
1695 T* ptr = m_pData;
1696 m_pData = other.m_pData;
1697 other.m_pData = ptr;
1698 size_type sz = m_physicalLength;
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;
1707}
1708
1709
1710#include "TD_PackPop.h"
1711
1718#ifdef OD_GEPNT3D_H
1720#endif
1721#ifdef OD_GEVEC3D_H
1723#endif
1724
1725#endif // OdVector_H_INCLUDED
1726// FELIX_CHANGE_END file was take from ODA gitlab repository https://gitlab.opendesign.com/
#define ODA_ASSERT(exp)
Definition DebugStuff.h:57
#define ODA_FAIL()
Definition DebugStuff.h:88
ODRX_CONSTEXPR const T & odmin(const T &a, const T &b)
Definition OdPlatform.h:64
OdResult
Definition OdResult.h:29
#define VEC_CONST_ITERATOR
Definition OdVector.h:685
#define VEC_SIZE_TYPE
Definition OdVector.h:683
OdVector< bool, OdMemoryAllocator< bool > > OdBoolVector
Definition OdVector.h:1717
OdVector< OdUInt8, OdMemoryAllocator< OdUInt8 > > OdUInt8Vector
Definition OdVector.h:1715
OdVector< OdUInt64, OdMemoryAllocator< OdUInt64 > > OdUInt64Vector
Definition OdVector.h:1716
OdVector< int, OdMemoryAllocator< int > > OdIntVector
Definition OdVector.h:1712
#define VEC_ITERATOR
Definition OdVector.h:684
OdVector< OdInt32, OdMemoryAllocator< OdInt32 > > OdInt32Vector
Definition OdVector.h:1714
OdVector< OdUInt32, OdMemoryAllocator< OdUInt32 > > OdUInt32Vector
Definition OdVector.h:1713
OdVector & reverse()
Definition OdVector.h:1653
const_iterator begin() const
Definition OdVector.h:898
iterator append()
Definition OdVector.h:1534
OdVector & setAll(const T &value)
Definition OdVector.h:1588
iterator emplace(iterator before, Args &&... args)
const_iterator end() const
Definition OdVector.h:910
void reserve(size_type reserveLength)
Definition OdVector.h:1284
iterator insert(iterator before, size_type numElem, const T &value)
Definition OdVector.h:1008
iterator insert(iterator before, T &&value=T())
Definition OdVector.h:1065
OdVector & setGrowLength(int growLength)
Definition OdVector.h:1642
OdVector & removeSubArray(size_type startIndex, size_type endIndex)
Definition OdVector.h:1196
bool empty() const
Definition OdVector.h:1272
const T & operator[](size_type index) const
Definition OdVector.h:1452
typename OdMemoryAllocator< OdGiTriangleForIntersectTest >::size_type size_type
Definition OdVector.h:67
OdVector & removeLast()
Definition OdVector.h:1567
T & operator[](size_type index)
Definition OdVector.h:1459
bool find(const ConstForPtrT &value, size_type &index, size_type startIndex=0) const
Definition OdVector.h:1597
OdVector(OdVector &&vec)
Definition OdVector.h:724
void emplace_back(Args &&... args)
Definition OdVector.h:1375
iterator erase(iterator where)
Definition OdVector.h:1324
bool remove(const T &value, size_type startIndex=0)
Definition OdVector.h:1217
iterator begin()
Definition OdVector.h:892
iterator insert(iterator before, const T &value=T())
Definition OdVector.h:1055
size_type length() const
Definition OdVector.h:1403
void clear()
Definition OdVector.h:1334
iterator erase(iterator first, iterator afterLast)
Definition OdVector.h:1313
const T & first() const
Definition OdVector.h:1503
OdVector & operator=(OdVector &&vec)
Definition OdVector.h:760
void resize(size_type logicalLength, const T &value)
Definition OdVector.h:1229
void push_back(T &&value)
Definition OdVector.h:1358
OdVector & append(const OdVector &vec)
Definition OdVector.h:1541
const T & at(size_type index) const
Definition OdVector.h:1473
~OdVector()
Definition OdVector.h:735
void push_back(const T &value)
Definition OdVector.h:1342
OdVector & emplaceAt(size_type index, Args &&... args)
OdVector & insertAt(size_type index, const T &value)
Definition OdVector.h:1075
const T & getAt(size_type index) const
Definition OdVector.h:1490
size_type size() const
Definition OdVector.h:1266
void assign(const_iterator first, const_iterator afterLast)
Definition OdVector.h:1291
const T * asArrayPtr() const
Definition OdVector.h:1433
const T * getPtr() const
Definition OdVector.h:1439
size_type append(const T &value)
Definition OdVector.h:1521
T * asArrayPtr()
Definition OdVector.h:1445
typename std::conditional< std::is_pointer< OdGiTriangleForIntersectTest >::value, typename std::add_const< typename std::remove_pointer< OdGiTriangleForIntersectTest >::type >::type *, OdGiTriangleForIntersectTest >::type ConstForPtrT
Definition OdVector.h:74
size_type capacity() const
Definition OdVector.h:1278
void insertMove(iterator before, iterator first, iterator afterLast)
Definition OdVector.h:962
OdVector & setLogicalLength(size_type logicalLength)
Definition OdVector.h:1616
bool isEmpty() const
Definition OdVector.h:1409
OdVector & removeAt(size_type index)
Definition OdVector.h:1179
OdVector & setPhysicalLength(size_type physicalLength)
Definition OdVector.h:1623
size_type append(T &&value)
Definition OdVector.h:1527
void resize(size_type logicalLength)
Definition OdVector.h:1249
OdVector & swap(size_type firstIndex, size_type secondIndex)
Definition OdVector.h:1677
bool operator==(const OdVector &vec) const
Definition OdVector.h:1573
OdVector & operator=(const OdVector &vec)
Definition OdVector.h:741
OdVector(size_type physicalLength, int growLength=8)
Definition OdVector.h:688
void swap(OdVector &other)
Definition OdVector.h:1693
void insert(iterator before, const_iterator first, const_iterator afterLast)
Definition OdVector.h:916
bool contains(const ConstForPtrT &value, size_type startIndex=0) const
Definition OdVector.h:1395
T & at(size_type index)
Definition OdVector.h:1466
OdVector(const OdVector &vec)
Definition OdVector.h:710
OdVector & removeFirst()
Definition OdVector.h:1561
T & last()
Definition OdVector.h:1509
iterator end()
Definition OdVector.h:904
void assignMove(iterator first, iterator afterLast)
Definition OdVector.h:1302
OdVector & appendMove(OdVector &vec)
Definition OdVector.h:1548
OdVector & append(OdVector &&vec)
Definition OdVector.h:1555
OdVector & insertAt(size_type index, T &&value)
Definition OdVector.h:1107
OdVector & setAt(size_type index, const T &value)
Definition OdVector.h:1480
const T & last() const
Definition OdVector.h:1515
GLuint index
Definition gles2_ext.h:265
GLuint GLsizei GLsizei GLint GLenum * type
Definition gles2_ext.h:274
GLuint GLsizei GLsizei * length
Definition gles2_ext.h:274
GLsizei const GLfloat * value
Definition gles2_ext.h:302