12 #ifndef __GA_OffsetList__
13 #define __GA_OffsetList__
36 #define GA_OFFSETLIST_VERBOSE_DEBUG 0
39 template<
typename FromType,
typename ToType,
typename INT_TYPE>
47 template <
typename FromType,
typename ToType,
typename INT_TYPE=ex
int>
52 template<
typename FromType2,
typename ToType2,
typename INT_TYPE2>
54 template<
typename FromType2,
typename ToType2,
typename INT_TYPE2>
77 data->myCapacity = capacity;
78 #if GA_OFFSETLIST_VERBOSE_DEBUG
79 printf(
"Allocating %p with ref count 1 and capacity %d\n", data,
int(capacity));
94 #if GA_OFFSETLIST_VERBOSE_DEBUG
95 printf(
"Reallocating %p to %p with ref count %d from capacity %d to %d\n",
this, that,
int(that->myRefCount.relaxedLoad()),
int(that->myCapacity),
int(new_capacity));
99 that->myCapacity = new_capacity;
105 if (myCapacity >= mincapacity)
108 mincapacity =
SYSmax(mincapacity, UTbumpAlloc(myCapacity));
116 if (myCapacity == new_capacity)
127 const INT_TYPE *
src = getRawData();
128 if (new_capacity < size)
138 #if GA_OFFSETLIST_VERBOSE_DEBUG
142 #if GA_OFFSETLIST_VERBOSE_DEBUG
143 printf(
"Incrementing ref of %p with capacity %d from %d to %d\n",
this,
int(myCapacity),
int(new_count-1),
int(new_count));
147 printf(
"!!! ERROR: NEGATIVE REF COUNT INCREMENTED on %p !!!",
this);
154 exint new_count = myRefCount.add(-1);
155 #if GA_OFFSETLIST_VERBOSE_DEBUG
156 printf(
"Decrementing ref of %p with capacity %d from %d to %d\n",
this,
int(myCapacity),
int(new_count+1),
int(new_count));
160 printf(
"!!! ERROR: NEGATIVE REF COUNT DECREMENTED on %p !!!",
this);
171 {
return myRefCount.relaxedLoad() != 1; }
175 {
return (inclusive ?
sizeof(*
this) : 0) +
sizeof(INT_TYPE)*myCapacity; }
181 {
return myCapacity; }
187 const INT_TYPE *
start = getRawData();
188 const INT_TYPE
offset = start[0];
189 for (INT_TYPE
i = 1;
i <
size;
i++)
191 if (start[
i] != offset+
i)
202 const INT_TYPE *
data = getRawData();
203 INT_TYPE prev = data[0];
206 INT_TYPE cur = data[
i];
223 FromType
remove(FromType
i, FromType
size)
225 if (
i < FromType(0) ||
i >=
size)
228 INT_TYPE *
start = getRawData();
229 for (FromType j =
i+1; j <
size; ++j)
231 start[j-1] = start[j];
237 INT_TYPE *array = getRawData();
239 const INT_TYPE *
end = array +
size;
240 for (; p !=
end; ++p)
244 FromType idx(p - array);
245 for (FromType j = idx+1; j <
size; ++j)
247 array[j-1] = array[j];
256 INT_TYPE *
start = getRawData();
258 const INT_TYPE *
end = start +
size;
259 INT_TYPE *dest =
start;
262 if (*src != INT_TYPE(v))
271 FromType
find(ToType
v, FromType s, FromType
size)
const
273 const INT_TYPE *array = getRawData();
274 const INT_TYPE *p = array + s;
275 const INT_TYPE *
end = array +
size;
276 for (; p !=
end; ++p)
279 return FromType(p - array);
283 FromType findSorted(ToType
v, FromType s, FromType
size)
const;
289 return ((INT_TYPE *)(
this+1))[
index];
294 return ((
const INT_TYPE *)(
this+1))[
index];
298 { (*this)(
index) = value; }
301 {
return ToType((*
this)(
index)); }
304 INT_TYPE *
start = getRawData();
305 for (INT_TYPE
i = 0;
i < INT_TYPE(size); ++
i)
306 start[
i] = INT_TYPE(value);
313 INT_TYPE *array = getRawData();
314 if (offset == ToType(0))
317 array[
i] = ToType(data[
i]);
322 array[
i] = ToType(data[
i]) +
offset;
328 INT_TYPE *array = getRawData();
330 array[
i + destindex] = values[
i + srcindex] + offset;
335 INT_TYPE *array = getRawData();
340 array[
i + destindex] = combined +
i;
346 array[
i + destindex] = src[
i + srcindex] + offset;
358 array.
cycle(howMany);
363 INT_TYPE *array = getRawData();
364 std::reverse(array, array+size);
369 INT_TYPE *array = getRawData();
370 std::sort(array, array+size, std::less<INT_TYPE>());
375 if (size <= FromType(1))
378 INT_TYPE *array = getRawData();
380 std::sort(array, end, std::less<INT_TYPE>());
383 const INT_TYPE *
src = array+1;
384 INT_TYPE *dest = array+1;
385 INT_TYPE prev = array[0];
397 return FromType(dest-array);
402 const INT_TYPE *array = getRawData();
403 for ( ; start <
end; start++)
405 if (ToType(array[start]) == search)
412 const INT_TYPE *array = getRawData();
413 for ( ; start <
end; start++)
415 if (ToType(array[start]) != search)
423 const INT_TYPE *array = getRawData();
424 for ( ; start <
end; start++)
433 const INT_TYPE *array = getRawData();
434 for ( ; start <
end; start++)
445 return (
const INT_TYPE *)(
this+1);
450 return (INT_TYPE *)(
this+1);
473 #if GA_OFFSETLIST_VERBOSE_DEBUG
476 printf(
"%p listref copy constructor with data %p from %p\n",
this, src.
myData, &src);
481 memcpy(
this, &src,
sizeof(*
this));
488 #if GA_OFFSETLIST_VERBOSE_DEBUG
489 if (!
src.isTrivial())
491 printf(
"%p listref move constructor with data %p from %p\n",
this,
src.myData, &
src);
495 memcpy(
this, &
src,
sizeof(*
this));
501 UT_ASSERT_MSG(0,
"GA_ListTypeRef cannot be move-constructed from GA_ListType, because the data will be invalid momentarily.");
510 myTrivialOffset = startvalue;
511 myIsFlagSet = flag_set;
527 #if GA_OFFSETLIST_VERBOSE_DEBUG
530 printf(
"%p listref copy constructor with data %p from %p\n",
this, src.
myData, &src);
535 memcpy(
this, &src,
sizeof(*
this));
543 #if GA_OFFSETLIST_VERBOSE_DEBUG
544 if (!
src.isTrivial())
546 printf(
"%p listref move constructor with data %p from %p\n",
this,
src.myData, &
src);
551 memcpy(
this, &
src,
sizeof(*
this));
558 UT_ASSERT_MSG(0,
"GA_ListTypeRef cannot be move-assigned from GA_ListType, because the data will be invalid momentarily.");
581 myTrivialOffset = startvalue;
592 myTrivialOffset = startvalue;
601 return isTrivial() ? 0 : myData->capacity();
611 return FromType(mySize);
635 (mySize == that.
mySize) &&
638 return (myData == that.
myData);
642 bool isAscending()
const;
647 FromType find(ToType
value, FromType s = FromType(0))
const;
650 FromType findSorted(ToType value, FromType s=FromType(0))
const;
659 : myData->get(
index);
667 return ToType(myTrivialOffset);
672 FromType
start, FromType
end)
const;
677 exint last_index = mySize-1;
679 ? ToType(myTrivialOffset+last_index)
680 : myData->get(FromType(last_index));
693 FromType matchingindex = FromType(
GA_Size(search) -
GA_Size(myTrivialOffset));
694 if (matchingindex >= start && matchingindex < end)
695 return matchingindex;
699 return myData->findInRange(start, end, search);
705 FromType matchingindex = FromType(
GA_Size(search) -
GA_Size(myTrivialOffset));
707 if (matchingindex != start)
714 return myData->findInRangeNotEqual(start, end, search);
728 return myData->findValidInRange(start, end);
742 return myData->findInvalidInRange(start, end);
747 template<
typename FUNCTOR>
753 ToType
value(myTrivialOffset);
754 const ToType
end(value + mySize);
762 const INT_TYPE *
data = myData->getRawData();
763 const INT_TYPE *
const end = data + mySize;
766 functor(ToType(*data));
775 return (inclusive ?
sizeof(*
this) : 0) + (!isTrivial() ? myData->getMemoryUsage(
true) : 0);
779 static const intptr_t POINTER_MASK = ~0x1;
780 static const intptr_t TRIVIAL_MASK = 0x1;
782 #ifndef SESI_LITTLE_ENDIAN
783 #error "Make sure the bitfields in the union work on big endian platforms!"
804 template <
typename FromType,
typename ToType,
typename INT_TYPE=ex
int>
809 template<
typename FromType2,
typename ToType2,
typename INT_TYPE2>
811 template<
typename FromType2,
typename ToType2,
typename INT_TYPE2>
853 #if GA_OFFSETLIST_VERBOSE_DEBUG
854 printf(
"%p adding reference to %p (orig reference by list %p) in copy constructor\n",
this, src.
myData, &src);
860 memcpy(
this, &src,
sizeof(*
this));
868 #if GA_OFFSETLIST_VERBOSE_DEBUG
869 if (!
src.isTrivial())
871 printf(
"%p stealing reference to %p (orig reference by list %p) in move constructor\n",
this,
src.myData, &
src);
875 memcpy(
this, &
src,
sizeof(*
this));
876 src.myIsTrivial =
true;
890 #if GA_OFFSETLIST_VERBOSE_DEBUG
891 printf(
"%p adding reference to %p (orig reference by listref %p) in list(listref) type conversion constructor\n",
this, src.
myData, &src);
898 memcpy(
this, &src,
sizeof(*
this));
904 :
Base(startvalue, size, flag_set)
916 #if GA_OFFSETLIST_VERBOSE_DEBUG
917 printf(
"%p removing reference to %p in desctructor\n",
this,
myData);
930 #if GA_OFFSETLIST_VERBOSE_DEBUG
931 printf(
"%p removing reference to %p in copy assignment operator\n",
this,
myData);
938 #if GA_OFFSETLIST_VERBOSE_DEBUG
939 printf(
"%p adding reference to %p (orig reference by list %p) in copy assignment operator\n",
this, src.
myData, &src);
945 memcpy(
this, &src,
sizeof(*
this));
955 #if GA_OFFSETLIST_VERBOSE_DEBUG
956 printf(
"%p removing reference to %p in move assignment operator\n",
this,
myData);
961 #if GA_OFFSETLIST_VERBOSE_DEBUG
962 if (!src.isTrivial())
964 printf(
"%p stealing reference to %p (orig reference by list %p) in move assignment operator\n",
this, src.myData, &src);
969 memcpy(
this, &src,
sizeof(*
this));
970 src.myIsTrivial =
true;
984 #if GA_OFFSETLIST_VERBOSE_DEBUG
985 printf(
"%p removing reference to %p in copy-from-listref assignment operator\n",
this,
myData);
992 #if GA_OFFSETLIST_VERBOSE_DEBUG
993 printf(
"%p adding reference to %p (orig reference by listref %p) in copy-from-listref assignment operator\n",
this, src.
myData, &src);
1000 memcpy(
this, &src,
sizeof(*
this));
1019 #if GA_OFFSETLIST_VERBOSE_DEBUG
1020 printf(
"%p removing reference to %p in clear function\n",
this,
myData);
1042 #if GA_OFFSETLIST_VERBOSE_DEBUG
1043 printf(
"%p removing reference to %p in setTrivial(start,size)\n",
this,
myData);
1060 #if GA_OFFSETLIST_VERBOSE_DEBUG
1061 printf(
"%p removing reference to %p in setTrivial(start,size,flag)\n",
this,
myData);
1075 void setEntries(FromType sz,
bool doresize=
true);
1079 void reserve(FromType mincapacity);
1100 return FromType(
mySize-1);
1106 return FromType(
mySize-1);
1114 FromType
insert(FromType
i, ToType value);
1121 FromType
remove(FromType
i);
1160 template<
typename S>
1169 ToType
first = ToType(data[0]);
1170 bool istrivial =
true;
1173 if (ToType(data[
i]) != first + ToType(i))
1187 newdata->set(data, size, offset);
1197 bool ismatch =
true;
1219 bool ismatch =
true;
1236 FromType endindex = startindex + nelements;
1239 if (startindex == FromType(0) && nelements >=
mySize)
1247 if (endindex > FromType(
mySize))
1252 else if (startindex == FromType(0) && nelements >=
mySize)
1263 data->
set(startindex +
i, startvalue +
i);
1282 INT_TYPE *array = data->getRawData();
1285 #if GA_OFFSETLIST_VERBOSE_DEBUG
1286 printf(
"%p taking ownership of new %p in harden()\n",
this, data);
1296 #if GA_OFFSETLIST_VERBOSE_DEBUG
1297 printf(
"%p removing reference to %p in harden(), and taking ownership of new %p\n",
this,
myData, data);
1320 INT_TYPE *array = data->getRawData();
1321 if (mincapacity <
mySize)
1325 #if GA_OFFSETLIST_VERBOSE_DEBUG
1326 printf(
"%p taking ownership of new %p in harden(mincapacity)\n",
this, data);
1336 #if GA_OFFSETLIST_VERBOSE_DEBUG
1337 printf(
"%p removing reference to %p in harden(mincapacity), and taking ownership of new %p\n",
this,
myData, data);
1350 if (mincapacity <
mySize)
1355 #if GA_OFFSETLIST_VERBOSE_DEBUG
1356 printf(
"%p bumping capacity of %p, current capacity = %d in harden(mincapacity=%d)\n",
this,
myData,
int(mincapacity),
int(
myData->
capacity()));
1359 #if GA_OFFSETLIST_VERBOSE_DEBUG
1378 #if GA_OFFSETLIST_VERBOSE_DEBUG
1379 printf(
"%p adding reference to %p in incDataRef()\n",
this,
myData);
1390 template <
typename FromType,
typename INT_TYPE=ex
int>
1436 #if GA_OFFSETLIST_VERBOSE_DEBUG
1437 printf(
"%p removing reference to %p in GA_OffsetListType move assignment operator\n",
this, myData);
1442 #if GA_OFFSETLIST_VERBOSE_DEBUG
1443 if (!src.isTrivial())
1445 printf(
"%p stealing reference to %p (orig reference by list %p) in GA_OffsetListType move assignment operator\n",
this, src.myData, &src);
1450 memcpy(
this, &src,
sizeof(*
this));
1451 src.myIsTrivial =
true;
1515 bool jsonSaveTranslatedArray(
SYS_FORCE_INLINE void clear()
clear removes all of the entries
A class to manage an ordered array which has fixed offset handles.
SYS_FORCE_INLINE GA_ListType()
Default constructor.
#define UT_ASSERT_COMPILETIME(expr)
FromType multipleInsert(FromType i, GA_Size count)
void reverse()
Reverse the entire array.
SYS_FORCE_INLINE GA_ListType(const GA_ListType &src)
Copy constructor.
void harden(exint mincapacity)
void copyAdd(FromType destindex, const GA_ListTypeRef< FromType, ToType, S > &values, FromType srcindex, GA_Size n, ToType offset)
SYS_FORCE_INLINE GA_OffsetListType & operator=(const GA_OffsetListType &src)
Copy assignment operator.
SYS_FORCE_INLINE GA_ListType(ToType startvalue, GA_Size size, bool flag_set=false)
Trivial list constructor.
FromType append(ToType value)
Add a single entry (may grow array)
Used to pass options and map offset values during saving.
FromType findInRange(FromType start, FromType end, ToType search) const
SYS_FORCE_INLINE void set(FromType index, ToType value)
void copyAdd(FromType destindex, const int *values, GA_Size srcindex, GA_Size n, ToType offset)
SYS_FORCE_INLINE GA_OffsetListType & operator=(GA_OffsetListType &&src)
Move assignment operator.
SYS_FORCE_INLINE void setTrivial(ToType startvalue, GA_Size size)
Makes the list a trivial list with the specified start value and size.
GA_OffsetListType(const GA_OffsetListType &src)
void sortAndRemoveDuplicates()
Sort entries into ascending order and remove duplicates.
GA_OffsetListType< GA_Size > GA_OffsetList
GA_OffsetList is a map from index to offset.
bool GAisValid(GA_Size v)
FromType findInRangeNotEqual(FromType start, FromType end, ToType search) const
SYS_FORCE_INLINE int64 getMemoryUsage(bool inclusive) const
void constant(ToType value)
Set all entries to a constant value.
ListTypeData * reallocate(exint new_capacity)
void copyAdd(FromType destindex, const GA_ListTypeRef< FromType, ToType > &values, FromType srcindex, GA_Size n, ToType offset)
SYS_FORCE_INLINE bool getExtraFlag() const
void reserve(FromType mincapacity)
void setTrivial(ToType startvalue, GA_Size size)
Makes the list a trivial list with the specified start value and size.
FromType findInRangeNotEqual(FromType start, FromType end, ToType search) const
void setTrivialRange(FromType startindex, ToType startvalue, GA_Size nelements)
void reverse(FromType size)
JSON reader class which handles parsing of JSON or bJSON files.
Class which writes ASCII or binary JSON streams.
SYS_FORCE_INLINE GA_ListTypeRef(GA_ListTypeRef &&src)
Move constructor.
FromType findInvalidInRange(FromType start, FromType end) const
typename Base::ListTypeData ListTypeData
GA_ListTypeRef< GA_Size, GA_Offset > GA_OffsetListRef
SYS_FORCE_INLINE GA_ListType & operator=(const Base &src)
FromType findValidInRange(FromType start, FromType end) const
SYS_FORCE_INLINE GA_ListType & operator=(const GA_ListType &src)
Copy assignment operator.
SYS_FORCE_INLINE void forEach(FUNCTOR &&functor) const
exint GA_Size
Defines the bit width for index and offset types in GA.
SYS_FORCE_INLINE GA_ListTypeRef()
Default constructor.
SYS_FORCE_INLINE int64 getMemoryUsage(bool inclusive) const
Report memory usage (includes all shared memory)
SYS_FORCE_INLINE ~GA_ListTypeRef()
Destructor.
void set(FromType index, ToType value)
Set the index to the value.
GA_OffsetListType(const GA_ListTypeRef< FromType, GA_Offset, INT_TYPE > &src)
SYS_FORCE_INLINE INT_TYPE * getRawData()
SYS_FORCE_INLINE bool isTrivial() const
ListTypeData * setCapacity(exint new_capacity)
unsigned long long uint64
void removeLast()
Remove the last entry.
SYS_FORCE_INLINE INT_TYPE & operator()(exint index)
SYS_FORCE_INLINE GA_ListType(const Base &src)
bool isAscending(exint size) const
FromType findAndRemove(ToType i)
Find an entry and remove it from the list.
void cycle(GA_Size howMany)
Cyclically shift the entire array by howMany.
FromType findValidInRange(FromType start, FromType end) const
SYS_FORCE_INLINE GA_ListType & operator=(GA_ListType &&src)
Move assignment operator.
void countMemory(UT_MemoryCounter &counter, bool inclusive) const
static const intptr_t POINTER_MASK
ListTypeData * copy(exint size, exint new_capacity) const
SYS_FORCE_INLINE GA_ListTypeRef(ToType startvalue, GA_Size size, bool flag_set=false)
Trivial list constructor.
SYS_FORCE_INLINE const INT_TYPE & operator()(exint index) const
void changeSize(FromType new_capacity)
SYS_FORCE_INLINE GA_ListTypeRef(const GA_ListTypeRef &src)
Copy constructor.
GLenum GLsizei GLsizei GLint * values
Defragmentation of IndexMaps.
GA_Size removeAll(ToType v, FromType size)
FromType findAndRemove(ToType v, FromType size)
SYS_FORCE_INLINE const INT_TYPE * getRawData() const
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
void unsafeShareData(UT_Array< T > &src)
void cycle(exint howMany)
Cyclically shifts the entire array by howMany.
SYS_FORCE_INLINE ToType operator()(FromType i) const
Convenience () operator to access the list entries.
bool isSame(const GA_ListTypeRef &that) const
ToType last() const
Return the value of the last element.
GA_Size removeAll(ToType i)
Remove all matching entries from the list.
SYS_FORCE_INLINE GA_Size capacity() const
Returns the allocated capacity of the list.
void sortAscending(FromType size)
GLsizei const GLfloat * value
SYS_FORCE_INLINE GA_ListType(GA_ListType &&src)
Move constructor.
#define UT_ASSERT_MSG_P(ZZ, MM)
FromType insert(FromType i, ToType value)
Insert a single entry (may grow array)
static const intptr_t TRIVIAL_MASK
SYS_FORCE_INLINE void setExtraFlag(bool v)
void setTrivial(ToType startvalue, GA_Size size, bool flag)
SYS_FORCE_INLINE void setTrivial(ToType startvalue, GA_Size size, bool flag)
void setEntries(FromType sz, bool doresize=true)
SYS_FORCE_INLINE GA_Size capacity() const
void set(const S *data, exint size, ToType offset)
FromType findInvalidInRange(FromType start, FromType end) const
FromType findInRange(FromType start, FromType end, ToType search) const
SYS_FORCE_INLINE ToType get(FromType index) const
Get the the value at the index.
FromType sortAndRemoveDuplicates(FromType size)
FromType find(ToType v, FromType s, FromType size) const
SYS_FORCE_INLINE GA_ListTypeRef & operator=(GA_ListTypeRef &&src)
Move assignment operator.
GA_OffsetListType(const UT_ValArray< GA_Offset > &src, FromType start=FromType(0), FromType end=FromType(-1))
GLubyte GLubyte GLubyte GLubyte w
void cycle(GA_Size howMany, FromType size)
SYS_FORCE_INLINE GA_OffsetListType & operator=(const GA_ListTypeRef< FromType, GA_Offset, INT_TYPE > &src)
SYS_FORCE_INLINE ToType trivialStart() const
Returns the start, assuming this list is trivial.
SYS_FORCE_INLINE void relaxedStore(T val)
SYS_FORCE_INLINE ~GA_ListType()
Destructor.
png_infop png_uint_32 flag
FromType removeIndex(FromType i)
Alias for remove to match UT array types.
void constant(ToType value, FromType size)
void sortAscending()
Sort entries into ascending order.
void copyAdd(FromType destindex, const S *values, GA_Size srcindex, GA_Size n, ToType offset)
void set(const S *data, exint size, ToType offset)
#define UT_ASSERT_MSG(ZZ, MM)
SYS_FORCE_INLINE void clear()
clear removes all of the entries
static ListTypeData * allocate(exint capacity)
bool isTrivial(exint size) const
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
SYS_FORCE_INLINE GA_ListTypeRef & operator=(const GA_ListTypeRef &src)
Copy assignment operator.
SYS_FORCE_INLINE FromType entries() const
Returns the number of used elements in the list (always <= capacity())
ListTypeData * bumpCapacity(exint mincapacity)