CFx SDK Documentation 2026 SP0
Loading...
Searching...
No Matches
OdArray.h
Go to the documentation of this file.
1
2// Copyright (C) 2002-2024, Open Design Alliance (the "Alliance").
3// All rights reserved.
4//
5// This software and its documentation and related materials are owned by
6// the Alliance. The software may only be incorporated into application
7// programs owned by members of the Alliance, subject to a signed
8// Membership Agreement and Supplemental Software License Agreement with the
9// Alliance. The structure and organization of this software are the valuable
10// trade secrets of the Alliance and its suppliers. The software is also
11// protected by copyright law and international treaty provisions. Application
12// programs incorporating this software must include the following statement
13// with their copyright notices:
14//
15// This application incorporates Open Design Alliance software pursuant to a license
16// agreement with Open Design Alliance.
17// Open Design Alliance Copyright (C) 2002-2024 by Open Design Alliance.
18// All rights reserved.
19//
20// By use of this software, its documentation or related materials, you
21// acknowledge and accept the above terms.
23
24
25
26
27#ifndef ODARRAY_H_INCLUDED
28#define ODARRAY_H_INCLUDED
29
30#include <new>
31#include <utility>
32
33#include "TD_PackPush.h"
34
35#include "OdArrayPreDef.h"
36#include "OdHeap.h"
37#include "OdMutex.h"
38#include "OdError.h"
39#include "RxSystemServices.h"
40#include <iterator>
41#include <algorithm>
42#include <type_traits>
43#include <initializer_list>
44
45template<class T>
47{
48 static const bool value = false;
49};
50
51template <class First, class Second>
52struct OdIsTriviallyCopyablePair <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
66template <class T> class OdMemoryAllocator
67{
68public:
69 typedef unsigned int size_type;
70
82 static inline void copyAssignRangeDisjoint(
83 T* pDestination,
84 const T* pSource,
85 size_type numElements)
86 {
87 // FELIX_CHANGE_BEGIN
88 #if defined (_MSC_VER) && defined(_DEBUG)
89 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
90 #endif
91 // FELIX_CHANGE_END
92 memcpy(pDestination, pSource, numElements * sizeof(T));
93 }
94
106 static inline void copyAssignRange(
107 T* pDestination,
108 const T* pSource,
109 size_type numElements)
110 {
111 // FELIX_CHANGE_BEGIN
112 #if defined (_MSC_VER) && defined(_DEBUG)
113 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
114 #endif
115 // FELIX_CHANGE_END
116 memmove(pDestination, pSource, numElements * sizeof(T));
117 }
118
129 static inline void moveAssignRange(
130 T* pDestination,
131 T* pSource,
132 size_type numElements)
133 {
134 // FELIX_CHANGE_BEGIN
135 #if defined (_MSC_VER) && defined(_DEBUG)
136 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
137 #endif
138 // FELIX_CHANGE_END
139 memmove(pDestination, pSource, numElements * sizeof(T));
140 }
141
151 static inline void defaultConstruct(
152 T* /*pElement*/)
153 {
154 // DOES NOTHING
155 }
156
163 static inline void copyConstruct(
164 T* pElement,
165 const T& value)
166 {
167 // FELIX_CHANGE_BEGIN
168 #if defined (_MSC_VER) && defined(_DEBUG)
169 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
170 #endif
171#if defined(__GNUC__) && (__GNUC__ > 4)
172 // The below memcpy may cause warnings and errors, when pushing elements to an empty array. Disable for now.
173#pragma GCC diagnostic push
174#pragma GCC diagnostic ignored "-Warray-bounds"
175#pragma GCC diagnostic ignored "-Wstringop-overflow"
176#endif
177 // FELIX_CHANGE_END
178 memcpy(pElement, std::addressof(value), sizeof(value));
179 // FELIX_CHANGE_BEGIN
180#if defined(__GNUC__) && (__GNUC__ > 4)
181#pragma GCC diagnostic pop
182#endif
183 // FELIX_CHANGE_END
184 }
185
192 static inline void moveConstruct(
193 T* pElement,
194 T&& value)
195 {
196 // FELIX_CHANGE_BEGIN
197 #if defined (_MSC_VER) && defined(_DEBUG)
198 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
199 #endif
200 // FELIX_CHANGE_END
201 memmove(pElement, std::addressof(value), sizeof(value));
202 }
203
210 template <class... Args>
211 static inline void construct(
212 T* pDestination,
213 Args&&... args)
214 {
215 ::new (pDestination) T(std::forward<Args>(args)...);
216 }
217
225 static inline void copyConstructFill(
226 T* pDestination,
227 size_type numElements,
228 const T& value)
229 {
230 // FELIX_CHANGE_BEGIN
231 #if defined (_MSC_VER) && defined(_DEBUG)
232 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
233 #endif
234 // FELIX_CHANGE_END
235 while(numElements--)
236 {
237 memcpy(pDestination + numElements, std::addressof(value), sizeof(value));
238 }
239 }
240
248 static inline void copyConstructRange(
249 T* pDestination,
250 const T* pSource,
251 size_type numElements)
252 {
253 copyAssignRangeDisjoint(pDestination, pSource, numElements);
254 }
255
263 static inline void moveConstructRange(
264 T* pDestination,
265 T* pSource,
266 size_type numElements)
267 {
268 copyAssignRangeDisjoint(pDestination, pSource, numElements);
269 }
270
281 static inline void defaultConstructFill(
282 T* /*pDestination*/,
283 size_type /*numElements*/)
284 {
285 // DOES NOTHING
286 }
287
293 static inline void destroy(
294 T* pObject)
295 {
296 // DOES NOTHING
297 }
298
305 static inline void destroyRange(
306 T* /*objects*/,
307 size_type /*numObjects*/)
308 {
309 // DOES NOTHING
310 }
311
317 static inline bool useRealloc()
318 {
319 return true;
320 }
321};
322
323
332template <class T> class OdClrMemAllocator : public OdMemoryAllocator<T>
333{
334public:
335 typedef unsigned int size_type;
336
344 static inline void copyConstructFill(
345 T* pDestination,
346 size_type numElements,
347 const T& value)
348 {
349 OdMemoryAllocator<T>::copyConstructFill(pDestination, numElements, value);
350 }
351
359 static inline void copyConstructRange(
360 T* pDestination,
361 const T* pSource,
362 size_type numElements)
363 {
364 OdMemoryAllocator<T>::copyConstructRange(pDestination, pSource, numElements);
365 }
366
376 static inline void defaultConstruct(
377 T* pElement)
378 {
379 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
380 memset(pElement, 0, sizeof(T));
381 }
382
393 static inline void defaultConstructFill(
394 T* pDestination,
395 size_type numElements)
396 {
397 // FELIX_CHANGE_BEGIN
398 #if defined (_MSC_VER) && defined(_DEBUG)
399 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
400 #endif
401 // FELIX_CHANGE_END
402 memset(pDestination, 0, numElements * sizeof(T));
403 }
404};
405
406
419template <class T> class OdObjectsAllocator
420{
421public:
422 typedef unsigned int size_type;
423
435 static inline void copyAssignRangeDisjoint(
436 T* pDestination,
437 const T* pSource,
438 size_type numElements)
439 {
440 while(numElements--)
441 {
442 *pDestination = *pSource;
443 pDestination++;
444 pSource++;
445 }
446 }
447
459 static inline void copyAssignRange(
460 T* pDestination,
461 const T* pSource,
462 size_type numElements)
463 {
464 if (pDestination <= pSource || pDestination >= pSource + numElements)
465 {
466 copyAssignRangeDisjoint(pDestination, pSource, numElements);
467 }
468 else
469 {
470 while(numElements--)
471 {
472 pDestination[numElements] = pSource[numElements];
473 }
474 }
475 }
476
487 static inline void moveAssignRange(
488 T* pDestination,
489 T* pSource,
490 size_type numElements)
491 {
492 if (pDestination <= pSource || pDestination >= pSource + numElements)
493 {
494 while(numElements--)
495 {
496 *pDestination = std::move(*pSource);
497 pDestination++;
498 pSource++;
499 }
500 }
501 else
502 {
503 while(numElements--)
504 {
505 pDestination[numElements] = std::move(pSource[numElements]);
506 }
507 }
508 }
509
519 static inline void defaultConstruct(
520 T* pElement)
521 {
522 ::new (pElement) T;
523 }
524
531 static inline void copyConstruct(
532 T* pElement,
533 const T& value)
534 {
535 ::new (pElement) T(value);
536 }
537
544 static inline void moveConstruct(
545 T* pElement,
546 T&& value)
547 {
548 ::new (pElement) T(std::move(value));
549 }
550
557 template <class... Args>
558 static inline void construct(
559 T* pDestination,
560 Args&&... args)
561 {
562 ::new (pDestination) T(std::forward<Args>(args)...);
563 }
564
572 static inline void copyConstructFill(
573 T* pDestination,
574 size_type numElements,
575 const T& value)
576 {
577 while(numElements--)
578 {
579 copyConstruct(pDestination+numElements, value);
580 }
581 }
582
593 static inline void defaultConstructFill(
594 T* pDestination,
595 size_type numElements)
596 {
597 while(numElements--)
598 {
599 defaultConstruct(pDestination+numElements);
600 }
601 }
602
610 static inline void copyConstructRange(
611 T* pDestination,
612 const T* pSource,
613 size_type numElements)
614 {
615 while(numElements--)
616 {
617 copyConstruct(pDestination, *pSource);
618 pDestination++;
619 pSource++;
620 }
621 }
622
630 static inline void moveConstructRange(
631 T* pDestination,
632 T* pSource,
633 size_type numElements)
634 {
635 while(numElements--)
636 {
637 moveConstruct(pDestination, std::move(*pSource));
638 pDestination++;
639 pSource++;
640 }
641 }
642
648 static inline void destroy(
649 T* pObject)
650 {
651 pObject->~T();
652 pObject = 0;
653 }
654
661 static inline void destroyRange(
662 T* objects,
663 size_type numObjects)
664 {
665 while(numObjects--)
666 {
667 destroy(objects + numObjects);
668 }
669 }
670
679 static inline bool useRealloc()
680 {
681 return false;
682 }
683};
684
685
698template <class T> class OdPlainObjectsAllocator : public OdObjectsAllocator<T>
699{
700public:
701 typedef unsigned int size_type;
702
714 static inline void copyAssignRangeDisjoint(
715 T* pDestination,
716 const T* pSource,
717 size_type numElements)
718 {
719 // FELIX_CHANGE_BEGIN
720 #if defined (_MSC_VER) && defined(_DEBUG)
721 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
722 #endif
723 // FELIX_CHANGE_END
724 memcpy(pDestination, pSource, numElements * sizeof(T));
725 }
726
738 static inline void copyAssignRange(
739 T* pDestination,
740 const T* pSource,
741 size_type numElements)
742 {
743 // FELIX_CHANGE_BEGIN
744 #if defined (_MSC_VER) && defined(_DEBUG)
745 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
746 #endif
747 // FELIX_CHANGE_END
748 memmove(pDestination, pSource, numElements * sizeof(T));
749 }
750
761 static inline void moveAssignRange(
762 T* pDestination,
763 T* pSource,
764 size_type numElements)
765 {
766 // FELIX_CHANGE_BEGIN
767 #if defined (_MSC_VER) && defined(_DEBUG)
768 ODA_ASSERT_ONCE(std::is_trivially_copyable<T>::value || OdIsTriviallyCopyablePair<T>::value);
769 #endif
770 // FELIX_CHANGE_END
771 memmove(pDestination, pSource, numElements * sizeof(T));
772 }
773
782 static inline bool useRealloc()
783 {
784 return true;
785 }
786};
787
803
804
805
834template <class T, class A> class OdArray
835{
836public:
837 using size_type = typename A::size_type;
838 using iterator = T*;
839 using const_iterator = const T*;
840 using value_type = T;
841 using const_reference = const T&;
842 using reference = T&;
843 using ConstForPtrT = typename std::conditional<std::is_pointer<T>::value,
844 typename std::add_const<typename std::remove_pointer<T>::type>::type*, T>::type;
845private:
846 struct Buffer : OdArrayBuffer
847 {
848 const T* data() const { return reinterpret_cast<const T*>(this+1); }
849 T* data() { return reinterpret_cast<T*>(this + 1); }
850
851 static Buffer* allocate(size_type nLength2Allocate, int nGrowBy)
852 {
853 OdUInt64 nBytes2Allocate = (OdUInt64)sizeof(Buffer) + nLength2Allocate * sizeof(T);
854 ODA_ASSERT(nBytes2Allocate > nLength2Allocate); // size_type overflow
855 size_t nBytes2AllocateSize_t = (size_t)nBytes2Allocate;//size_t overflow on x32
856 if(nBytes2Allocate > nLength2Allocate && (OdUInt64)nBytes2AllocateSize_t == nBytes2Allocate)
857 {
858 Buffer* pBuffer = (Buffer*)::odrxAlloc(nBytes2AllocateSize_t);
859 if (pBuffer)
860 {
861 pBuffer->m_nRefCounter = 1;
862 pBuffer->m_nGrowBy = nGrowBy;
863 pBuffer->m_nAllocated = nLength2Allocate;
864 pBuffer->m_nLength = 0;
865 return pBuffer;
866 }
867 }
868 throw OdError(eOutOfMemory);
869 }
870 static Buffer* _default()
871 {
872 return reinterpret_cast<Buffer*>(&g_empty_array_buffer);
873 }
874 void release()
875 {
877 if((--m_nRefCounter)==0 && this != _default())
878 {
879 A::destroyRange(data(), m_nLength);
880 ::odrxFree(this);
881 }
882 }
883 void addref() const { ++m_nRefCounter; }
884 };
885#if defined(_MSC_VER)
886#pragma warning(disable : 4127) // conditional expression is constant
887#pragma warning(push)
888#endif
889 class reallocator
890 {
891 bool _may_use_realloc;
892 Buffer* m_pBuffer;
893 public:
894 inline reallocator( bool may_use_realloc = false ) : _may_use_realloc(may_use_realloc), m_pBuffer(NULL) {}
895 inline void reallocate(OdArray* pArray, size_type nNewLen)
896 {
897 if(!pArray->referenced())
898 {
899 if(nNewLen > pArray->physicalLength())
900 {
901 if ( !_may_use_realloc )
902 {
903 if (m_pBuffer)
904 m_pBuffer->release();
905 if (!std::is_copy_constructible<T>::value)
906 throw OdError(eNotApplicable); //trying to copy buffer for non-copyable T!
907 m_pBuffer = pArray->buffer();
908 m_pBuffer->addref(); // save buffer to ensure copy from itself would work (e.g insertAt)
909 }
910 pArray->copy_buffer(nNewLen, _may_use_realloc);
911 }
912 }
913 else
914 {
915 pArray->copy_buffer(nNewLen);
916 }
917 }
918 inline ~reallocator()
919 {
920 if (m_pBuffer)
921 m_pBuffer->release();
922 }
923 };
924#if defined(_MSC_VER)
925#pragma warning(pop)
926#endif
927 friend class reallocator;
928 const_iterator begin_const() const { return begin(); }
929 iterator begin_non_const() { return begin(); }
930 const_iterator end_const() const { return end(); }
931 iterator end_non_const() { return end(); }
932 void copy_before_write(size_type len, bool may_use_realloc = false )
933 {
934 if( referenced() )
935 copy_buffer(len);
936 else if ( len > physicalLength() )
937 copy_buffer( len, may_use_realloc );
938 }
939 void copy_if_referenced() { if(referenced()) { copy_buffer(physicalLength()); } }
940// FELIX_CHANGE_BEGIN
941#if !defined(SWIG) || defined(SWIGBUILD)
942// FELIX_CHANGE_END
943 template<typename U = T,
944 typename std::enable_if<std::is_same<U, T>::value && std::is_copy_constructible<U>::value, bool>::type = true>
945 inline void copyConstructRangeChecked(T* dest, T* source, size_type len)
946 {
947 A::copyConstructRange(dest, source, len);
948 }
949 template<typename U = T,
950 typename std::enable_if<std::is_same<U, T>::value && !std::is_copy_constructible<U>::value, bool>::type = true>
951 inline void copyConstructRangeChecked(T* dest, T* source, size_type len)
952 {
953 if (len != 0)
954 throw OdError(eNotApplicable); //trying to copy buffer for non-copyable T (should never be here)!
955 }
956#endif
957 void copy_buffer(size_type len, bool may_use_realloc = false, bool force_size = false, bool releaseOldBufAfterCopy = true)
958 {
959 Buffer* pOldBuffer = buffer();
960 int nGrowBy = pOldBuffer->m_nGrowBy;
961 size_type len2 = len;
962 if (!force_size)
963 {
964 if (nGrowBy > 0)
965 {
966 len2 += nGrowBy;
967 len2 = ((len2 - 1) / nGrowBy) * nGrowBy;
968 }
969 else
970 {
971 len2 = pOldBuffer->m_nLength;
972 len2 = len2 + -nGrowBy * len2 / 100;
973 if (len2 < len)
974 {
975 len2 = len;
976 }
977 }
978 }
979 if (may_use_realloc && A::useRealloc() && !empty())
980 {
981 Buffer* pNewBuffer = reinterpret_cast<Buffer*>(::odrxRealloc(
982 pOldBuffer, len2 * sizeof(T) + sizeof(Buffer), pOldBuffer->m_nAllocated * sizeof(T) + sizeof(Buffer)));
983 if (!pNewBuffer)
984 throw OdError(eOutOfMemory);
985 pNewBuffer->m_nAllocated = len2;
986 pNewBuffer->m_nLength = odmin(pNewBuffer->m_nLength, len);
987 m_pData = pNewBuffer->data();
988 }
989 else
990 {
991 Buffer* pNewBuffer = Buffer::allocate(len2, nGrowBy);
992 if (!pNewBuffer)
993 throw OdError(eOutOfMemory);
994 len = odmin(pOldBuffer->m_nLength, len);
995 if (may_use_realloc)
996 A::moveConstructRange(pNewBuffer->data(), pOldBuffer->data(), len);
997 else
998 copyConstructRangeChecked(pNewBuffer->data(), pOldBuffer->data(), len);
999 pNewBuffer->m_nLength = len;
1000 m_pData = pNewBuffer->data();
1001 if (releaseOldBufAfterCopy)
1002 pOldBuffer->release();
1003 }
1004 }
1005 inline void assertValid(size_type index) const
1006 {
1007 if(!isValid(index))
1008 {
1009 ODA_FAIL();
1010 throw OdError_InvalidIndex();
1011 }
1012 }
1013 static inline void rise_error(OdResult e)
1014 {
1015 ODA_FAIL();
1016 throw OdError(e);
1017 }
1018public:
1019 // STL-like interface
1020
1025 {
1026 if (!empty())
1027 {
1028 copy_if_referenced();
1029 return data();
1030 }
1031 return nullptr;
1032 }
1033
1037 {
1038 if (!empty())
1039 {
1040 return data();
1041 }
1042 return nullptr;
1043 }
1044
1049 {
1050 if (!empty())
1051 {
1052 copy_if_referenced();
1053 return data() + length();
1054 }
1055 return nullptr;
1056 }
1057
1061 {
1062 if (!empty())
1063 {
1064 return data() + length();
1065 }
1066 return nullptr;
1067 }
1068
1072 std::reverse_iterator<iterator> rbegin()
1073 {
1074 return std::reverse_iterator<iterator>(end());
1075 }
1076
1079 std::reverse_iterator<const_iterator> rbegin() const
1080 {
1081 return std::reverse_iterator<const_iterator>(end());
1082 }
1083
1087 std::reverse_iterator<iterator> rend()
1088 {
1089 return std::reverse_iterator<iterator>(begin());
1090 }
1091
1094 std::reverse_iterator<const_iterator> rend() const
1095 {
1096 return std::reverse_iterator<const_iterator>(begin());
1097 }
1098
1109 iterator before,
1111 const_iterator afterLast)
1112 {
1113#ifdef ODA_DIAGNOSTICS
1114 if (first >= begin_const() && first < end_const() && before < afterLast)
1115 throw OdError(L"Inserted iterator range will become invalid while inserting.");
1116#endif
1117 size_type len = length();
1118 size_type index = (size_type)(before - begin_const());
1120 {
1121 if(afterLast > first)
1122 {
1123 size_type num2copy = (size_type)(afterLast - first);
1124 reallocator r( first < begin() || first >= end() );
1125 r.reallocate(this, len + num2copy);
1126 A::defaultConstructFill(m_pData + len, num2copy);
1127 buffer()->m_nLength = len + num2copy;
1128 T* pDestination = m_pData + index;
1129 if (index != len)
1130 {
1131 A::moveAssignRange(pDestination + num2copy, pDestination, len - index);
1132 }
1133 A::copyAssignRangeDisjoint(pDestination, first, (size_type)(afterLast - first));
1134 }
1135 }
1136 else
1137 {
1138 rise_error(eInvalidInput);
1139 }
1140 }
1141
1152 iterator before,
1154 iterator afterLast)
1155 {
1156#ifdef ODA_DIAGNOSTICS
1157 if (first >= begin_const() && first < end_const() && before < afterLast)
1158 throw OdError(L"Inserted iterator range will become invalid while inserting.");
1159#endif
1160 size_type len = length();
1161 size_type index = (size_type)(before - begin_const());
1163 {
1164 if (afterLast > first)
1165 {
1166 size_type num2copy = (size_type)(afterLast - first);
1167 reallocator r(first < begin() || first >= end());
1168 r.reallocate(this, len + num2copy);
1169 A::defaultConstructFill(m_pData + len, num2copy);
1170 buffer()->m_nLength = len + num2copy;
1171 T* pDestination = m_pData + index;
1172 if (index != len)
1173 {
1174 A::moveAssignRange(pDestination + num2copy, pDestination, len - index);
1175 }
1176 A::moveAssignRange(pDestination, first, (size_type)(afterLast - first));
1177 }
1178 }
1179 else
1180 {
1181 rise_error(eInvalidInput);
1182 }
1183 }
1184
1192 void resize(
1194 const T& value )
1195 {
1196 size_type len = length();
1197 int d = logicalLength - len;
1198 if ( d > 0 )
1199 {
1200 increaseLogicalLength(logicalLength, len, d, value);
1201 }
1202 else if ( d < 0 )
1203 {
1204 d=-d;
1205 if(!referenced())
1206 {
1207 A::destroyRange(m_pData + logicalLength, d);
1208 }
1209 else
1210 {
1211 copy_buffer(logicalLength);
1212 }
1213 }
1214 buffer()->m_nLength = logicalLength;
1215 }
1216
1224 void resize(
1226 {
1227 size_type len = length();
1228 int d = logicalLength - len;
1229 if ( d > 0 )
1230 {
1231 increaseLogicalLength(logicalLength, len, d);
1232 }
1233 else if ( d < 0 )
1234 {
1235 d = -d;
1236 if ( !referenced() )
1237 {
1238 A::destroyRange( m_pData + logicalLength, d );
1239 }
1240 else
1241 {
1242 copy_buffer(logicalLength);
1243 }
1244 }
1245 buffer()->m_nLength = logicalLength;
1246 }
1247
1255 {
1256 return buffer()->m_nLength;
1257 }
1258
1264 bool empty() const
1265 {
1266 return size() == 0;
1267 }
1268
1276 {
1277 return buffer()->m_nAllocated;
1278 }
1279
1289 size_type reserveLength)
1290 {
1291 if(physicalLength() < reserveLength)
1292 {
1293 setPhysicalLength(reserveLength);
1294 }
1295 }
1296
1308 const_iterator afterLast)
1309 {
1310#ifdef ODA_DIAGNOSTICS
1311 //FELIX_CHANGE_BEGIN
1312 // Issue: DESKTOP-205889
1313 // end_const call may change data (via copy_if_referenced) instead of begin_const
1314 // so it's required to call end_const() first
1315 /*
1316 if (first >= begin_const() && first < end_const())
1317 */
1318 if (first < end_const() && first >= begin_const())
1319 //FELIX_CHANGE_END
1320 throw OdError(L"Assignment of a subrange from self is not allowed.");
1321#endif
1322 clear();
1323 if (afterLast < first)
1324 {
1325 rise_error(eInvalidInput);
1326 }
1327 if (afterLast > first)
1328 {
1329 size_type num2copy = (size_type)(afterLast - first);
1330 copy_buffer(num2copy, true);
1331 buffer()->m_nLength = num2copy;
1332 A::copyConstructRange(m_pData, first, (size_type)(afterLast - first));
1333 }
1334 }
1335
1347 iterator afterLast)
1348 {
1349#ifdef ODA_DIAGNOSTICS
1350 //FELIX_CHANGE_BEGIN
1351 // Issue: DESKTOP-205889
1352 // end_const call may change data (via copy_if_referenced) instead of begin_const
1353 // so it's required to call end_const() first
1354 /*
1355 if (first >= begin_const() && first < end_const())
1356 */
1357 if (first < end_const() && first >= begin_const())
1358 //FELIX_CHANGE_END
1359 throw OdError(L"Assignment of a subrange from self is not allowed.");
1360#endif
1361 clear();
1362 if (afterLast < first)
1363 {
1364 rise_error(eInvalidInput);
1365 }
1366 if (afterLast > first)
1367 {
1368 size_type num2move = (size_type)(afterLast - first);
1369 copy_buffer(num2move, true);
1370 buffer()->m_nLength = num2move;
1371 A::moveConstructRange(m_pData, first, (size_type)(afterLast - first));
1372 }
1373 }
1374
1382 iterator first,
1383 iterator afterLast)
1384 {
1385 size_type i = (size_type)(first - begin_const());
1386 if(first != afterLast)
1387 {
1388 removeSubArray(i, (size_type)(afterLast-begin_const()-1));
1389 }
1390 return begin_non_const()+i;
1391 }
1392
1398 iterator where)
1399 {
1400 size_type i = (size_type) (where - begin_const());
1401 removeAt(i);
1402 return begin_non_const()+i;
1403 }
1404
1407 void clear()
1408 {
1409 if (m_pData == Buffer::_default()->data())
1410 return;
1411 copy_if_referenced();
1412 size_type len = length();
1413 A::destroyRange(m_pData, len);
1414 buffer()->m_nLength -= len;
1415 }
1416
1423 const T& value)
1424 {
1425 size_type len = length();
1426 bool ref = referenced();
1427 bool need2Copy = ref || len == physicalLength();
1428
1429 if (need2Copy && std::addressof(value) >= begin() && std::addressof(value) < end())
1430 {
1431 T valueCopy(value);
1432 copy_buffer(len + 1, !ref);
1433 A::moveConstruct(m_pData + len, std::move(valueCopy));
1434 }
1435 else
1436 {
1437 if (need2Copy)
1438 copy_buffer(len + 1, !ref);
1439 A::copyConstruct(m_pData + len, value);
1440 }
1441 ++buffer()->m_nLength;
1442 }
1443
1450 T&& value)
1451 {
1452 size_type len = length();
1453 bool ref = referenced();
1454 bool need2Copy = ref || len == physicalLength();
1455
1456 if (need2Copy && std::addressof(value) >= begin() && std::addressof(value) < end())
1457 {
1458 T valueMoved(std::move(value));
1459 copy_buffer(len + 1, !ref);
1460 A::moveConstruct(m_pData + len, std::move(valueMoved));
1461 }
1462 else
1463 {
1464 if (need2Copy)
1465 copy_buffer(len + 1, !ref);
1466 A::moveConstruct(m_pData + len, std::move(value));
1467 }
1468 ++buffer()->m_nLength;
1469 }
1470
1480 iterator before,
1481 size_type numElements,
1482 const T& value)
1483 {
1484 if (numElements == 0)
1485 {
1486 return before;
1487 }
1488 size_type len = length();
1489 size_type index = (size_type)(before - begin_const());
1490 T tmpval(value);
1491 reallocator r(true);
1492 r.reallocate(this, len + numElements);
1493 A::defaultConstructFill(m_pData + len, numElements);
1494 buffer()->m_nLength = len + numElements;
1495 T* pData = m_pData;
1496 pData += index;
1497 if (index != len)
1498 {
1499 A::moveAssignRange(pData + numElements, pData, len - index);
1500 }
1501 while (numElements-- > 1)
1502 {
1503 pData[numElements] = tmpval;
1504 }
1505 pData[0] = std::move(tmpval);
1506 return begin_non_const()+index;
1507 }
1508
1516 iterator before,
1517 const T& value = T())
1518 {
1519 size_type index = (size_type)(before - begin_const());
1521 return (begin_non_const() + index);
1522 }
1523
1531 iterator before,
1532 T&& value)
1533 {
1534 size_type index = (size_type)(before - begin_const());
1536 return (begin_non_const() + index);
1537 }
1538
1547 const ConstForPtrT& value,
1548 size_type start = 0) const
1549 {
1550 size_type dummy;
1551 return find(value, dummy, start);
1552 }
1553
1560 {
1561 return buffer()->m_nLength;
1562 }
1563
1569 bool isEmpty() const
1570 {
1571 return length() == 0;
1572 }
1573
1581 {
1582 return length();
1583 }
1584
1592 {
1593 return buffer()->m_nAllocated;
1594 }
1595
1602 int growLength() const
1603 {
1604 return buffer()->m_nGrowBy;
1605 }
1606
1612 const T* asArrayPtr() const
1613 {
1614 return data();
1615 }
1616
1622 const T* getPtr() const
1623 {
1624 return data();
1625 }
1626
1633 {
1634 copy_if_referenced();
1635 return data();
1636 }
1637
1641 const T& operator [](
1642 size_type index) const
1643 {
1644 assertValid(index);
1645 return m_pData[index];
1646 }
1647
1652 {
1653 assertValid(index);
1654 copy_if_referenced();
1655 return m_pData[index];
1656 }
1657
1664 T& at(size_type arrayIndex)
1665 {
1666 assertValid(arrayIndex);
1667 copy_if_referenced();
1668 return *(data() + arrayIndex);
1669 }
1670
1677 const T& at(size_type arrayIndex) const
1678 {
1679 assertValid(arrayIndex);
1680 return *(data() + arrayIndex);
1681 }
1682
1691 size_type arrayIndex,
1692 const T& value)
1693 {
1694 assertValid(arrayIndex);
1695 copy_if_referenced();
1696 m_pData[arrayIndex] = value;
1697 return *this;
1698 }
1699
1706 const T& getAt(
1707 size_type arrayIndex) const
1708 {
1709 assertValid(arrayIndex);
1710 return *(data() + arrayIndex);
1711 }
1712
1718 T& first()
1719 {
1720 return *begin();
1721 }
1722 const T& first() const
1723 {
1724 return *begin();
1725 }
1726
1732 T& last()
1733 {
1734 return at(length() - 1);
1735 }
1736 const T& last() const
1737 {
1738 return at(length() - 1);
1739 }
1740
1748 const T& value)
1749 {
1751 return length() - 1;
1752 }
1753
1763 T&& value)
1764 {
1765 return appendMove(value);
1766 }
1767
1785 T& value)
1786 {
1787 if (index > logicalLength())
1788 rise_error(eInvalidIndex);
1789 size_type oldLen = logicalLength();
1790
1791 T tmp(std::move(value));
1792 reallocator r(true);
1793 r.reallocate(this, oldLen + 1);
1794 A::moveConstruct(m_pData + oldLen, std::move(tmp));
1795 ++buffer()->m_nLength;
1796 if (index != oldLen) {
1797 tmp = std::move(m_pData[oldLen]);
1798 A::moveAssignRange(m_pData + index + 1, m_pData + index, oldLen - index);
1799 m_pData[index] = std::move(tmp);
1800 }
1801 return *this;
1802 }
1803
1813 {
1814 push_back(std::move(value));
1815 return logicalLength() - 1;
1816 }
1817
1825 OdArray& otherArray)
1826 {
1827 insertMove(end_non_const(), otherArray.begin(), otherArray.end());
1828 return *this;
1829 }
1830
1841 const T& value,
1842 size_type nCount
1843 )
1844 {
1845 if (nCount <= 0)
1846 return *this;
1847 size_type oldLen = logicalLength();
1848 T tmp(value);
1849 reallocator r(true);
1850 r.reallocate(this, oldLen + nCount);
1851 A::copyConstructFill(m_pData + oldLen, nCount, tmp);
1852 (buffer()->m_nLength) += nCount;
1853 return *this;
1854 }
1855
1864 template<typename... Args>
1866 const Args&... args
1867 )
1868 {
1869 const size_type numElements = sizeof...(Args);
1870 if (numElements == 0)
1871 {
1872 return *this;
1873 }
1874 reallocator r(!areArgsFromThisArray(args...));
1875 r.reallocate(this, length() + numElements);
1876
1877 variadicAssignHelper(length(), args...);
1878
1879 return *this;
1880 }
1881
1888 {
1889 size_type i = append(T());
1890 return begin_non_const() + i;
1891 }
1892
1899 {
1900 return removeAt(0);
1901 }
1902
1909 {
1910 resize(length() - 1);
1911 return *this;
1912 }
1913
1921 int growLength)
1922 {
1923 if (growLength != 0)
1924 {
1925 copy_if_referenced();
1926 buffer()->m_nGrowBy = growLength;
1927 }
1928 else
1929 {
1930 ODA_FAIL();
1931 }
1932 return *this;
1933 }
1934
1941 explicit OdArray(
1943 int growLength = 8) : m_pData(0)
1944 {
1945 if (growLength == 0)
1946 {
1947 growLength = 8;
1948 }
1949 m_pData = Buffer::allocate(physicalLength, growLength)->data();
1950 }
1951
1952 OdArray() : m_pData(Buffer::_default()->data())
1953 {
1954 buffer()->addref();
1955 }
1956
1957 OdArray(const OdArray& source) : m_pData(source.m_pData)
1958 {
1959 static_assert(std::is_copy_constructible<T>::value, "Can not copy array with non-copyable argument");
1960 buffer()->addref();
1961 }
1962
1963 OdArray(OdArray&& source) : m_pData(source.m_pData)
1964 {
1965 source.m_pData = Buffer::_default()->data();
1966 source.buffer()->addref();
1967 }
1968
1973 OdArray(std::initializer_list<T> l)
1974 {
1975 m_pData = Buffer::allocate(static_cast<size_type>(l.size()), 8)->data();
1976 assign(l.begin(), l.end());
1977 }
1978
1979#if !defined(SWIG)
1980#if !defined(_MSC_VER) || (_MSC_VER > 1800)
1986 template <typename Iter, typename std::enable_if<
1987 std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<Iter>::iterator_category>::value, bool>::type = true>
1988 OdArray(Iter begin, Iter end)
1989 {
1990 m_pData = Buffer::allocate(static_cast<size_type>(std::distance(begin, end)), 8)->data();
1991 assign(begin, end);
1992 }
1993
2000 template <typename Iter, typename std::enable_if<
2001 std::is_base_of<std::input_iterator_tag, typename std::iterator_traits<Iter>::iterator_category>::value
2002 && !std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<Iter>::iterator_category>::value, bool>::type = true>
2003 OdArray(Iter begin, Iter end)
2004 {
2005 m_pData = Buffer::_default()->data();
2006 buffer()->addref();
2007 for (Iter i = begin; i != end; ++i)
2008 push_back(*i);
2009 }
2010#else // VS 2013 with half baked SFINAE support
2017 template <class Iter, class = typename std::enable_if<
2018 std::is_base_of<std::input_iterator_tag, typename std::iterator_traits<typename Iter>::iterator_category>::value, void>::type>
2019 OdArray(Iter begin, Iter end)
2020 {
2021 construct(begin, end, std::_Iter_cat(begin));
2022 }
2023private:
2024 template<class Iter> void construct(Iter begin, Iter end, std::input_iterator_tag)
2025 {
2026 m_pData = Buffer::_default()->data();
2027 buffer()->addref();
2028 for (Iter i = begin; i != end; ++i)
2029 push_back(*i);
2030 }
2031 template<class Iter> void construct(Iter begin, Iter end, std::forward_iterator_tag)
2032 {
2033 m_pData = Buffer::allocate(static_cast<size_type>(std::distance(begin, end)), 8)->data();
2034 assign(begin, end);
2035 }
2036public:
2037#endif // _MSC_VER <= 1800
2038#endif // SWIG
2039
2046 static OdArray<T, A> create(const T* sourceArray, int sourceLength)
2047 {
2048 OdArray<T, A> res(sourceLength);
2049 res.assign(sourceArray, sourceArray + sourceLength);
2050 return res;
2051 }
2052
2057 {
2058 buffer()->release();
2059 }
2060
2062 const OdArray& source)
2063 {
2064 static_assert(std::is_copy_constructible<T>::value, "Can not copy array with non-copyable argument");
2065 source.buffer()->addref();
2066 buffer()->release();
2067 m_pData = source.m_pData;
2068 return *this;
2069 }
2070
2072 OdArray&& source)
2073 {
2074 buffer()->release();
2075 //FELIX_CHANGE_BEGIN
2076 std::swap( m_pData, source.m_pData );
2077 //FELIX_CHANGE_END
2078 source.m_pData = Buffer::_default()->data();
2079 source.buffer()->addref();
2080 return *this;
2081 }
2082
2084 const OdArray& array) const
2085 {
2086 if(length() == array.length())
2087 {
2088 for(size_type i = 0; i < length(); i++)
2089 {
2090 if(at(i) != array[i])
2091 {
2092 return false;
2093 }
2094 }
2095 return true;
2096 }
2097 return false;
2098 }
2099
2101 const OdArray& array) const
2102 {
2103 return !operator == (array);
2104 }
2105
2113 const T& value)
2114 {
2115 copy_if_referenced();
2116 T* pData = m_pData;
2117 size_type n = length();
2118 while(n)
2119 {
2120 pData[--n] = value;
2121 }
2122 return *this;
2123 }
2124
2132 const OdArray& otherArray)
2133 {
2134 insert(end_non_const(), otherArray.begin(), otherArray.end());
2135 return *this;
2136 }
2137
2146 OdArray&& otherArray)
2147 {
2148 appendMove(otherArray);
2149 return *this;
2150 }
2151
2165 const T& value)
2166 {
2167 if (index > logicalLength())
2168 rise_error(eInvalidIndex);
2169 size_type oldLen = logicalLength();
2170
2171 T tmp(value);
2172 reallocator r(true);
2173 r.reallocate(this, oldLen + 1);
2174 A::moveConstruct(m_pData + oldLen, std::move(tmp));
2175 ++buffer()->m_nLength;
2176 if (index != oldLen) {
2177 tmp = std::move(m_pData[oldLen]);
2178 A::moveAssignRange(m_pData + index + 1, m_pData + index, oldLen - index);
2179 m_pData[index] = std::move(tmp);
2180 }
2181 return *this;
2182 }
2183
2197 T&& val
2198 )
2199 {
2200 return insertAtMove(index, val);
2201 }
2202
2208 template<class... Args>
2209 void emplace_back(Args&&... args)
2210 {
2211 reallocator r(!areArgsFromThisArray(std::forward<Args>(args)...));
2212 size_type len = length();
2213 r.reallocate(this, len + 1);
2214 A::construct(m_pData + len, std::forward<Args>(args)...);
2215 ++buffer()->m_nLength;
2216 }
2217
2229 template<class... Args>
2232 Args&&... args)
2233 {
2234 if (index > logicalLength())
2235 rise_error(eInvalidIndex);
2236 size_type oldLen = logicalLength();
2237
2238 reallocator r(!areArgsFromThisArray(std::forward<Args>(args)...));
2239 r.reallocate(this, oldLen + 1);
2240 A::construct(m_pData + oldLen, std::forward<Args>(args)...);
2241 ++buffer()->m_nLength;
2242 if (index != oldLen) {
2243 T tmp = std::move(m_pData[oldLen]);
2244 A::moveAssignRange(m_pData + index + 1, m_pData + index, oldLen - index);
2245 m_pData[index] = std::move(tmp);
2246 }
2247 return *this;
2248 }
2249
2257 template<class... Args>
2259 iterator before,
2260 Args&&... args)
2261 {
2262 size_type index = (size_type)(before - begin_const());
2263 emplaceAt(index, std::forward<Args>(args)...);
2264 return begin_non_const() + index;
2265 }
2266
2278 size_type arrayIndex)
2279 {
2280 assertValid(arrayIndex);
2281 size_type len = length();
2282 if (arrayIndex < --len)
2283 {
2284 copy_if_referenced();
2285 T* pData = m_pData;
2286 A::moveAssignRange(pData + arrayIndex, pData + arrayIndex + 1, len - arrayIndex);
2287 }
2288 resize(len);
2289 return *this;
2290 }
2291
2302 size_type startIndex,
2303 size_type endIndex)
2304 {
2305 if (!isValid(startIndex) || startIndex > endIndex)
2306 {
2307 rise_error(eInvalidIndex);
2308 }
2309 size_type len = length();
2310 copy_if_referenced();
2311 T* pData = m_pData;
2312 ++endIndex;
2313 size_type n2remove = endIndex - startIndex;
2314 A::moveAssignRange(pData + startIndex, pData + endIndex, len - endIndex);
2315 A::destroyRange(pData + len - n2remove, n2remove);
2316 buffer()->m_nLength -= n2remove;
2317 return *this;
2318 }
2319
2328 bool find(
2329 const ConstForPtrT& value,
2330 size_type& findIndex,
2331 size_type start = 0) const
2332 {
2333 if (!empty())
2334 {
2335 assertValid(start);
2336 size_type len = length();
2337 const T* pData = m_pData;
2338 for (size_type i = start; i < len; ++i)
2339 {
2340 if (pData[i] == value)
2341 {
2342 findIndex = i;
2343 return true;
2344 }
2345 }
2346 }
2347 return false;
2348 }
2349
2359 size_type logLength)
2360 {
2361 resize(logLength);
2362 return *this;
2363 }
2364
2374 size_type physLength)
2375 {
2376 if(physLength==0)
2377 {
2378 *this = OdArray<T, A>();
2379 }
2380 else if(physLength != physicalLength())
2381 {
2382 copy_buffer(physLength, !referenced(), true);
2383 }
2384 return *this;
2385 }
2386
2393 {
2394 if(!empty())
2395 {
2396 copy_if_referenced();
2397 T tmp;
2398 iterator iter1 = begin_non_const();
2399 iterator iter2 = end_non_const();
2400 --iter2;
2401 while(iter1 < iter2)
2402 {
2403 tmp = *iter1;
2404 *iter1 = *iter2;
2405 *iter2 = tmp;
2406 ++iter1;
2407 --iter2;
2408 }
2409 }
2410 return *this;
2411 }
2412
2421 size_type firstIndex,
2422 size_type secondIndex)
2423 {
2424 if(!isValid(firstIndex) || !isValid(secondIndex))
2425 {
2426 rise_error(eInvalidIndex);
2427 }
2428 if(firstIndex != secondIndex)
2429 {
2430 T tmp = std::move(at(firstIndex));
2431 at(firstIndex) = std::move(at(secondIndex));
2432 at(secondIndex) = std::move(tmp);
2433 }
2434 return *this;
2435 }
2436
2442 void swap(
2443 OdArray &other)
2444 {
2445 T *temp = m_pData;
2446 m_pData = other.m_pData;
2447 other.m_pData = temp;
2448 }
2449
2460 const T& value,
2461 size_type start = 0)
2462 {
2463 size_type i = 0;
2464 if(find(value, i, start))
2465 {
2466 removeAt(i);
2467 return true;
2468 }
2469 return false;
2470 }
2471private:
2472
2473 T* m_pData;
2474
2475 bool isValid(size_type i) const
2476 {
2477 return i < length();
2478 }
2479
2480 T* data()
2481 {
2482 return (length() ? m_pData : nullptr);
2483 }
2484
2485 const T* data() const
2486 {
2487 return (length() ? m_pData : nullptr);
2488 }
2489
2490 const Buffer* buffer() const
2491 {
2492 return reinterpret_cast<const Buffer*>(m_pData) - 1;
2493 }
2494 Buffer* buffer()
2495 {
2496 return reinterpret_cast<Buffer*>(m_pData) - 1;
2497 }
2498 bool referenced() const
2499 {
2500 return buffer()->m_nRefCounter > 1;
2501 }
2502
2503 // to support appendList() call without args
2504 OdArray& variadicAssignHelper(
2505 size_type
2506 )
2507 {
2508 return *this;
2509 }
2510
2511 // called when last value is to be assigned
2512 OdArray& variadicAssignHelper(
2514 const T& value
2515 )
2516 {
2517 A::copyConstruct(&m_pData[index], value);
2518 ++(buffer()->m_nLength);
2519 return *this;
2520 }
2521
2522 template<typename... Args>
2523 OdArray& variadicAssignHelper(
2525 const T& value,
2526 const Args&... args
2527 )
2528 {
2529 variadicAssignHelper(index, value);
2530 return variadicAssignHelper(index + 1, args...);
2531 }
2532
2533// FELIX_CHANGE_BEGIN
2534#if !defined(SWIG) || defined(SWIGBUILD)
2535// FELIX_CHANGE_END
2536 template<typename U = T,
2537 typename std::enable_if<std::is_same<U, T>::value && !std::is_move_assignable<U>::value, bool>::type = true>
2538 void increaseLogicalLength(
2539 size_type,
2540 size_type,
2541 int,
2542 const T&)
2543 {
2544 throw OdError(eNotApplicable);
2545 }
2546
2547 template<typename U = T,
2548 typename std::enable_if<std::is_same<U, T>::value && std::is_move_assignable<U>::value, bool>::type = true>
2549 void increaseLogicalLength(
2551 size_type oldLen,
2552 int diff,
2553 const T& value)
2554 {
2555 reallocator r(m_pData > std::addressof(value) || std::addressof(value) > m_pData + oldLen);
2556 r.reallocate(this, logicalLength);
2557 A::copyConstructFill(m_pData + oldLen, diff, value);
2558 }
2559
2560 template<typename U = T,
2561 typename std::enable_if<std::is_same<U, T>::value && !std::is_default_constructible<U>::value, bool>::type = true>
2562 void increaseLogicalLength(
2563 size_type,
2564 size_type,
2565 int)
2566 {
2567 throw OdError(eNotApplicable);
2568 }
2569
2570 template<typename U = T,
2571 typename std::enable_if<std::is_same<U, T>::value && std::is_default_constructible<U>::value, bool>::type = true>
2572 void increaseLogicalLength(
2573 size_type /*logicalLength*/,
2574 size_type oldLen,
2575 int diff)
2576 {
2577 copy_before_write(oldLen + diff, true);
2578 A::defaultConstructFill(m_pData + oldLen, diff);
2579 }
2580#endif
2581
2582 bool areArgsFromThisArray()
2583 {
2584 return false;
2585 }
2586 template<class U>
2587 bool areArgsFromThisArray(U&& arg)
2588 {
2589 return static_cast<const void*>(std::addressof(arg)) >= static_cast<const void*>(begin()) &&
2590 static_cast<const void*>(std::addressof(arg)) < static_cast<const void*>(end());
2591 }
2592 template<class U, class... Args>
2593 bool areArgsFromThisArray(U&& arg, Args&&... args)
2594 {
2595 return areArgsFromThisArray(std::forward<U>(arg)) || areArgsFromThisArray(std::forward<Args>(args)...);
2596 }
2597};
2598
2599#include "TD_PackPop.h"
2600
2601#endif // ODARRAY_H_INCLUDED
#define ODA_ASSERT_ONCE(exp)
Definition DebugStuff.h:73
#define ODA_ASSERT(exp)
Definition DebugStuff.h:57
#define ODA_FAIL()
Definition DebugStuff.h:88
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:478
ODRX_CONSTEXPR const T & odmin(const T &a, const T &b)
Definition OdPlatform.h:64
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:1612
OdArray & appendMove(OdArray &otherArray)
Definition OdArray.h:1824
OdArray & emplaceAt(size_type index, Args &&... args)
Definition OdArray.h:2230
T * asArrayPtr()
Definition OdArray.h:1632
~OdArray()
Definition OdArray.h:2056
OdArray & insertAtMove(size_type index, T &value)
Definition OdArray.h:1783
OdArray(std::initializer_list< T > l)
Definition OdArray.h:1973
void clear()
Definition OdArray.h:1407
static OdArray< T, A > create(const T *sourceArray, int sourceLength)
Definition OdArray.h:2046
size_type capacity() const
Definition OdArray.h:1275
OdArray & removeFirst()
Definition OdArray.h:1898
OdArray & swap(size_type firstIndex, size_type secondIndex)
Definition OdArray.h:2420
const T & getAt(size_type arrayIndex) const
Definition OdArray.h:1706
bool operator==(const OdArray &array) const
Definition OdArray.h:2083
iterator end()
Definition OdArray.h:1048
const T & operator[](size_type index) const
Definition OdArray.h:1641
void swap(OdArray &other)
Definition OdArray.h:2442
const_iterator end() const
Definition OdArray.h:1060
void assign(const_iterator first, const_iterator afterLast)
Definition OdArray.h:1306
size_type physicalLength() const
Definition OdArray.h:1591
std::reverse_iterator< const_iterator > rbegin() const
Definition OdArray.h:1079
iterator insert(iterator before, T &&value)
Definition OdArray.h:1530
OdArray & reverse()
Definition OdArray.h:2392
void emplace_back(Args &&... args)
Definition OdArray.h:2209
std::reverse_iterator< const_iterator > rend() const
Definition OdArray.h:1094
OdArray & setAll(const T &value)
Definition OdArray.h:2112
bool operator!=(const OdArray &array) const
Definition OdArray.h:2100
iterator emplace(iterator before, Args &&... args)
Definition OdArray.h:2258
bool empty() const
Definition OdArray.h:1264
OdArray(size_type physicalLength, int growLength=8)
Definition OdArray.h:1941
void resize(size_type logicalLength)
Definition OdArray.h:1224
void insertMove(iterator before, iterator first, iterator afterLast)
Definition OdArray.h:1151
OdArray & operator=(const OdArray &source)
Definition OdArray.h:2061
AECVariant & reference
Definition OdArray.h:842
OdArray & append(const OdArray &otherArray)
Definition OdArray.h:2131
void push_back(T &&value)
Definition OdArray.h:1449
bool contains(const ConstForPtrT &value, size_type start=0) const
Definition OdArray.h:1546
AECVariant & first()
Definition OdArray.h:1718
OdArray & setPhysicalLength(size_type physLength)
Definition OdArray.h:2373
OdArray & setGrowLength(int growLength)
Definition OdArray.h:1920
iterator erase(iterator where)
Definition OdArray.h:1397
OdArray(const OdArray &source)
Definition OdArray.h:1957
size_type length() const
Definition OdArray.h:1559
OdArray & removeLast()
Definition OdArray.h:1908
bool isEmpty() const
Definition OdArray.h:1569
size_type size() const
Definition OdArray.h:1254
OdArray(OdArray &&source)
Definition OdArray.h:1963
bool find(const ConstForPtrT &value, size_type &findIndex, size_type start=0) const
Definition OdArray.h:2328
void push_back(const T &value)
Definition OdArray.h:1422
OdArray & setAt(size_type arrayIndex, const T &value)
Definition OdArray.h:1690
size_type logicalLength() const
Definition OdArray.h:1580
const AECVariant & const_reference
Definition OdArray.h:841
OdArray()
Definition OdArray.h:1952
size_type append(T &&value)
Definition OdArray.h:1762
OdArray & appendList(const Args &... args)
Definition OdArray.h:1865
iterator begin()
Definition OdArray.h:1024
OdArray & appendRep(const T &value, size_type nCount)
Definition OdArray.h:1840
const T & last() const
Definition OdArray.h:1736
void reserve(size_type reserveLength)
Definition OdArray.h:1288
void insert(iterator before, const_iterator first, const_iterator afterLast)
Definition OdArray.h:1108
const T & at(size_type arrayIndex) const
Definition OdArray.h:1677
std::reverse_iterator< iterator > rend()
Definition OdArray.h:1087
OdArray & setLogicalLength(size_type logLength)
Definition OdArray.h:2358
const T & first() const
Definition OdArray.h:1722
typename A::size_type size_type
Definition OdArray.h:837
OdArray & removeSubArray(size_type startIndex, size_type endIndex)
Definition OdArray.h:2301
OdArray & append(OdArray &&otherArray)
Definition OdArray.h:2145
iterator erase(iterator first, iterator afterLast)
Definition OdArray.h:1381
typename std::conditional< std::is_pointer< AECVariant >::value, typename std::add_const< typename std::remove_pointer< AECVariant >::type >::type *, AECVariant >::type ConstForPtrT
Definition OdArray.h:843
OdArray(Iter begin, Iter end)
Definition OdArray.h:1988
iterator insert(iterator before, size_type numElements, const T &value)
Definition OdArray.h:1479
T & at(size_type arrayIndex)
Definition OdArray.h:1664
AECVariant value_type
Definition OdArray.h:840
void assignMove(iterator first, iterator afterLast)
Definition OdArray.h:1345
const AECVariant * const_iterator
Definition OdArray.h:839
const T * getPtr() const
Definition OdArray.h:1622
iterator append()
Definition OdArray.h:1887
OdArray & insertAt(size_type index, T &&val)
Definition OdArray.h:2195
OdArray & removeAt(size_type arrayIndex)
Definition OdArray.h:2277
T & last()
Definition OdArray.h:1732
friend class reallocator
Definition OdArray.h:927
size_type appendMove(T &value)
Definition OdArray.h:1812
void resize(size_type logicalLength, const T &value)
Definition OdArray.h:1192
size_type append(const T &value)
Definition OdArray.h:1747
int growLength() const
Definition OdArray.h:1602
iterator insert(iterator before, const T &value=T())
Definition OdArray.h:1515
std::reverse_iterator< iterator > rbegin()
Definition OdArray.h:1072
OdArray & insertAt(size_type index, const T &value)
Definition OdArray.h:2163
bool remove(const T &value, size_type start=0)
Definition OdArray.h:2459
AECVariant * iterator
Definition OdArray.h:838
const_iterator begin() const
Definition OdArray.h:1036
unsigned int size_type
Definition OdArray.h:335
static void defaultConstruct(T *pElement)
Definition OdArray.h:376
static void defaultConstructFill(T *pDestination, size_type numElements)
Definition OdArray.h:393
static void copyConstructFill(T *pDestination, size_type numElements, const T &value)
Definition OdArray.h:344
static void copyConstructRange(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:359
static void moveAssignRange(T *pDestination, T *pSource, size_type numElements)
Definition OdArray.h:129
static void construct(T *pDestination, Args &&... args)
Definition OdArray.h:211
static void defaultConstructFill(T *, size_type)
Definition OdArray.h:281
static void destroyRange(T *, size_type)
Definition OdArray.h:305
static void moveConstruct(T *pElement, T &&value)
Definition OdArray.h:192
static void copyConstruct(T *pElement, const T &value)
Definition OdArray.h:163
static void destroy(T *pObject)
Definition OdArray.h:293
unsigned int size_type
Definition OdArray.h:69
static void copyAssignRangeDisjoint(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:82
static bool useRealloc()
Definition OdArray.h:317
static void copyConstructRange(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:248
static void copyConstructFill(T *pDestination, size_type numElements, const T &value)
Definition OdArray.h:225
static void copyAssignRange(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:106
static void moveConstructRange(T *pDestination, T *pSource, size_type numElements)
Definition OdArray.h:263
static void defaultConstruct(T *)
Definition OdArray.h:151
static void moveAssignRange(T *pDestination, T *pSource, size_type numElements)
Definition OdArray.h:487
static void copyConstructRange(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:610
static void defaultConstructFill(T *pDestination, size_type numElements)
Definition OdArray.h:593
static void copyConstructFill(T *pDestination, size_type numElements, const T &value)
Definition OdArray.h:572
unsigned int size_type
Definition OdArray.h:422
static void moveConstructRange(T *pDestination, T *pSource, size_type numElements)
Definition OdArray.h:630
static void copyAssignRange(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:459
static void construct(T *pDestination, Args &&... args)
Definition OdArray.h:558
static void defaultConstruct(T *pElement)
Definition OdArray.h:519
static void destroyRange(T *objects, size_type numObjects)
Definition OdArray.h:661
static bool useRealloc()
Definition OdArray.h:679
static void destroy(T *pObject)
Definition OdArray.h:648
static void copyConstruct(T *pElement, const T &value)
Definition OdArray.h:531
static void moveConstruct(T *pElement, T &&value)
Definition OdArray.h:544
static void copyAssignRangeDisjoint(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:435
static void copyAssignRangeDisjoint(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:714
unsigned int size_type
Definition OdArray.h:701
static void moveAssignRange(T *pDestination, T *pSource, size_type numElements)
Definition OdArray.h:761
static bool useRealloc()
Definition OdArray.h:782
static void copyAssignRange(T *pDestination, const T *pSource, size_type numElements)
Definition OdArray.h:738
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:801
size_type m_nLength
Definition OdArray.h:799
unsigned int size_type
Definition OdArray.h:794
OdRefCounter m_nRefCounter
Definition OdArray.h:796
size_type m_nAllocated
Definition OdArray.h:798
static const bool value
Definition OdArray.h:48