CFx SDK Documentation  2023 SP0
OdArray.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2017, 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 Teigha(R) software pursuant to a license
16 // agreement with Open Design Alliance.
17 // Teigha(R) Copyright (C) 2002-2017 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 
32 #include "TD_PackPush.h"
33 
34 #include "OdArrayPreDef.h"
35 #include "OdHeap.h"
36 #include "OdMutex.h"
37 #include "OdError.h"
38 #include "RxSystemServices.h"
39 
48 template <class T> class OdMemoryAllocator
49 {
50 public:
51  typedef unsigned int size_type;
62  static inline void copy(
63  T* pDestination,
64  const T* pSource,
65  size_type numElements)
66  {
67  memcpy(pDestination, pSource, numElements * sizeof(T));
68  }
69 
83  static inline void move(
84  T* pDestination,
85  const T* pSource,
86  size_type numElements)
87  {
88  memmove(pDestination, pSource, numElements * sizeof(T));
89  }
96  static inline void construct(
97  T* pElement,
98  const T& value = T())
99  {
100  *pElement = value;
101  }
102 
113  static inline void constructn(
114  T* pDestination,
115  size_type numElements,
116  const T& value)
117  {
118  while(numElements--)
119  {
120  pDestination[numElements] = value;
121  }
122  }
123 
134  static inline void constructn(
135  T* pDestination,
136  const T* pSource,
137  size_type numElements)
138  {
139  copy(pDestination, pSource, numElements);
140  }
141 
151  //FELIX_CHANGE_BEGIN
152  // merged from ODA GIT, CORE-15248
153  static inline void constructn(
154  T* pDestination,
155  size_type numElements)
156  {
157  memset(pDestination, 0, numElements * sizeof(T));
158  }
159  //FELIX_CHANGE_END
166  static inline void destroy(
167  T*)
168  {
169  // DOES NOTHING
170  }
177  static inline void destroy(
178  T*,
179  size_type )
180  {
181  // DOES NOTHING
182  }
189  static inline bool useRealloc()
190  {
191  return true;
192  }
193 };
194 
195 
208 template <class T> class OdObjectsAllocator
209 {
210 public:
211  typedef unsigned int size_type;
212 
223  static inline void copy(
224  T* pDestination,
225  const T* pSource,
226  size_type numObjects)
227  {
228  while(numObjects--)
229  {
230  *pDestination = *pSource;
231  pDestination++;
232  pSource++;
233  }
234  }
235 
249  static inline void move(
250  T* pDestination,
251  const T* pSource,
252  size_type numObjects)
253  {
254  if (pDestination <= pSource || pDestination >= pSource + numObjects)
255  {
256  copy(pDestination, pSource, numObjects);
257  }
258  else
259  {
260  while(numObjects--)
261  {
262  pDestination[numObjects] = pSource[numObjects];
263  }
264  }
265  }
271  static inline void construct(
272  T* pObject)
273  {
274 #ifdef new
275 #undef new
276 #endif
277  ::new (pObject) T;
278  }
285  static inline void construct(
286  T* pObject,
287  const T& value)
288  {
289 #ifdef new
290 #undef new
291 #endif
292  ::new (pObject) T(value);
293  }
301  static inline void constructn(
302  T* pDestination,
303  size_type numObjects,
304  const T& value)
305  {
306  while(numObjects--)
307  {
308  construct(pDestination+numObjects, value);
309  }
310  }
317  static inline void constructn(
318  T* pDestination,
319  size_type numObjects)
320  {
321  while(numObjects--)
322  {
323  construct(pDestination+numObjects);
324  }
325  }
333  static inline void constructn(
334  T* pDestination,
335  const T* pSource,
336  size_type numObjects)
337  {
338  while(numObjects--)
339  {
340  construct(pDestination, *pSource);
341  pDestination++;
342  pSource++;
343  }
344  }
349  static inline void destroy(
350  T* pObject)
351  {
352  pObject->~T();
353  pObject = 0;
354  }
360  static inline void destroy(
361  T* objects,
362  size_type numObjects)
363  {
364  while(numObjects--)
365  {
366  destroy(objects + numObjects);
367  }
368  }
375  static inline bool useRealloc()
376  {
377  return false;
378  }
379 };
392 template <class T> class OdPlainObjectsAllocator
393 {
394 public:
395  typedef unsigned int size_type;
396 
407  static inline void copy(
408  T* pDestination,
409  const T* pSource,
410  size_type numObjects)
411  {
412  memcpy(pDestination, pSource, numObjects * sizeof(T));
413  }
414 
428  static inline void move(
429  T* pDestination,
430  const T* pSource,
431  size_type numObjects)
432  {
433  memmove(pDestination, pSource, numObjects * sizeof(T));
434  }
435 
441  static inline void construct(
442  T* pObject)
443  {
444 #ifdef new
445 #undef new
446 #endif
447  ::new (pObject) T;
448  }
455  static inline void construct(
456  T* pObject,
457  const T& value)
458  {
459 #ifdef new
460 #undef new
461 #endif
462  ::new (pObject) T(value);
463  }
464 
472  static inline void constructn(
473  T* pDestination,
474  size_type numObjects,
475  const T& value)
476  {
477  while(numObjects--)
478  {
479  construct(pDestination+numObjects, value);
480  }
481  }
488  static inline void constructn(
489  T* pDestination,
490  size_type numObjects)
491  {
492  while(numObjects--)
493  {
494  construct(pDestination+numObjects);
495  }
496  }
504  static inline void constructn(
505  T* pDestination,
506  const T* pSource,
507  size_type numObjects)
508  {
509  while(numObjects--)
510  {
511  construct(pDestination, *pSource);
512  pDestination++;
513  pSource++;
514  }
515  }
516 
522  static inline void destroy(
523  T* pObject)
524  {
525  pObject->~T();
526  pObject = 0;
527  }
534  static inline void destroy(
535  T* objects,
536  size_type numObjects)
537  {
538  while(numObjects--)
539  {
540  destroy(objects + numObjects);
541  }
542  }
549  static inline bool useRealloc()
550  {
551  return true;
552  }
553 };
554 
560 {
561  typedef unsigned int size_type;
562 
567 
569 };
570 
571 
572 
590 template <class T, class A> class OdArray
591 {
592 public:
593  typedef typename A::size_type size_type;
594  typedef T* iterator;
595  typedef const T* const_iterator;
596  typedef T value_type;
597  typedef const T& const_reference;
598  typedef T& reference;
599 private:
600  struct Buffer : OdArrayBuffer
601  {
602  T* data() const { return (T*)(this+1); }
603 
604  static Buffer* allocate(size_type nLength2Allocate, int nGrowBy)
605  {
606  size_type nBytes2Allocate = sizeof(Buffer) + nLength2Allocate * sizeof(T);
607  ODA_ASSERT(nBytes2Allocate > nLength2Allocate); // size_type overflow
608  if(nBytes2Allocate > nLength2Allocate)
609  {
610  Buffer* pBuffer = (Buffer*)::odrxAlloc(nBytes2Allocate);
611  if (pBuffer)
612  {
613  pBuffer->m_nRefCounter = 1;
614  pBuffer->m_nGrowBy = nGrowBy;
615  pBuffer->m_nAllocated = nLength2Allocate;
616  pBuffer->m_nLength = 0;
617  return pBuffer;
618  }
619  }
620  throw OdError(eOutOfMemory);
621  }
622  static Buffer* _default()
623  {
624  return (Buffer*)&g_empty_array_buffer;
625  }
626  void release()
627  {
628  ODA_ASSERT(m_nRefCounter);
629  if((--m_nRefCounter)==0 && this != _default())
630  {
631  A::destroy(data(), m_nLength);
632  ::odrxFree(this);
633  }
634  }
635  void addref() const { ++m_nRefCounter; }
636  };
637  class reallocator
638  {
639  bool _may_use_realloc;
640  Buffer* m_pBuffer;
641  public:
642  inline reallocator( bool may_use_realloc = false ) : _may_use_realloc(may_use_realloc), m_pBuffer(NULL)
643  {
644  if ( !_may_use_realloc )
645  {
646  m_pBuffer = Buffer::_default();
647  m_pBuffer->addref();
648  }
649  }
650  inline void reallocate(OdArray* pArray, size_type nNewLen )
651  {
652  if(!pArray->referenced())
653  {
654  if(nNewLen > pArray->physicalLength())
655  {
656  if ( !_may_use_realloc )
657  {
658  m_pBuffer->release();
659  m_pBuffer = pArray->buffer();
660  m_pBuffer->addref(); // save buffer to ensure copy from itself would work (e.g insertAt)
661  }
662  pArray->copy_buffer(nNewLen, _may_use_realloc);
663  }
664  }
665  else
666  {
667  pArray->copy_buffer(nNewLen);
668  }
669  }
670  inline ~reallocator()
671  {
672  if ( !_may_use_realloc ) m_pBuffer->release();
673  }
674  };
675  friend class reallocator;
676  const_iterator begin_const() const { return begin(); }
677  iterator begin_non_const() { return begin(); }
678  const_iterator end_const() { return end(); }
679  iterator end_non_const() { return end(); }
680  void copy_before_write(size_type len, bool may_use_realloc = false )
681  {
682  if( referenced() )
683  copy_buffer(len);
684  else if ( len > physicalLength() )
685  copy_buffer( len, may_use_realloc );
686  }
687  void copy_if_referenced() { if(referenced()) { copy_buffer(physicalLength()); } }
688  void copy_buffer( size_type len, bool may_use_realloc = false, bool force_size = false )
689  {
690  Buffer* pOldBuffer = buffer();
691  int nGrowBy = pOldBuffer->m_nGrowBy;
692  size_type len2 = len;
693  if ( !force_size )
694  {
695  if(nGrowBy > 0)
696  {
697  len2 += nGrowBy;
698  len2 = ((len2 - 1) / nGrowBy) * nGrowBy;
699  }
700  else
701  {
702  len2 = pOldBuffer->m_nLength;
703  len2 = len2 + -nGrowBy * len2 / 100;
704  if(len2 < len)
705  {
706  len2 = len;
707  }
708  }
709  }
710  if ( may_use_realloc && A::useRealloc() && !empty() )
711  {
712  Buffer* pNewBuffer = reinterpret_cast<Buffer*>( ::odrxRealloc(
713  pOldBuffer, len2 * sizeof(T) + sizeof(Buffer), pOldBuffer->m_nAllocated * sizeof(T) + sizeof(Buffer) ) );
714  if (!pNewBuffer)
715  throw OdError(eOutOfMemory);
716  pNewBuffer->m_nAllocated = len2;
717  pNewBuffer->m_nLength = odmin(pNewBuffer->m_nLength, len);
718  m_pData = pNewBuffer->data();
719  }
720  else
721  {
722  Buffer* pNewBuffer = Buffer::allocate(len2, nGrowBy);
723  if (!pNewBuffer)
724  throw OdError(eOutOfMemory);
725  len = odmin(pOldBuffer->m_nLength, len);
726  A::constructn(pNewBuffer->data(), pOldBuffer->data(), len);
727  pNewBuffer->m_nLength = len;
728  m_pData = pNewBuffer->data();
729  pOldBuffer->release();
730  }
731  }
732  inline void assertValid(size_type index) const
733  {
734  if(!isValid(index))
735  {
736  ODA_FAIL();
737  throw OdError_InvalidIndex();
738  }
739  }
740  static inline void rise_error(OdResult e)
741  {
742  ODA_FAIL();
743  throw OdError(e);
744  }
745 public:
746  // STL-like interface
747 
752  {
753  if(!empty())
754  {
755  copy_if_referenced();
756  return data();
757  }
758  return 0;
759  }
761  {
762  if(!empty())
763  {
764  return data();
765  }
766  return 0;
767  }
768 
773  {
774  if(!empty())
775  {
776  copy_if_referenced();
777  return data() + length();
778  }
779  return 0;
780  }
782  {
783  if(!empty())
784  {
785  return data() + length();
786  }
787  return 0;
788  }
789 
800  void insert(
801  iterator before,
803  const_iterator afterLast)
804  {
805  size_type len = length();
806  size_type index = (size_type)(before - begin_const());
808  {
809  if(afterLast > first)
810  {
811  size_type num2copy = (size_type)(afterLast - first);
812  reallocator r( first < begin() || first >= end() );
813  r.reallocate(this, len + num2copy);
814  A::constructn(m_pData + len, first, num2copy);
815  buffer()->m_nLength = len + num2copy;
816  T* pDestination = m_pData + index;
817  if(index != len)
818  {
819  A::move(pDestination + num2copy, pDestination, len - index);
820  }
821  A::copy(pDestination, first, (size_type)(afterLast - first));
822  }
823  }
824  else
825  {
826  rise_error(eInvalidInput);
827  }
828  }
834  void resize(
836  const T& value )
837  {
838  size_type len = length();
839  int d = logicalLength - len;
840  if ( d > 0 )
841  {
842  reallocator r( m_pData > &value || &value > (m_pData + len) );
843  r.reallocate(this, logicalLength);
844  A::constructn(m_pData + len, d, value);
845  }
846  else if ( d < 0 )
847  {
848  d=-d;
849  if(!referenced())
850  {
851  A::destroy(m_pData + logicalLength, d);
852  }
853  else
854  {
855  copy_buffer(logicalLength);
856  }
857  }
858  buffer()->m_nLength = logicalLength;
859  }
860 
865  void resize(
867  {
868  size_type len = length();
869  int d = logicalLength - len;
870  if ( d > 0 )
871  {
872  copy_before_write( len + d, true );
873  A::constructn(m_pData + len, d);
874  }
875  else if ( d < 0 )
876  {
877  d = -d;
878  if ( !referenced() )
879  {
880  A::destroy( m_pData + logicalLength, d );
881  }
882  else
883  {
884  copy_buffer(logicalLength);
885  }
886  }
887  buffer()->m_nLength = logicalLength;
888  }
889 
893  size_type size() const
894  {
895  return buffer()->m_nLength;
896  }
897 
901  bool empty() const
902  {
903  return size() == 0;
904  }
905 
910  {
911  return buffer()->m_nAllocated;
912  }
913 
920  void reserve(
921  size_type reserveLength)
922  {
923  if(physicalLength() < reserveLength)
924  {
925  setPhysicalLength(reserveLength);
926  }
927  }
928 
939  void assign(
941  const_iterator afterLast)
942  {
943  erase(begin_non_const(), end_non_const());
944  insert(begin_non_const(), first, afterLast);
945  }
946 
954  iterator first,
955  iterator afterLast)
956  {
957  size_type i = (size_type)(first - begin_const());
958  if(first != afterLast)
959  {
960  removeSubArray(i, (size_type)(afterLast-begin_const()-1));
961  }
962  return begin_non_const()+i;
963  }
970  iterator where)
971  {
972  size_type i = (size_type) (where - begin_const());
973  removeAt(i);
974  return begin_non_const()+i;
975  }
979  void clear()
980  {
981  erase(begin_non_const(), end_non_const());
982  }
983 
987  void push_back(
988  const T& value)
989  {
990  insertAt(length(), value);
991  }
992 
1001  iterator before,
1002  size_type numElements,
1003  const T& value)
1004  {
1005  size_type len = length();
1006  size_type index = (size_type)(before - begin_const());
1007  reallocator r( m_pData > &value || &value > (m_pData + len) );
1008  r.reallocate(this, len + numElements);
1009  A::constructn(m_pData + len, numElements, value);
1010  buffer()->m_nLength = len + numElements;
1011  T* pData = data();
1012  pData += index;
1013  if(index != len)
1014  {
1015  A::move(pData + numElements, pData, len - index);
1016  }
1017  while(numElements--)
1018  {
1019  pData[numElements] = value;
1020  }
1021  return begin_non_const()+index;
1022  }
1029  iterator before,
1030  const T& value = T())
1031  {
1032  size_type index = (size_type)(before - begin_const());
1033  insertAt(index, value);
1034  return (begin_non_const() + index);
1035  }
1036 
1043  bool contains(
1044  const T& value,
1045  size_type start = 0) const
1046  {
1047  size_type dummy;
1048  return find(value, dummy, start);
1049  }
1050 
1055  {
1056  return buffer()->m_nLength;
1057  }
1058 
1062  bool isEmpty() const
1063  {
1064  return length() == 0;
1065  }
1066 
1071  {
1072  return length();
1073  }
1074 
1079  {
1080  return buffer()->m_nAllocated;
1081  }
1082 
1086  int growLength() const
1087  {
1088  return buffer()->m_nGrowBy;
1089  }
1090 
1094  const T* asArrayPtr() const
1095  {
1096  return data();
1097  }
1098 
1102  const T* getPtr() const
1103  {
1104  return data();
1105  }
1106 
1111  {
1112  copy_if_referenced();
1113  return data();
1114  }
1115 
1119  const T& operator [](
1120  size_type index) const
1121  {
1122  assertValid(index);
1123  return m_pData[index];
1124  }
1129  size_type index)
1130  {
1131  assertValid(index);
1132  copy_if_referenced();
1133  return m_pData[index];
1134  }
1135 
1140  T& at(size_type arrayIndex)
1141  {
1142  assertValid(arrayIndex);
1143  copy_if_referenced();
1144  return *(data() + arrayIndex);
1145  }
1146 
1151  const T& at(size_type arrayIndex) const
1152  {
1153  assertValid(arrayIndex);
1154  return *(data() + arrayIndex);
1155  }
1156 
1163  size_type arrayIndex,
1164  const T& value)
1165  {
1166  assertValid(arrayIndex);
1167  copy_if_referenced();
1168  m_pData[arrayIndex] = value;
1169  return *this;
1170  }
1171 
1176  const T& getAt(
1177  size_type arrayIndex) const
1178  {
1179  assertValid(arrayIndex);
1180  return *(data() + arrayIndex);
1181  }
1182 
1186  T& first()
1187  {
1188  return *begin();
1189  }
1190  const T& first() const
1191  {
1192  return *begin();
1193  }
1194 
1198  T& last()
1199  {
1200  return at(length() - 1);
1201  }
1202  const T& last() const
1203  {
1204  return at(length() - 1);
1205  }
1206 
1216  const T& value)
1217  {
1218  insertAt(length(), value);
1219  return length() - 1;
1220  }
1221 
1226  {
1227  size_type i = append(T());
1228  return begin_non_const() + i;
1229  }
1230 
1235  {
1236  return removeAt(0);
1237  }
1238 
1243  {
1244  return removeAt(length() - 1);
1245  }
1246 
1252  int growLength)
1253  {
1254  if (growLength != 0)
1255  {
1256  copy_if_referenced();
1257  buffer()->m_nGrowBy = growLength;
1258  }
1259  else
1260  {
1261  ODA_FAIL();
1262  }
1263  return *this;
1264  }
1265 
1272  explicit OdArray(
1274  int growLength = 8) : m_pData(0)
1275  {
1276  if (growLength == 0)
1277  {
1278  growLength = 8;
1279  }
1280  m_pData = Buffer::allocate(physicalLength, growLength)->data();
1281  }
1282 
1283  OdArray() : m_pData(Buffer::_default()->data())
1284  {
1285  buffer()->addref();
1286  }
1287 
1288  OdArray(const OdArray& source) : m_pData((T*)source.data())
1289  {
1290  buffer()->addref();
1291  }
1292 
1294  {
1295  buffer()->release();
1296  }
1297 
1299  const OdArray& source)
1300  {
1301  source.buffer()->addref();
1302  buffer()->release();
1303  m_pData = source.m_pData;
1304  return *this;
1305  }
1306 
1308  const OdArray& array) const
1309  {
1310  if(length() == array.length())
1311  {
1312  for(size_type i = 0; i < length(); i++)
1313  {
1314  if(at(i) != array[i])
1315  {
1316  return false;
1317  }
1318  }
1319  return true;
1320  }
1321  return false;
1322  }
1323 
1329  const T& value)
1330  {
1331  copy_if_referenced();
1332  T* pData = data();
1333  size_type n = length();
1334  while(n)
1335  {
1336  pData[--n] = value;
1337  }
1338  return *this;
1339  }
1355  const OdArray& otherArray)
1356  {
1357  insert(end_non_const(), otherArray.begin(), otherArray.end());
1358  return *this;
1359  }
1360 
1375  size_type arrayIndex,
1376  const T& value)
1377  {
1378  size_type len = length();
1379  if( arrayIndex == len )
1380  {
1381  resize( len + 1, value );
1382  }
1383  else if ( arrayIndex < len )
1384  {
1385  reallocator r( m_pData > &value || &value > (m_pData + len) );
1386  r.reallocate( this, len+1 );
1387  A::construct( m_pData + len );
1388  ++(buffer()->m_nLength);
1389  A::move(m_pData + arrayIndex + 1, m_pData + arrayIndex, len - arrayIndex);
1390  m_pData[arrayIndex] = value;
1391  }
1392  else
1393  {
1394  rise_error(eInvalidIndex);
1395  }
1396  return *this;
1397  }
1398 
1412  size_type arrayIndex)
1413  {
1414  assertValid(arrayIndex);
1415  size_type len = length();
1416  if(arrayIndex < --len)
1417  {
1418  copy_if_referenced();
1419  T* pData = data();
1420  A::move(pData + arrayIndex, pData + arrayIndex + 1, len - arrayIndex);
1421  }
1422  resize(len);
1423  return *this;
1424  }
1425 
1438  size_type startIndex,
1439  size_type endIndex)
1440  {
1441  if(!isValid(startIndex) || startIndex > endIndex)
1442  {
1443  rise_error(eInvalidIndex);
1444  }
1445  size_type len = length();
1446  copy_if_referenced();
1447  T* pData = data();
1448  ++endIndex;
1449  size_type n2remove = endIndex - startIndex;
1450  A::move(pData + startIndex, pData + endIndex, len - endIndex);
1451  A::destroy(pData + len - n2remove, n2remove);
1452  buffer()->m_nLength -= n2remove;
1453  return *this;
1454  }
1455 
1466  bool find(
1467  const T& value,
1468  size_type& findIndex,
1469  size_type start=0) const
1470  {
1471  if(!empty())
1472  {
1473  assertValid(start);
1474  size_type len = length();
1475  const T* pData = data();
1476  for(size_type i = start; i<len; ++i)
1477  {
1478  if(pData[i] == value)
1479  {
1480  findIndex = i;
1481  return true;
1482  }
1483  }
1484  }
1485  return false;
1486  }
1487 
1495  size_type logLength)
1496  {
1497  resize(logLength);
1498  return *this;
1499  }
1500 
1508  size_type physLength)
1509  {
1510  if(physLength==0)
1511  {
1512  *this = OdArray<T, A>();
1513  }
1514  else if(physLength != physicalLength())
1515  {
1516  copy_buffer(physLength, !referenced(), true);
1517  }
1518  return *this;
1519  }
1520 
1525  {
1526  if(!empty())
1527  {
1528  copy_if_referenced();
1529  T tmp;
1530  iterator iter1 = begin_non_const();
1531  iterator iter2 = end_non_const();
1532  --iter2;
1533  while(iter1 < iter2)
1534  {
1535  tmp = *iter1;
1536  *iter1 = *iter2;
1537  *iter2 = tmp;
1538  ++iter1;
1539  --iter2;
1540  }
1541  }
1542  return *this;
1543  }
1544 
1551  size_type firstIndex,
1552  size_type secondIndex)
1553  {
1554  if(!isValid(firstIndex) || !isValid(secondIndex))
1555  {
1556  rise_error(eInvalidIndex);
1557  }
1558  if(firstIndex != secondIndex)
1559  {
1560  const T tmp = at(firstIndex);
1561  at(firstIndex) = at(secondIndex);
1562  at(secondIndex) = tmp;
1563  }
1564  return *this;
1565  }
1577  bool remove(
1578  const T& value,
1579  size_type start = 0)
1580  {
1581  size_type i = 0;
1582  if(find(value, i, start))
1583  {
1584  removeAt(i);
1585  return true;
1586  }
1587  return false;
1588  }
1589 private:
1590 
1591  T* m_pData;
1592 
1593  bool isValid(size_type i) const
1594  {
1595  return (i < length());
1596  }
1597 
1598  T* data()
1599  {
1600  return (length() ? m_pData : 0);
1601  }
1602 
1603  const T* data() const
1604  {
1605  return m_pData;
1606  }
1607 
1608  Buffer* buffer() const
1609  {
1610  return (reinterpret_cast<Buffer*>(const_cast<OdArray*>(this)->m_pData) - 1);
1611  }
1612  bool referenced() const
1613  {
1614  return (buffer()->m_nRefCounter>1);
1615  }
1616 };
1617 
1618 template <class T, class A>
1620  const OdArray<T,A>& a,
1621  const OdArray<T, A>& b)
1622 {
1623  return !( a.operator == (b) );
1624 }
1625 
1626 #include "TD_PackPop.h"
1627 
1628 #endif // ODARRAY_H_INCLUDED
1629 
1630 
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:49
#define ODA_FAIL()
Definition: DebugStuff.h:65
#define NULL
Definition: GsProperties.h:177
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)
bool operator!=(const OdArray< T, A > &a, const OdArray< T, A > &b)
Definition: OdArray.h:1619
int OdRefCounter
Definition: OdMutex.h:436
#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 & last() const
Definition: OdArray.h:1202
~OdArray()
Definition: OdArray.h:1293
OdArray & operator=(const OdArray &source)
Definition: OdArray.h:1298
void clear()
Definition: OdArray.h:979
A::size_type size_type
Definition: OdArray.h:593
T & last()
Definition: OdArray.h:1198
size_type capacity() const
Definition: OdArray.h:909
T * asArrayPtr()
Definition: OdArray.h:1110
const T & getAt(size_type arrayIndex) const
Definition: OdArray.h:1176
bool operator==(const OdArray &array) const
Definition: OdArray.h:1307
T value_type
Definition: OdArray.h:596
T & reference
Definition: OdArray.h:598
iterator end()
Definition: OdArray.h:772
T & first()
Definition: OdArray.h:1186
const_iterator end() const
Definition: OdArray.h:781
void assign(const_iterator first, const_iterator afterLast)
Definition: OdArray.h:939
size_type physicalLength() const
Definition: OdArray.h:1078
OdArray & reverse()
Definition: OdArray.h:1524
const T & first() const
Definition: OdArray.h:1190
OdArray & setGrowLength(int growLength)
Definition: OdArray.h:1251
bool empty() const
Definition: OdArray.h:901
OdArray(size_type physicalLength, int growLength=8)
Definition: OdArray.h:1272
void resize(size_type logicalLength)
Definition: OdArray.h:865
OdArray & append(const OdArray &otherArray)
Definition: OdArray.h:1354
OdArray & removeAt(size_type arrayIndex)
Definition: OdArray.h:1411
OdArray & removeSubArray(size_type startIndex, size_type endIndex)
Definition: OdArray.h:1437
bool find(const T &value, size_type &findIndex, size_type start=0) const
Definition: OdArray.h:1466
iterator erase(iterator where)
Definition: OdArray.h:969
OdArray(const OdArray &source)
Definition: OdArray.h:1288
OdArray & setAt(size_type arrayIndex, const T &value)
Definition: OdArray.h:1162
OdArray & swap(size_type firstIndex, size_type secondIndex)
Definition: OdArray.h:1550
size_type length() const
Definition: OdArray.h:1054
bool isEmpty() const
Definition: OdArray.h:1062
size_type size() const
Definition: OdArray.h:893
void push_back(const T &value)
Definition: OdArray.h:987
OdArray & insertAt(size_type arrayIndex, const T &value)
Definition: OdArray.h:1374
const T & at(size_type arrayIndex) const
Definition: OdArray.h:1151
size_type logicalLength() const
Definition: OdArray.h:1070
OdArray()
Definition: OdArray.h:1283
T & at(size_type arrayIndex)
Definition: OdArray.h:1140
iterator begin()
Definition: OdArray.h:751
const T & operator[](size_type index) const
Definition: OdArray.h:1119
const T * getPtr() const
Definition: OdArray.h:1102
void reserve(size_type reserveLength)
Definition: OdArray.h:920
void insert(iterator before, const_iterator first, const_iterator afterLast)
Definition: OdArray.h:800
iterator erase(iterator first, iterator afterLast)
Definition: OdArray.h:953
iterator insert(iterator before, size_type numElements, const T &value)
Definition: OdArray.h:1000
const T & const_reference
Definition: OdArray.h:597
iterator append()
Definition: OdArray.h:1225
T * iterator
Definition: OdArray.h:594
const T * const_iterator
Definition: OdArray.h:595
OdArray & removeLast()
Definition: OdArray.h:1242
const T * asArrayPtr() const
Definition: OdArray.h:1094
OdArray & removeFirst()
Definition: OdArray.h:1234
bool contains(const T &value, size_type start=0) const
Definition: OdArray.h:1043
friend class reallocator
Definition: OdArray.h:675
OdArray & setAll(const T &value)
Definition: OdArray.h:1328
void resize(size_type logicalLength, const T &value)
Definition: OdArray.h:834
size_type append(const T &value)
Definition: OdArray.h:1215
int growLength() const
Definition: OdArray.h:1086
iterator insert(iterator before, const T &value=T())
Definition: OdArray.h:1028
bool remove(const T &value, size_type start=0)
Definition: OdArray.h:1577
OdArray & setPhysicalLength(size_type physLength)
Definition: OdArray.h:1507
const_iterator begin() const
Definition: OdArray.h:760
OdArray & setLogicalLength(size_type logLength)
Definition: OdArray.h:1494
static void construct(T *pElement, const T &value=T())
Definition: OdArray.h:96
static void destroy(T *)
Definition: OdArray.h:166
static void constructn(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:134
unsigned int size_type
Definition: OdArray.h:51
static void constructn(T *pDestination, size_type numElements, const T &value)
Definition: OdArray.h:113
static void constructn(T *pDestination, size_type numElements)
Definition: OdArray.h:153
static void destroy(T *, size_type)
Definition: OdArray.h:177
static bool useRealloc()
Definition: OdArray.h:189
static void copy(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:62
static void move(T *pDestination, const T *pSource, size_type numElements)
Definition: OdArray.h:83
static void constructn(T *pDestination, size_type numObjects, const T &value)
Definition: OdArray.h:301
unsigned int size_type
Definition: OdArray.h:211
static void construct(T *pObject)
Definition: OdArray.h:271
static void destroy(T *objects, size_type numObjects)
Definition: OdArray.h:360
static void constructn(T *pDestination, size_type numObjects)
Definition: OdArray.h:317
static void copy(T *pDestination, const T *pSource, size_type numObjects)
Definition: OdArray.h:223
static bool useRealloc()
Definition: OdArray.h:375
static void destroy(T *pObject)
Definition: OdArray.h:349
static void move(T *pDestination, const T *pSource, size_type numObjects)
Definition: OdArray.h:249
static void constructn(T *pDestination, const T *pSource, size_type numObjects)
Definition: OdArray.h:333
static void construct(T *pObject, const T &value)
Definition: OdArray.h:285
static void destroy(T *objects, size_type numObjects)
Definition: OdArray.h:534
unsigned int size_type
Definition: OdArray.h:395
static void move(T *pDestination, const T *pSource, size_type numObjects)
Definition: OdArray.h:428
static void constructn(T *pDestination, size_type numObjects, const T &value)
Definition: OdArray.h:472
static void destroy(T *pObject)
Definition: OdArray.h:522
static void constructn(T *pDestination, size_type numObjects)
Definition: OdArray.h:488
static bool useRealloc()
Definition: OdArray.h:549
static void constructn(T *pDestination, const T *pSource, size_type numObjects)
Definition: OdArray.h:504
static void construct(T *pObject, const T &value)
Definition: OdArray.h:455
static void copy(T *pDestination, const T *pSource, size_type numObjects)
Definition: OdArray.h:407
static void construct(T *pObject)
Definition: OdArray.h:441
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
GLsizei const GLfloat * value
Definition: gles2_ext.h:302
static FIRSTDLL_EXPORT_STATIC OdArrayBuffer g_empty_array_buffer
Definition: OdArray.h:568
size_type m_nLength
Definition: OdArray.h:566
unsigned int size_type
Definition: OdArray.h:561
int m_nGrowBy
Definition: OdArray.h:564
OdRefCounter m_nRefCounter
Definition: OdArray.h:563
size_type m_nAllocated
Definition: OdArray.h:565