CFx SDK Documentation 2024 SP0
Loading...
Searching...
No Matches
OdArray.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-2022, 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-2022 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
26
27
28#ifndef ODARRAY_H_INCLUDED
29#define ODARRAY_H_INCLUDED
30
31#include <new>
32#include <utility>
33
34#include "TD_PackPush.h"
35
36#include "OdArrayPreDef.h"
37#include "OdHeap.h"
38#include "OdMutex.h"
39#include "OdError.h"
40#include "RxSystemServices.h"
41#include <iterator>
42#include <algorithm>
43#include <type_traits>
44
45template<class T>
47{
48 static const bool value = false;
49};
50
51template <class First, class Second>
52struct od_is_trivially_copyable_pair <std::pair<First, Second>>
53{
54 static const bool value = std::is_trivially_copyable<First>::value && std::is_trivially_copyable<Second>::value;
55};
56
57// FELIX_CHANGE_BEGIN
58template< typename T, bool >
60
61template< typename T >
63{
65 {
66 //#if defined (_MSC_VER) && defined(_DEBUG)
67 //T; // Just to generate MSVC warning C4091 to be able fix memory allocator
68 //#endif
69 }
70};
71
72template< typename T >
73struct should_be_trivially_copyable : public check_trivially_copyable< T, std::is_trivially_copyable<T>::value || od_is_trivially_copyable_pair<T>::value >
74{
75};
76// FELIX_CHANGE_END
77
78
87template <class T> class OdMemoryAllocator
88{
89public:
90 typedef unsigned int size_type;
91
103 static inline void copyAssignRangeDisjoint(
104 T* pDestination,
105 const T* pSource,
106 size_type numElements)
107 {
108 // FELIX_CHANGE_BEGIN
109 #if defined (_MSC_VER) && defined(_DEBUG)
111 #endif
112 // FELIX_CHANGE_END
113 memcpy(pDestination, pSource, numElements * sizeof(T));
114 }
115
127 static inline void copyAssignRange(
128 T* pDestination,
129 const T* pSource,
130 size_type numElements)
131 {
132 // FELIX_CHANGE_BEGIN
133 #if defined (_MSC_VER) && defined(_DEBUG)
135 #endif
136 // FELIX_CHANGE_END
137 memmove(pDestination, pSource, numElements * sizeof(T));
138 }
139
150 static inline void moveAssignRange(
151 T* pDestination,
152 T* pSource,
153 size_type numElements)
154 {
155 // FELIX_CHANGE_BEGIN
156 #if defined (_MSC_VER) && defined(_DEBUG)
158 #endif
159 // FELIX_CHANGE_END
160 memmove(pDestination, pSource, numElements * sizeof(T));
161 }
162
172 static inline void defaultConstruct(
173 T* pElement)
174 {
175 // FELIX_CHANGE_BEGIN
176 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || od_is_trivially_copyable_pair<T>::value);
177 // FELIX_CHANGE_END
178 *pElement = T();
179 }
180
187 static inline void copyConstruct(
188 T* pElement,
189 const T& value)
190 {
191 // FELIX_CHANGE_BEGIN
192 #if defined (_MSC_VER) && defined(_DEBUG)
194 #endif
195#if defined(__GNUC__) && (__GNUC__ > 4)
196 // The below memcpy may cause warnings and errors, when pushing elements to an empty array. Disable for now.
197#pragma GCC diagnostic push
198#pragma GCC diagnostic ignored "-Warray-bounds"
199#pragma GCC diagnostic ignored "-Wstringop-overflow"
200#endif
201 // FELIX_CHANGE_END
202 memcpy(pElement, &value, sizeof(value));
203 // FELIX_CHANGE_BEGIN
204#if defined(__GNUC__) && (__GNUC__ > 4)
205#pragma GCC diagnostic pop
206#endif
207 // FELIX_CHANGE_END
208 }
209
216 static inline void moveConstruct(
217 T* pElement,
218 T&& value)
219 {
220 // FELIX_CHANGE_BEGIN
221 #if defined (_MSC_VER) && defined(_DEBUG)
223 #endif
224 // FELIX_CHANGE_END
225 memmove(pElement, &value, sizeof(value));
226 }
227
235 static inline void copyConstructFill(
236 T* pDestination,
237 size_type numElements,
238 const T& value)
239 {
240 // FELIX_CHANGE_BEGIN
241 #if defined (_MSC_VER) && defined(_DEBUG)
243 #endif
244 // FELIX_CHANGE_END
245
246 while(numElements--)
247 {
248 memcpy(pDestination + numElements, &value, sizeof(value));
249 }
250 }
251
259 static inline void copyConstructRange(
260 T* pDestination,
261 const T* pSource,
262 size_type numElements)
263 {
264 copyAssignRangeDisjoint(pDestination, pSource, numElements);
265 }
266
274 static inline void moveConstructRange(
275 T* pDestination,
276 T* pSource,
277 size_type numElements)
278 {
279 copyAssignRangeDisjoint(pDestination, pSource, numElements);
280 }
281
292 static inline void defaultConstructFill(
293 T* pDestination,
294 size_type numElements)
295 {
296 // DOES NOTHING
297 }
298
304 static inline void destroy(
305 T* pObject)
306 {
307 // DOES NOTHING
308 }
309
316 static inline void destroyRange(
317 T* objects,
318 size_type numObjects)
319 {
320 // DOES NOTHING
321 }
322
328 static inline bool useRealloc()
329 {
330 return true;
331 }
332};
333
334
343template <class T> class OdClrMemAllocator : public OdMemoryAllocator<T>
344{
345public:
346 typedef unsigned int size_type;
347
355 static inline void copyConstructFill(
356 T* pDestination,
357 size_type numElements,
358 const T& value)
359 {
360 OdMemoryAllocator<T>::copyConstructFill(pDestination, numElements, value);
361 }
362
370 static inline void copyConstructRange(
371 T* pDestination,
372 const T* pSource,
373 size_type numElements)
374 {
375 OdMemoryAllocator<T>::copyConstructRange(pDestination, pSource, numElements);
376 }
377
388 static inline void defaultConstructFill(
389 T* pDestination,
390 size_type numElements)
391 {
392 // FELIX_CHANGE_BEGIN
393 #if defined (_MSC_VER) && defined(_DEBUG)
395 #endif
396 // FELIX_CHANGE_END
397
398 memset(pDestination, 0, numElements * sizeof(T));
399 }
400};
401
402
415template <class T> class OdObjectsAllocator
416{
417public:
418 typedef unsigned int size_type;
419
431 static inline void copyAssignRangeDisjoint(
432 T* pDestination,
433 const T* pSource,
434 size_type numElements)
435 {
436 while(numElements--)
437 {
438 *pDestination = *pSource;
439 pDestination++;
440 pSource++;
441 }
442 }
443
455 static inline void copyAssignRange(
456 T* pDestination,
457 const T* pSource,
458 size_type numElements)
459 {
460 if (pDestination <= pSource || pDestination >= pSource + numElements)
461 {
462 copyAssignRangeDisjoint(pDestination, pSource, numElements);
463 }
464 else
465 {
466 while(numElements--)
467 {
468 pDestination[numElements] = pSource[numElements];
469 }
470 }
471 }
472
483 static inline void moveAssignRange(
484 T* pDestination,
485 T* pSource,
486 size_type numElements)
487 {
488 if (pDestination <= pSource || pDestination >= pSource + numElements)
489 {
490 while(numElements--)
491 {
492 *pDestination = std::move(*pSource);
493 pDestination++;
494 pSource++;
495 }
496 }
497 else
498 {
499 while(numElements--)
500 {
501 pDestination[numElements] = std::move(pSource[numElements]);
502 }
503 }
504 }
505
515 static inline void defaultConstruct(
516 T* pElement)
517 {
518#ifdef new
519#undef new
520#endif
521 ::new (pElement) T;
522 }
523
530 static inline void copyConstruct(
531 T* pElement,
532 const T& value)
533 {
534#ifdef new
535#undef new
536#endif
537 ::new (pElement) T(value);
538 }
539
546 static inline void moveConstruct(
547 T* pElement,
548 T&& value)
549 {
550#ifdef new
551#undef new
552#endif
553 ::new (pElement) T(std::move(value));
554 }
555
563 static inline void copyConstructFill(
564 T* pDestination,
565 size_type numElements,
566 const T& value)
567 {
568 while(numElements--)
569 {
570 copyConstruct(pDestination+numElements, value);
571 }
572 }
573
584 static inline void defaultConstructFill(
585 T* pDestination,
586 size_type numElements)
587 {
588 while(numElements--)
589 {
590 defaultConstruct(pDestination+numElements);
591 }
592 }
593
601 static inline void copyConstructRange(
602 T* pDestination,
603 const T* pSource,
604 size_type numElements)
605 {
606 while(numElements--)
607 {
608 copyConstruct(pDestination, *pSource);
609 pDestination++;
610 pSource++;
611 }
612 }
613
621 static inline void moveConstructRange(
622 T* pDestination,
623 T* pSource,
624 size_type numElements)
625 {
626 while(numElements--)
627 {
628 moveConstruct(pDestination, std::move(*pSource));
629 pDestination++;
630 pSource++;
631 }
632 }
633
639 static inline void destroy(
640 T* pObject)
641 {
642 pObject->~T();
643 pObject = 0;
644 }
645
652 static inline void destroyRange(
653 T* objects,
654 size_type numObjects)
655 {
656 while(numObjects--)
657 {
658 destroy(objects + numObjects);
659 }
660 }
661
670 static inline bool useRealloc()
671 {
672 return false;
673 }
674};
675
676
689template <class T> class OdPlainObjectsAllocator : public OdObjectsAllocator<T>
690{
691public:
692 typedef unsigned int size_type;
693
705 static inline void copyAssignRangeDisjoint(
706 T* pDestination,
707 const T* pSource,
708 size_type numElements)
709 {
710 // FELIX_CHANGE_BEGIN
711 #if defined (_MSC_VER) && defined(_DEBUG)
713 #endif
714 // FELIX_CHANGE_END
715
716 memcpy(pDestination, pSource, numElements * sizeof(T));
717 }
718
730 static inline void copyAssignRange(
731 T* pDestination,
732 const T* pSource,
733 size_type numElements)
734 {
735 // FELIX_CHANGE_BEGIN
736 #if defined (_MSC_VER) && defined(_DEBUG)
738 #endif
739 // FELIX_CHANGE_END
740
741 memmove(pDestination, pSource, numElements * sizeof(T));
742 }
743
754 static inline void moveAssignRange(
755 T* pDestination,
756 T* pSource,
757 size_type numElements)
758 {
759 // FELIX_CHANGE_BEGIN
760 #if defined (_MSC_VER) && defined(_DEBUG)
762 #endif
763 // FELIX_CHANGE_END
764
765 memmove(pDestination, pSource, numElements * sizeof(T));
766 }
767
776 static inline bool useRealloc()
777 {
778 return true;
779 }
780};
781
787{
788 typedef unsigned int size_type;
789
794
796};
797
798
799
828template <class T, class A> class OdArray
829{
830public:
831 using size_type = typename A::size_type;
832 using iterator = T*;
833 using const_iterator = const T*;
834 using value_type = T;
835 using const_reference = const T&;
836 using reference = T&;
837 using ConstForPtrT = typename std::conditional<std::is_pointer<T>::value,
838 typename std::add_const<typename std::remove_pointer<T>::type>::type*, T>::type;
839private:
840 struct Buffer : OdArrayBuffer
841 {
842 T* data() const { return (T*)(this+1); }
843
844 static Buffer* allocate(size_type nLength2Allocate, int nGrowBy)
845 {
846 OdUInt64 nBytes2Allocate = (OdUInt64)sizeof(Buffer) + nLength2Allocate * sizeof(T);
847 ODA_ASSERT(nBytes2Allocate > nLength2Allocate); // size_type overflow
848 size_t nBytes2AllocateSize_t = (size_t)nBytes2Allocate;//size_t overflow on x32
849 if(nBytes2Allocate > nLength2Allocate && (OdUInt64)nBytes2AllocateSize_t == nBytes2Allocate)
850 {
851 Buffer* pBuffer = (Buffer*)::odrxAlloc(nBytes2AllocateSize_t);
852 if (pBuffer)
853 {
854 pBuffer->m_nRefCounter = 1;
855 pBuffer->m_nGrowBy = nGrowBy;
856 pBuffer->m_nAllocated = nLength2Allocate;
857 pBuffer->m_nLength = 0;
858 return pBuffer;
859 }
860 }
861 throw OdError(eOutOfMemory);
862 }
863 static Buffer* _default()
864 {
865 return (Buffer*)&g_empty_array_buffer;
866 }
867 void release()
868 {
870 if((--m_nRefCounter)==0 && this != _default())
871 {
872 A::destroyRange(data(), m_nLength);
873 ::odrxFree(this);
874 }
875 }
876 void addref() const { ++m_nRefCounter; }
877 };
878#if defined(_MSC_VER)
879#pragma warning(disable : 4127) // conditional expression is constant
880#pragma warning(push)
881#endif
882 class reallocator
883 {
884 bool _may_use_realloc;
885 Buffer* m_pBuffer;
886 public:
887 inline reallocator( bool may_use_realloc = false ) : _may_use_realloc(may_use_realloc), m_pBuffer(NULL) {}
888 inline void reallocate(OdArray* pArray, size_type nNewLen)
889 {
890 if(!pArray->referenced())
891 {
892 if(nNewLen > pArray->physicalLength())
893 {
894 if ( !_may_use_realloc )
895 {
896 if (m_pBuffer)
897 m_pBuffer->release();
898 if (!std::is_copy_constructible<T>::value)
899 throw OdError(eNotApplicable); //trying to copy buffer for non-copyable T!
900 m_pBuffer = pArray->buffer();
901 m_pBuffer->addref(); // save buffer to ensure copy from itself would work (e.g insertAt)
902 }
903 pArray->copy_buffer(nNewLen, _may_use_realloc);
904 }
905 }
906 else
907 {
908 pArray->copy_buffer(nNewLen);
909 }
910 }
911 inline ~reallocator()
912 {
913 if (m_pBuffer)
914 m_pBuffer->release();
915 }
916 };
917#if defined(_MSC_VER)
918#pragma warning(pop)
919#endif
920 friend class reallocator;
921 const_iterator begin_const() const { return begin(); }
922 iterator begin_non_const() { return begin(); }
923 const_iterator end_const() { return end(); }
924 iterator end_non_const() { return end(); }
925 void copy_before_write(size_type len, bool may_use_realloc = false )
926 {
927 if( referenced() )
928 copy_buffer(len);
929 else if ( len > physicalLength() )
930 copy_buffer( len, may_use_realloc );
931 }
932 void copy_if_referenced() { if(referenced()) { copy_buffer(physicalLength()); } }
933// FELIX_CHANGE_BEGIN
934#if !defined(SWIG) || defined(SWIGBUILD)
935// FELIX_CHANGE_END
936 template<typename U = T,
937 typename std::enable_if<std::is_same<U, T>::value && std::is_copy_constructible<U>::value, bool>::type = true>
938 inline void copyConstructRangeChecked(T* dest, T* source, size_type len)
939 {
940 A::copyConstructRange(dest, source, len);
941 }
942 template<typename U = T,
943 typename std::enable_if<std::is_same<U, T>::value && !std::is_copy_constructible<U>::value, bool>::type = true>
944 inline void copyConstructRangeChecked(T* dest, T* source, size_type len)
945 {
946 if (len != 0)
947 throw OdError(eNotApplicable); //trying to copy buffer for non-copyable T (should never be here)!
948 }
949#endif
950 void copy_buffer(size_type len, bool may_use_realloc = false, bool force_size = false, bool releaseOldBufAfterCopy = true)
951 {
952 Buffer* pOldBuffer = buffer();
953 int nGrowBy = pOldBuffer->m_nGrowBy;
954 size_type len2 = len;
955 if (!force_size)
956 {
957 if (nGrowBy > 0)
958 {
959 len2 += nGrowBy;
960 len2 = ((len2 - 1) / nGrowBy) * nGrowBy;
961 }
962 else
963 {
964 len2 = pOldBuffer->m_nLength;
965 len2 = len2 + -nGrowBy * len2 / 100;
966 if (len2 < len)
967 {
968 len2 = len;
969 }
970 }
971 }
972 if (may_use_realloc && A::useRealloc() && !empty())
973 {
974 Buffer* pNewBuffer = reinterpret_cast<Buffer*>(::odrxRealloc(
975 pOldBuffer, len2 * sizeof(T) + sizeof(Buffer), pOldBuffer->m_nAllocated * sizeof(T) + sizeof(Buffer)));
976 if (!pNewBuffer)
977 throw OdError(eOutOfMemory);
978 pNewBuffer->m_nAllocated = len2;
979 pNewBuffer->m_nLength = odmin(pNewBuffer->m_nLength, len);
980 m_pData = pNewBuffer->data();
981 }
982 else
983 {
984 Buffer* pNewBuffer = Buffer::allocate(len2, nGrowBy);
985 if (!pNewBuffer)
986 throw OdError(eOutOfMemory);
987 len = odmin(pOldBuffer->m_nLength, len);
988 if (may_use_realloc)
989 A::moveConstructRange(pNewBuffer->data(), pOldBuffer->data(), len);
990 else
991 copyConstructRangeChecked(pNewBuffer->data(), pOldBuffer->data(), len);
992 pNewBuffer->m_nLength = len;
993 m_pData = pNewBuffer->data();
994 if (releaseOldBufAfterCopy)
995 pOldBuffer->release();
996 }
997 }
998 inline void assertValid(size_type index) const
999 {
1000 if(!isValid(index))
1001 {
1002 ODA_FAIL();
1003 throw OdError_InvalidIndex();
1004 }
1005 }
1006 static inline void rise_error(OdResult e)
1007 {
1008 ODA_FAIL();
1009 throw OdError(e);
1010 }
1011public:
1012 // STL-like interface
1013
1018 {
1019 if(!empty())
1020 {
1021 copy_if_referenced();
1022 return data();
1023 }
1024 return 0;
1025 }
1030 {
1031 if(!empty())
1032 {
1033 return data();
1034 }
1035 return 0;
1036 }
1037
1042 {
1043 if(!empty())
1044 {
1045 copy_if_referenced();
1046 return data() + length();
1047 }
1048 return 0;
1049 }
1054 {
1055 if(!empty())
1056 {
1057 return data() + length();
1058 }
1059 return 0;
1060 }
1061
1065 std::reverse_iterator<iterator> rbegin()
1066 {
1067 return std::reverse_iterator<iterator>(end());
1068 }
1072 std::reverse_iterator<const_iterator> rbegin() const
1073 {
1074 return std::reverse_iterator<const_iterator>(end());
1075 }
1076
1080 std::reverse_iterator<iterator> rend()
1081 {
1082 return std::reverse_iterator<iterator>(begin());
1083 }
1087 std::reverse_iterator<const_iterator> rend() const
1088 {
1089 return std::reverse_iterator<const_iterator>(begin());
1090 }
1091
1102 iterator before,
1104 const_iterator afterLast)
1105 {
1106#ifdef ODA_DIAGNOSTICS
1107 if (first >= begin_const() && first < end_const() && before < afterLast)
1108 throw OdError(L"Inserted iterator range will become invalid while inserting.");
1109#endif
1110 size_type len = length();
1111 size_type index = (size_type)(before - begin_const());
1112 if(index <= len && afterLast>=first)
1113 {
1114 if(afterLast > first)
1115 {
1116 size_type num2copy = (size_type)(afterLast - first);
1117 reallocator r( first < begin() || first >= end() );
1118 r.reallocate(this, len + num2copy);
1119 A::defaultConstructFill(m_pData + len, num2copy);
1120 buffer()->m_nLength = len + num2copy;
1121 T* pDestination = m_pData + index;
1122 if (index != len)
1123 {
1124 A::moveAssignRange(pDestination + num2copy, pDestination, len - index);
1125 }
1126 A::copyAssignRangeDisjoint(pDestination, first, (size_type)(afterLast - first));
1127 }
1128 }
1129 else
1130 {
1131 rise_error(eInvalidInput);
1132 }
1133 }
1134
1145 iterator before,
1147 iterator afterLast)
1148 {
1149#ifdef ODA_DIAGNOSTICS
1150 if (first >= begin_const() && first < end_const() && before < afterLast)
1151 throw OdError(L"Inserted iterator range will become invalid while inserting.");
1152#endif
1153 size_type len = length();
1154 size_type index = (size_type)(before - begin_const());
1155 if (index <= len && afterLast >= first)
1156 {
1157 if (afterLast > first)
1158 {
1159 size_type num2copy = (size_type)(afterLast - first);
1160 reallocator r(first < begin() || first >= end());
1161 r.reallocate(this, len + num2copy);
1162 A::defaultConstructFill(m_pData + len, num2copy);
1163 buffer()->m_nLength = len + num2copy;
1164 T* pDestination = m_pData + index;
1165 if (index != len)
1166 {
1167 A::moveAssignRange(pDestination + num2copy, pDestination, len - index);
1168 }
1169 A::moveAssignRange(pDestination, first, (size_type)(afterLast - first));
1170 }
1171 }
1172 else
1173 {
1174 rise_error(eInvalidInput);
1175 }
1176 }
1185 void resize(
1187 const T& value )
1188 {
1189 size_type len = length();
1190 int d = logicalLength - len;
1191 if ( d > 0 )
1192 {
1193 increaseLogicalLength(logicalLength, len, d, value);
1194 }
1195 else if ( d < 0 )
1196 {
1197 d=-d;
1198 if(!referenced())
1199 {
1200 A::destroyRange(m_pData + logicalLength, d);
1201 }
1202 else
1203 {
1204 copy_buffer(logicalLength);
1205 }
1206 }
1207 buffer()->m_nLength = logicalLength;
1208 }
1209
1217 void resize(
1219 {
1220 size_type len = length();
1221 int d = logicalLength - len;
1222 if ( d > 0 )
1223 {
1224 increaseLogicalLength(logicalLength, len, d);
1225 }
1226 else if ( d < 0 )
1227 {
1228 d = -d;
1229 if ( !referenced() )
1230 {
1231 A::destroyRange( m_pData + logicalLength, d );
1232 }
1233 else
1234 {
1235 copy_buffer(logicalLength);
1236 }
1237 }
1238 buffer()->m_nLength = logicalLength;
1239 }
1240
1248 {
1249 return buffer()->m_nLength;
1250 }
1251
1257 bool empty() const
1258 {
1259 return size() == 0;
1260 }
1261
1269 {
1270 return buffer()->m_nAllocated;
1271 }
1272
1282 size_type reserveLength)
1283 {
1284 if(physicalLength() < reserveLength)
1285 {
1286 setPhysicalLength(reserveLength);
1287 }
1288 }
1289
1301 const_iterator afterLast)
1302 {
1303#ifdef ODA_DIAGNOSTICS
1304 //FELIX_CHANGE_BEGIN
1305 // Issue: DESKTOP-205889
1306 // end_const call may change data (via copy_if_referenced) instead of begin_const
1307 // so it's required to call end_const() first
1308 /*
1309 if (first >= begin_const() && first < end_const())
1310 */
1311 if (first < end_const() && first >= begin_const())
1312 //FELIX_CHANGE_END
1313 throw OdError(L"Assignment of a subrange from self is not allowed.");
1314#endif
1315 clear();
1316 if (afterLast < first)
1317 {
1318 rise_error(eInvalidInput);
1319 }
1320 if (afterLast > first)
1321 {
1322 size_type num2copy = (size_type)(afterLast - first);
1323 copy_buffer(num2copy, true);
1324 buffer()->m_nLength = num2copy;
1325 A::copyConstructRange(m_pData, first, (size_type)(afterLast - first));
1326 }
1327 }
1328
1340 iterator afterLast)
1341 {
1342#ifdef ODA_DIAGNOSTICS
1343 //FELIX_CHANGE_BEGIN
1344 // Issue: DESKTOP-205889
1345 // end_const call may change data (via copy_if_referenced) instead of begin_const
1346 // so it's required to call end_const() first
1347 /*
1348 if (first >= begin_const() && first < end_const())
1349 */
1350 if (first < end_const() && first >= begin_const())
1351 //FELIX_CHANGE_END
1352 throw OdError(L"Assignment of a subrange from self is not allowed.");
1353#endif
1354 clear();
1355 if (afterLast < first)
1356 {
1357 rise_error(eInvalidInput);
1358 }
1359 if (afterLast > first)
1360 {
1361 size_type num2move = (size_type)(afterLast - first);
1362 copy_buffer(num2move, true);
1363 buffer()->m_nLength = num2move;
1364 A::moveConstructRange(m_pData, first, (size_type)(afterLast - first));
1365 }
1366 }
1367
1375 iterator first,
1376 iterator afterLast)
1377 {
1378 size_type i = (size_type)(first - begin_const());
1379 if(first != afterLast)
1380 {
1381 removeSubArray(i, (size_type)(afterLast-begin_const()-1));
1382 }
1383 return begin_non_const()+i;
1384 }
1391 iterator where)
1392 {
1393 size_type i = (size_type) (where - begin_const());
1394 removeAt(i);
1395 return begin_non_const()+i;
1396 }
1400 void clear()
1401 {
1402 copy_if_referenced();
1403 size_type len = length();
1404 A::destroyRange(m_pData, len);
1405 buffer()->m_nLength -= len;
1406 }
1407
1412 const T& value)
1413 {
1414 size_type len = length();
1415 size_type newLen = len + 1;
1416 bool ref = referenced();
1417
1418 if (ref || len == physicalLength())
1419 {
1420 T valueCopy(value);
1421 copy_buffer(newLen, !ref);
1422 A::moveConstruct(m_pData + len, std::move(valueCopy));
1423 }
1424 else
1425 {
1426 A::copyConstruct(m_pData + len, value);
1427 }
1428 buffer()->m_nLength = newLen;
1429 }
1430
1435 T&& value)
1436 {
1437 size_type len = length();
1438 size_type newLen = len + 1;
1439 bool ref = referenced();
1440
1441 if (ref || len == physicalLength())
1442 {
1443 T valueMoved(std::move(value));
1444 copy_buffer(newLen, !ref);
1445 A::moveConstruct(m_pData + len, std::move(valueMoved));
1446 }
1447 else
1448 {
1449 A::moveConstruct(m_pData + len, std::move(value));
1450 }
1451 buffer()->m_nLength = newLen;
1452 }
1453
1462 iterator before,
1463 size_type numElements,
1464 const T& value)
1465 {
1466 if (numElements == 0)
1467 {
1468 return before;
1469 }
1470 size_type len = length();
1471 size_type index = (size_type)(before - begin_const());
1472 T tmpval(value);
1473 reallocator r(true);
1474 r.reallocate(this, len + numElements);
1475 A::defaultConstructFill(m_pData + len, numElements);
1476 buffer()->m_nLength = len + numElements;
1477 T* pData = data();
1478 pData += index;
1479 if (index != len)
1480 {
1481 A::moveAssignRange(pData + numElements, pData, len - index);
1482 }
1483 while (numElements-- > 1)
1484 {
1485 pData[numElements] = tmpval;
1486 }
1487 pData[0] = std::move(tmpval);
1488 return begin_non_const()+index;
1489 }
1496 iterator before,
1497 const T& value = T())
1498 {
1499 size_type index = (size_type)(before - begin_const());
1501 return (begin_non_const() + index);
1502 }
1509 iterator before,
1510 T&& value)
1511 {
1512 size_type index = (size_type)(before - begin_const());
1514 return (begin_non_const() + index);
1515 }
1516
1525 const ConstForPtrT& value,
1526 size_type start = 0) const
1527 {
1528 size_type dummy;
1529 return find(value, dummy, start);
1530 }
1531
1538 {
1539 return buffer()->m_nLength;
1540 }
1541
1547 bool isEmpty() const
1548 {
1549 return length() == 0;
1550 }
1551
1559 {
1560 return length();
1561 }
1562
1570 {
1571 return buffer()->m_nAllocated;
1572 }
1573
1580 int growLength() const
1581 {
1582 return buffer()->m_nGrowBy;
1583 }
1584
1590 const T* asArrayPtr() const
1591 {
1592 return data();
1593 }
1594
1600 const T* getPtr() const
1601 {
1602 return data();
1603 }
1604
1611 {
1612 copy_if_referenced();
1613 return data();
1614 }
1615
1619 const T& operator [](
1620 size_type index) const
1621 {
1622 assertValid(index);
1623 return m_pData[index];
1624 }
1630 {
1631 assertValid(index);
1632 copy_if_referenced();
1633 return m_pData[index];
1634 }
1635
1642 T& at(size_type arrayIndex)
1643 {
1644 assertValid(arrayIndex);
1645 copy_if_referenced();
1646 return *(data() + arrayIndex);
1647 }
1648
1655 const T& at(size_type arrayIndex) const
1656 {
1657 assertValid(arrayIndex);
1658 return *(data() + arrayIndex);
1659 }
1660
1669 size_type arrayIndex,
1670 const T& value)
1671 {
1672 assertValid(arrayIndex);
1673 copy_if_referenced();
1674 m_pData[arrayIndex] = value;
1675 return *this;
1676 }
1677
1684 const T& getAt(
1685 size_type arrayIndex) const
1686 {
1687 assertValid(arrayIndex);
1688 return *(data() + arrayIndex);
1689 }
1690
1696 T& first()
1697 {
1698 return *begin();
1699 }
1700 const T& first() const
1701 {
1702 return *begin();
1703 }
1704
1710 T& last()
1711 {
1712 return at(length() - 1);
1713 }
1714 const T& last() const
1715 {
1716 return at(length() - 1);
1717 }
1718
1726 const T& value)
1727 {
1729 return length() - 1;
1730 }
1731
1741 T&& value)
1742 {
1743 return appendMove(value);
1744 }
1745
1763 T& value)
1764 {
1766 if (index > logicalLength())
1767 return *this;
1768 size_type oldLen = logicalLength();
1769 size_type newLen = oldLen + 1;
1770
1771 T tmp(std::move(value));
1772 reallocator r(true);
1773 r.reallocate(this, newLen);
1774 A::moveConstruct(m_pData + oldLen, std::move(tmp));
1775 ++(buffer()->m_nLength);
1776 if (index != oldLen) {
1777 tmp = std::move(*(m_pData + oldLen));
1778 A::moveAssignRange(m_pData + index + 1, m_pData + index, oldLen - index);
1779 *(m_pData + index) = std::move(tmp);
1780 }
1781 return *this;
1782 }
1783
1793 {
1794 push_back(std::move(value));
1795 return logicalLength() - 1;
1796 }
1805 OdArray& otherArray)
1806 {
1807 insertMove(end_non_const(), otherArray.begin(), otherArray.end());
1808 return *this;
1809 }
1810
1821 const T& value,
1822 size_type nCount
1823 )
1824 {
1825 if (nCount <= 0)
1826 return *this;
1827 size_type oldLen = logicalLength();
1828 T tmp(value);
1829 reallocator r(true);
1830 r.reallocate(this, oldLen + nCount);
1831 A::copyConstructFill(m_pData + oldLen, nCount, tmp);
1832 (buffer()->m_nLength) += nCount;
1833 return *this;
1834 }
1835
1844 template<typename... Args>
1846 const Args&... args
1847 )
1848 {
1849 const auto count_elements = sizeof...(Args);
1850 if (count_elements == 0)
1851 {
1852 return *this;
1853 }
1854 size_type oldLen = logicalLength();
1855 Buffer* oldBuf = buffer();
1856
1857 // to support appending values from this array.
1858 // we should release old buffer only after variadicAssignHelper call,
1859 // otherwise default reallocation will cause args to become garbage.
1860 copy_buffer(oldLen + count_elements, false, false, false); // important only last flag
1861 A::defaultConstructFill(m_pData + oldLen, count_elements);
1862
1863 variadicAssignHelper(oldLen, args...);
1864 oldBuf->release();
1865 return *this;
1866 }
1867
1874 {
1875 size_type i = append(T());
1876 return begin_non_const() + i;
1877 }
1878
1885 {
1886 return removeAt(0);
1887 }
1888
1895 {
1896 resize(length() - 1);
1897 return *this;
1898 }
1899
1907 int growLength)
1908 {
1909 if (growLength != 0)
1910 {
1911 copy_if_referenced();
1912 buffer()->m_nGrowBy = growLength;
1913 }
1914 else
1915 {
1916 ODA_FAIL();
1917 }
1918 return *this;
1919 }
1920
1927 explicit OdArray(
1929 int growLength = 8) : m_pData(0)
1930 {
1931 if (growLength == 0)
1932 {
1933 growLength = 8;
1934 }
1935 m_pData = Buffer::allocate(physicalLength, growLength)->data();
1936 }
1937
1938 OdArray() : m_pData(Buffer::_default()->data())
1939 {
1940 buffer()->addref();
1941 }
1942
1943 OdArray(const OdArray& source) : m_pData(const_cast<T*>(source.data()))
1944 {
1945 static_assert(std::is_copy_constructible<T>::value, "Can not copy array with non-copyable argument");
1946 buffer()->addref();
1947 }
1948
1949 OdArray(OdArray&& source) : m_pData(source.m_pData)
1950 {
1951 source.m_pData = Buffer::_default()->data();
1952 source.buffer()->addref();
1953 }
1954
1955 static OdArray<T, A> create(T *sourceArray, int sourceLength)
1956 {
1957 OdArray<T, A> res(sourceLength);
1958 res.assign(sourceArray, sourceArray + sourceLength);
1959 return res;
1960 }
1961
1966 {
1967 buffer()->release();
1968 }
1969
1971 const OdArray& source)
1972 {
1973 static_assert(std::is_copy_constructible<T>::value, "Can not copy array with non-copyable argument");
1974 source.buffer()->addref();
1975 buffer()->release();
1976 m_pData = source.m_pData;
1977 return *this;
1978 }
1979
1981 OdArray&& source)
1982 {
1983 //FELIX_CHANGE_BEGIN
1984 std::swap( m_pData, source.m_pData );
1985 //FELIX_CHANGE_END
1986 return *this;
1987 }
1988
1990 const OdArray& array) const
1991 {
1992 if(length() == array.length())
1993 {
1994 for(size_type i = 0; i < length(); i++)
1995 {
1996 if(at(i) != array[i])
1997 {
1998 return false;
1999 }
2000 }
2001 return true;
2002 }
2003 return false;
2004 }
2005
2007 const OdArray& array) const
2008 {
2009 return !operator == (array);
2010 }
2011
2019 const T& value)
2020 {
2021 copy_if_referenced();
2022 T* pData = data();
2023 size_type n = length();
2024 while(n)
2025 {
2026 pData[--n] = value;
2027 }
2028 return *this;
2029 }
2038 const OdArray& otherArray)
2039 {
2040 insert(end_non_const(), otherArray.begin(), otherArray.end());
2041 return *this;
2042 }
2043
2052 OdArray&& otherArray)
2053 {
2054 appendMove(otherArray);
2055 return *this;
2056 }
2057
2070 size_type arrayIndex,
2071 const T& value)
2072 {
2073 size_type len = length();
2074 if( arrayIndex == len )
2075 {
2077 }
2078 else if ( arrayIndex < len )
2079 {
2080 T tmpval(value);
2081 reallocator r(true);
2082 r.reallocate( this, len+1 );
2083 A::defaultConstruct( m_pData + len );
2084 ++(buffer()->m_nLength);
2085 A::moveAssignRange(m_pData + arrayIndex + 1, m_pData + arrayIndex, len - arrayIndex);
2086 m_pData[arrayIndex] = std::move(tmpval);
2087 }
2088 else
2089 {
2090 rise_error(eInvalidIndex);
2091 }
2092 return *this;
2093 }
2094
2111 T&& val
2112 )
2113 {
2114 return insertAtMove(index, val);
2115 }
2116
2128 size_type arrayIndex)
2129 {
2130 assertValid(arrayIndex);
2131 size_type len = length();
2132 if(arrayIndex < --len)
2133 {
2134 copy_if_referenced();
2135 T* pData = data();
2136 A::moveAssignRange(pData + arrayIndex, pData + arrayIndex + 1, len - arrayIndex);
2137 }
2138 resize(len);
2139 return *this;
2140 }
2141
2152 size_type startIndex,
2153 size_type endIndex)
2154 {
2155 if(!isValid(startIndex) || startIndex > endIndex)
2156 {
2157 rise_error(eInvalidIndex);
2158 }
2159 size_type len = length();
2160 copy_if_referenced();
2161 T* pData = data();
2162 ++endIndex;
2163 size_type n2remove = endIndex - startIndex;
2164 A::moveAssignRange(pData + startIndex, pData + endIndex, len - endIndex);
2165 A::destroyRange(pData + len - n2remove, n2remove);
2166 buffer()->m_nLength -= n2remove;
2167 return *this;
2168 }
2169
2178 bool find(
2179 const ConstForPtrT& value,
2180 size_type& findIndex,
2181 size_type start = 0) const
2182 {
2183 if (!empty())
2184 {
2185 assertValid(start);
2186 size_type len = length();
2187 const T* pData = data();
2188 for (size_type i = start; i < len; ++i)
2189 {
2190 if (pData[i] == value)
2191 {
2192 findIndex = i;
2193 return true;
2194 }
2195 }
2196 }
2197 return false;
2198 }
2199
2209 size_type logLength)
2210 {
2211 resize(logLength);
2212 return *this;
2213 }
2214
2224 size_type physLength)
2225 {
2226 if(physLength==0)
2227 {
2228 *this = OdArray<T, A>();
2229 }
2230 else if(physLength != physicalLength())
2231 {
2232 copy_buffer(physLength, !referenced(), true);
2233 }
2234 return *this;
2235 }
2236
2243 {
2244 if(!empty())
2245 {
2246 copy_if_referenced();
2247 T tmp;
2248 iterator iter1 = begin_non_const();
2249 iterator iter2 = end_non_const();
2250 --iter2;
2251 while(iter1 < iter2)
2252 {
2253 tmp = *iter1;
2254 *iter1 = *iter2;
2255 *iter2 = tmp;
2256 ++iter1;
2257 --iter2;
2258 }
2259 }
2260 return *this;
2261 }
2262
2271 size_type firstIndex,
2272 size_type secondIndex)
2273 {
2274 if(!isValid(firstIndex) || !isValid(secondIndex))
2275 {
2276 rise_error(eInvalidIndex);
2277 }
2278 if(firstIndex != secondIndex)
2279 {
2280 T tmp = std::move(at(firstIndex));
2281 at(firstIndex) = std::move(at(secondIndex));
2282 at(secondIndex) = std::move(tmp);
2283 }
2284 return *this;
2285 }
2286
2292 void swap(
2293 OdArray &other)
2294 {
2295 T *temp = m_pData;
2296 m_pData = other.m_pData;
2297 other.m_pData = temp;
2298 }
2299
2310 const T& value,
2311 size_type start = 0)
2312 {
2313 size_type i = 0;
2314 if(find(value, i, start))
2315 {
2316 removeAt(i);
2317 return true;
2318 }
2319 return false;
2320 }
2321private:
2322
2323 T* m_pData;
2324
2325 bool isValid(size_type i) const
2326 {
2327 return (i < length());
2328 }
2329
2330 T* data()
2331 {
2332 return (length() ? m_pData : 0);
2333 }
2334
2335 const T* data() const
2336 {
2337 return m_pData;
2338 }
2339
2340 Buffer* buffer() const
2341 {
2342 return (reinterpret_cast<Buffer*>(const_cast<OdArray*>(this)->m_pData) - 1);
2343 }
2344 bool referenced() const
2345 {
2346 return (buffer()->m_nRefCounter>1);
2347 }
2348
2349 // to support appendList() call without args
2350 OdArray& variadicAssignHelper(
2351 size_type
2352 )
2353 {
2354 return *this;
2355 }
2356
2357 // called when last value is to be assigned
2358 OdArray& variadicAssignHelper(
2360 const T& value
2361 )
2362 {
2363 m_pData[index] = value;
2364 ++(buffer()->m_nLength);
2365 return *this;
2366 }
2367
2368 template<typename... Args>
2369 OdArray& variadicAssignHelper(
2371 const T& value,
2372 const Args&... args
2373 )
2374 {
2375 variadicAssignHelper(index, value);
2376 return variadicAssignHelper(index + 1, args...);
2377 }
2378
2379// FELIX_CHANGE_BEGIN
2380#if !defined(SWIG) || defined(SWIGBUILD)
2381// FELIX_CHANGE_END
2382 template<typename U = T,
2383 typename std::enable_if<std::is_same<U, T>::value && !std::is_move_assignable<U>::value, bool>::type = true>
2384 void increaseLogicalLength(
2385 size_type,
2386 size_type,
2387 int,
2388 const T&)
2389 {
2390 throw OdError(eNotApplicable);
2391 }
2392
2393 template<typename U = T,
2394 typename std::enable_if<std::is_same<U, T>::value && std::is_move_assignable<U>::value, bool>::type = true>
2395 void increaseLogicalLength(
2397 size_type len,
2398 int d,
2399 const T& value)
2400 {
2401 reallocator r(m_pData > &value || &value > (m_pData + len));
2402 r.reallocate(this, logicalLength);
2403 A::copyConstructFill(m_pData + len, d, value);
2404 }
2405
2406 template<typename U = T,
2407 typename std::enable_if<std::is_same<U, T>::value && !std::is_default_constructible<U>::value, bool>::type = true>
2408 void increaseLogicalLength(
2409 size_type,
2410 size_type,
2411 int)
2412 {
2413 throw OdError(eNotApplicable);
2414 }
2415
2416 template<typename U = T,
2417 typename std::enable_if<std::is_same<U, T>::value && std::is_default_constructible<U>::value, bool>::type = true>
2418 void increaseLogicalLength(
2420 size_type len,
2421 int d)
2422 {
2423 copy_before_write(len + d, true);
2424 A::defaultConstructFill(m_pData + len, d);
2425 }
2426#endif
2427};
2428
2429#include "TD_PackPop.h"
2430
2431#endif // ODARRAY_H_INCLUDED
2432// FELIX_CHANGE_END file was take from ODA gitlab repository https://gitlab.opendesign.com/
#define ODA_ASSERT_ONCE(exp)
Definition: DebugStuff.h:73
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:57
#define ODA_FAIL()
Definition: DebugStuff.h:88
false
Definition: DimVarDefs.h:165
ALLOCDLL_EXPORT void * odrxRealloc(void *pMemBlock, size_t newSize, size_t oldSize)
ALLOCDLL_EXPORT void * odrxAlloc(size_t nBytes)
ALLOCDLL_EXPORT void odrxFree(void *pMemBlock)
int OdRefCounter
Definition: OdMutex.h:487
#define odmin(X, Y)
Definition: OdPlatform.h:34
OdResult
Definition: OdResult.h:29
#define FIRSTDLL_EXPORT
Definition: RootExport.h:39
#define FIRSTDLL_EXPORT_STATIC
Definition: RootExport.h:40
const T * asArrayPtr() const
Definition: OdArray.h:1590
OdArray & appendMove(OdArray &otherArray)
Definition: OdArray.h:1804
T * asArrayPtr()
Definition: OdArray.h:1610
~OdArray()
Definition: OdArray.h:1965
OdArray & insertAtMove(size_type index, T &value)
Definition: OdArray.h:1761
void clear()
Definition: OdArray.h:1400
size_type capacity() const
Definition: OdArray.h:1268
OdArray & removeFirst()
Definition: OdArray.h:1884
OdArray & swap(size_type firstIndex, size_type secondIndex)
Definition: OdArray.h:2270
const T & getAt(size_type arrayIndex) const
Definition: OdArray.h:1684
bool operator==(const OdArray &array) const
Definition: OdArray.h:1989
iterator end()
Definition: OdArray.h:1041
const T & operator[](size_type index) const
Definition: OdArray.h:1619
void swap(OdArray &other)
Definition: OdArray.h:2292
const_iterator end() const
Definition: OdArray.h:1053
void assign(const_iterator first, const_iterator afterLast)
Definition: OdArray.h:1299
size_type physicalLength() const
Definition: OdArray.h:1569
std::reverse_iterator< const_iterator > rbegin() const
Definition: OdArray.h:1072
iterator insert(iterator before, T &&value)
Definition: OdArray.h:1508
OdArray & reverse()
Definition: OdArray.h:2242
std::reverse_iterator< const_iterator > rend() const
Definition: OdArray.h:1087
OdArray & setAll(const T &value)
Definition: OdArray.h:2018
bool operator!=(const OdArray &array) const
Definition: OdArray.h:2006
bool empty() const
Definition: OdArray.h:1257
OdArray(size_type physicalLength, int growLength=8)
Definition: OdArray.h:1927
void resize(size_type logicalLength)
Definition: OdArray.h:1217
void insertMove(iterator before, iterator first, iterator afterLast)
Definition: OdArray.h:1144
OdArray & operator=(const OdArray &source)
Definition: OdArray.h:1970
T & reference
Definition: OdArray.h:836
OdArray & append(const OdArray &otherArray)
Definition: OdArray.h:2037
void push_back(T &&value)
Definition: OdArray.h:1434
bool contains(const ConstForPtrT &value, size_type start=0) const
Definition: OdArray.h:1524
T & first()
Definition: OdArray.h:1696
OdArray & setPhysicalLength(size_type physLength)
Definition: OdArray.h:2223
OdArray & setGrowLength(int growLength)
Definition: OdArray.h:1906
iterator erase(iterator where)
Definition: OdArray.h:1390
OdArray(const OdArray &source)
Definition: OdArray.h:1943
size_type length() const
Definition: OdArray.h:1537
typename std::conditional< std::is_pointer< T >::value, typename std::add_const< typename std::remove_pointer< T >::type >::type *, T >::type ConstForPtrT
Definition: OdArray.h:838
OdArray & removeLast()
Definition: OdArray.h:1894
bool isEmpty() const
Definition: OdArray.h:1547
size_type size() const
Definition: OdArray.h:1247
OdArray(OdArray &&source)
Definition: OdArray.h:1949
bool find(const ConstForPtrT &value, size_type &findIndex, size_type start=0) const
Definition: OdArray.h:2178
void push_back(const T &value)
Definition: OdArray.h:1411
OdArray & setAt(size_type arrayIndex, const T &value)
Definition: OdArray.h:1668
size_type logicalLength() const
Definition: OdArray.h:1558
const T & const_reference
Definition: OdArray.h:835
OdArray()
Definition: OdArray.h:1938
size_type append(T &&value)
Definition: OdArray.h:1740
OdArray & appendList(const Args &... args)
Definition: OdArray.h:1845
iterator begin()
Definition: OdArray.h:1017
OdArray & appendRep(const T &value, size_type nCount)
Definition: OdArray.h:1820
const T & last() const
Definition: OdArray.h:1714
void reserve(size_type reserveLength)
Definition: OdArray.h:1281
void insert(iterator before, const_iterator first, const_iterator afterLast)
Definition: OdArray.h:1101
const T & at(size_type arrayIndex) const
Definition: OdArray.h:1655
std::reverse_iterator< iterator > rend()
Definition: OdArray.h:1080
OdArray & setLogicalLength(size_type logLength)
Definition: OdArray.h:2208
const T & first() const
Definition: OdArray.h:1700
typename A::size_type size_type
Definition: OdArray.h:831
OdArray & removeSubArray(size_type startIndex, size_type endIndex)
Definition: OdArray.h:2151
OdArray & append(OdArray &&otherArray)
Definition: OdArray.h:2051
iterator erase(iterator first, iterator afterLast)
Definition: OdArray.h:1374
iterator insert(iterator before, size_type numElements, const T &value)
Definition: OdArray.h:1461
T & at(size_type arrayIndex)
Definition: OdArray.h:1642
T value_type
Definition: OdArray.h:834
void assignMove(iterator first, iterator afterLast)
Definition: OdArray.h:1338
const T * const_iterator
Definition: OdArray.h:833
const T * getPtr() const
Definition: OdArray.h:1600
iterator append()
Definition: OdArray.h:1873
static OdArray< T, A > create(T *sourceArray, int sourceLength)
Definition: OdArray.h:1955
OdArray & insertAt(size_type index, T &&val)
Definition: OdArray.h:2109
OdArray & removeAt(size_type arrayIndex)
Definition: OdArray.h:2127
T & last()
Definition: OdArray.h:1710
friend class reallocator
Definition: OdArray.h:920
size_type appendMove(T &value)
Definition: OdArray.h:1792
OdArray & insertAt(size_type arrayIndex, const T &value)
Definition: OdArray.h:2069
void resize(size_type logicalLength, const T &value)
Definition: OdArray.h:1185
size_type append(const T &value)
Definition: OdArray.h:1725
int growLength() const
Definition: OdArray.h:1580
iterator insert(iterator before, const T &value=T())
Definition: OdArray.h:1495
std::reverse_iterator< iterator > rbegin()
Definition: OdArray.h:1065
bool remove(const T &value, size_type start=0)
Definition: OdArray.h:2309
T * iterator
Definition: OdArray.h:832
const_iterator begin() const
Definition: OdArray.h:1029
unsigned int size_type
Definition: OdArray.h:346
static void defaultConstructFill(T *pDestination, size_type numElements)
Definition: OdArray.h:388
static void copyConstructFill(T *pDestination, size_type numElements, const T &value)
Definition: OdArray.h:355
static void copyConstructRange(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:370
static void moveAssignRange(T *pDestination, T *pSource, size_type numElements)
Definition: OdArray.h:150
static void defaultConstructFill(T *pDestination, size_type numElements)
Definition: OdArray.h:292
static void defaultConstruct(T *pElement)
Definition: OdArray.h:172
static void moveConstruct(T *pElement, T &&value)
Definition: OdArray.h:216
static void copyConstruct(T *pElement, const T &value)
Definition: OdArray.h:187
static void destroy(T *pObject)
Definition: OdArray.h:304
unsigned int size_type
Definition: OdArray.h:90
static void copyAssignRangeDisjoint(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:103
static bool useRealloc()
Definition: OdArray.h:328
static void copyConstructRange(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:259
static void copyConstructFill(T *pDestination, size_type numElements, const T &value)
Definition: OdArray.h:235
static void copyAssignRange(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:127
static void moveConstructRange(T *pDestination, T *pSource, size_type numElements)
Definition: OdArray.h:274
static void destroyRange(T *objects, size_type numObjects)
Definition: OdArray.h:316
static void moveAssignRange(T *pDestination, T *pSource, size_type numElements)
Definition: OdArray.h:483
static void copyConstructRange(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:601
static void defaultConstructFill(T *pDestination, size_type numElements)
Definition: OdArray.h:584
static void copyConstructFill(T *pDestination, size_type numElements, const T &value)
Definition: OdArray.h:563
unsigned int size_type
Definition: OdArray.h:418
static void moveConstructRange(T *pDestination, T *pSource, size_type numElements)
Definition: OdArray.h:621
static void copyAssignRange(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:455
static void defaultConstruct(T *pElement)
Definition: OdArray.h:515
static void destroyRange(T *objects, size_type numObjects)
Definition: OdArray.h:652
static bool useRealloc()
Definition: OdArray.h:670
static void destroy(T *pObject)
Definition: OdArray.h:639
static void copyConstruct(T *pElement, const T &value)
Definition: OdArray.h:530
static void moveConstruct(T *pElement, T &&value)
Definition: OdArray.h:546
static void copyAssignRangeDisjoint(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:431
static void copyAssignRangeDisjoint(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:705
unsigned int size_type
Definition: OdArray.h:692
static void moveAssignRange(T *pDestination, T *pSource, size_type numElements)
Definition: OdArray.h:754
static bool useRealloc()
Definition: OdArray.h:776
static void copyAssignRange(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:730
GLenum GLint ref
Definition: gles2_ext.h:262
GLuint buffer
Definition: gles2_ext.h:178
GLint GLenum GLsizei GLsizei GLint GLsizei const void * data
Definition: gles2_ext.h:110
GLuint index
Definition: gles2_ext.h:265
GLsizei GLsizei GLchar * source
Definition: gles2_ext.h:282
GLuint GLsizei GLsizei GLint GLenum * type
Definition: gles2_ext.h:274
GLsizei const GLfloat * value
Definition: gles2_ext.h:302
static FIRSTDLL_EXPORT_STATIC OdArrayBuffer g_empty_array_buffer
Definition: OdArray.h:795
size_type m_nLength
Definition: OdArray.h:793
unsigned int size_type
Definition: OdArray.h:788
int m_nGrowBy
Definition: OdArray.h:791
OdRefCounter m_nRefCounter
Definition: OdArray.h:790
size_type m_nAllocated
Definition: OdArray.h:792