49 #ifndef __UT_ARRAY_H_INCLUDED__
50 #define __UT_ARRAY_H_INCLUDED__
68 #include <initializer_list>
70 #include <type_traits>
79 #undef UT_ARRAY_STRICT_LABELED_CAPACITY
125 explicit
UT_Array(std::initializer_list<
T> init);
148 if (check_dup && ((idx =
find(t)) != -1))
166 template <
typename...
S>
177 const UT_ArrayCT::ExternalCapacity,
179 const exint external_capacity
183 const UT_ArrayCT::ExternalMove,
185 const exint external_capacity,
196 const UT_ArrayCT::GeneralizedMove,
203 template <
typename Y>
213 template <
typename F>
214 using IsBoolComp = decltype(std::declval<F>()(std::declval<T>(),
226 template <typename ComparatorBool = Less<
T>,
227 typename = IsBoolComp<ComparatorBool>>
236 template <
typename ComparatorBool = Less<T>,
237 typename = IsBoolComp<ComparatorBool>>
248 template <
typename ComparatorBool = Less<T>,
249 typename = IsBoolComp<ComparatorBool>>
251 ComparatorBool is_less = {})
const;
262 template <typename ComparatorBool = Less<
T>>
264 bool allow_dups, ComparatorBool is_less = {});
266 template <
typename ComparatorBool = Less<T>,
267 typename = IsBoolComp<ComparatorBool>>
269 ComparatorBool is_less = {})
const;
271 template <
typename ComparatorBool = Less<T>,
272 typename = IsBoolComp<ComparatorBool>>
275 ComparatorBool is_less = {});
276 template <
typename ComparatorBool = Less<T>,
277 typename = IsBoolComp<ComparatorBool>>
281 ComparatorBool is_less = {})
const;
282 template <
typename ComparatorBool = Less<T>,
283 typename = IsBoolComp<ComparatorBool>>
286 ComparatorBool is_less = {});
287 template <
typename ComparatorBool = Less<T>,
288 typename = IsBoolComp<ComparatorBool>>
292 ComparatorBool is_less = {})
const;
293 template <
typename ComparatorBool = Less<T>,
294 typename = IsBoolComp<ComparatorBool>>
297 ComparatorBool is_less = {});
298 template <
typename ComparatorBool = Less<T>,
299 typename = IsBoolComp<ComparatorBool>>
303 ComparatorBool is_less = {})
const;
367 {
return (index >= 0 && index < mySize); }
373 template <
typename S>
383 exint idx = --mySize;
384 destroyElement(myData[idx]);
403 template <
typename IsEqual>
407 template <
typename IsEqual>
430 template <
typename S>
448 return (&t >= myData && &t < (myData + mySize))
454 template <
typename ComparatorBool = Less<T>,
455 typename = IsBoolComp<ComparatorBool>>
456 void sort(ComparatorBool is_less = {})
458 std::sort(myData, myData + mySize, is_less);
468 template <typename ComparatorBool,
469 typename = IsBoolComp<ComparatorBool>>
473 std::sort(myData, myData + mySize, is_less);
484 template<
typename ComparatorBool = Less<T>>
495 template<
typename ComparatorBool>
508 std::stable_sort(
array() + start,
array() + end, is_less);
512 template <
typename I,
typename V,
typename ComparatorBool>
522 {
return myCompare(myValues(a), myValues(b)); }
525 const ComparatorBool &myCompare;
536 template <
typename I,
typename ComparatorBool>
538 ComparatorBool is_less)
const
540 IndexedCompare<I, T, ComparatorBool>
compare(*
this, is_less);
541 std::stable_sort(indices.
getArray(),
548 template <
typename I,
typename ComparatorBool>
550 ComparatorBool is_less)
const
561 template <
typename K,
typename ComparatorBool>
579 template <
typename CompareEqual>
586 template<
typename ComparatorBool = Less<T>>
597 template <
typename ComparatorBool = Less<T>>
619 exint new_capacity = min_capacity;
620 if (bumped > min_capacity)
621 new_capacity = bumped;
659 return (inclusive ?
sizeof(*
this) : 0) +
capacity()*
sizeof(
T);
670 if (newsize == mySize)
673 if (mySize > newsize)
674 destroyRange(myData + newsize, mySize - newsize);
676 constructRange(myData + mySize, newsize - mySize);
681 if (
size() >= minsize)
699 if (newsize == mySize)
702 if (mySize > newsize)
703 destroyRange(myData + newsize, mySize - newsize);
705 constructRange(myData + mySize, newsize - mySize);
712 if (maxsize >= 0 &&
size() > maxsize)
721 destroyRange(myData, mySize);
793 return (i >= 0 && i < mySize) ? myData[i] :
T();
799 return myData[mySize-1];
804 return myData[mySize-1];
813 template <
typename BinaryOp>
820 const T *
array()
const {
return myData; }
823 const T *
data()
const {
return myData; }
828 {
T *
data = myData; myData = newdata;
return data; }
830 template <
typename IT,
bool FORWARD>
846 template<
typename EIT>
848 : myCurrent(src.myCurrent), myEnd(src.myEnd) {}
851 {
return FORWARD ? myCurrent : myCurrent - 1; }
854 {
return FORWARD ? *myCurrent : myCurrent[-1]; }
857 {
return FORWARD ? *myCurrent : myCurrent[-1]; }
860 {
return FORWARD ? myCurrent[
n] : myCurrent[-n - 1]; }
865 if (FORWARD) ++myCurrent;
else --myCurrent;
872 if (FORWARD) ++myCurrent;
else --myCurrent;
878 if (FORWARD) --myCurrent;
else ++myCurrent;
885 if (FORWARD) --myCurrent;
else ++myCurrent;
906 {
return (*
this) += (-
n); }
908 {
return (*
this) + (-
n); }
910 bool atEnd()
const {
return myCurrent == myEnd; }
914 template<
typename ITR,
bool FR>
916 {
return myCurrent == r.myCurrent; }
918 template<
typename ITR,
bool FR>
920 {
return myCurrent != r.myCurrent; }
922 template<
typename ITR>
923 bool operator<(const base_iterator<ITR, FORWARD> &
r)
const
926 return myCurrent <
r.myCurrent;
928 return r.myCurrent < myCurrent;
931 template<
typename ITR>
935 return myCurrent > r.myCurrent;
937 return r.myCurrent > myCurrent;
940 template<
typename ITR>
941 bool operator<=(const base_iterator<ITR, FORWARD> &
r)
const
944 return myCurrent <=
r.myCurrent;
946 return r.myCurrent <= myCurrent;
949 template<
typename ITR>
953 return myCurrent >= r.myCurrent;
955 return r.myCurrent >= myCurrent;
959 template<
typename ITR>
963 return exint(myCurrent - r.myCurrent);
965 return exint(r.myCurrent - myCurrent);
988 return iterator(myData, myData + mySize);
1046 removeAt(&it.item() - myData);
1055 myData = src.myData;
1056 myCapacity = labelExternal( src.
capacity() );
1057 mySize = src.mySize;
1062 myCapacity = labelExternal( srcsize );
1069 myCapacity = labelExternal( capacity );
1074 myCapacity = labelExternal( 0 );
1091 return SYS_IsPod_v< T >;
1097 template <
typename S>
1101 template <
typename S>
1104 template <
typename S>
1110 template <typename First, typename... Rest>
1114 static_cast<const void *>(&first) <
1115 static_cast<const void *>(myData) ||
1116 static_cast<const void *>(&first) >=
1117 static_cast<const void *>(myData + mySize),
1118 "Argument cannot reference an existing element in the array.");
1129 template <
typename...
S>
1132 new (&
dst)
T(std::forward<S>(
s)...);
1138 if constexpr( SYS_IsPod_v< T > )
1152 class AppendIterator
1155 using iterator_category = std::output_iterator_tag;
1157 using difference_type =
void;
1159 using reference =
void;
1161 explicit AppendIterator(
UT_Array<T> &arr) : myArray(&arr) {}
1167 myArray->append(val);
1173 myArray->append(std::move(val));
1180 AppendIterator &
operator*() {
return *
this; }
1181 AppendIterator &operator++() {
return *
this; }
1182 AppendIterator operator++(
int) {
return *
this; }
1189 #ifdef UT_ARRAY_STRICT_LABELED_CAPACITY
1199 LabeledCapacity myCapacity;
1205 static LabeledCapacity labelOwned(
const exint capacity) noexcept;
1208 static LabeledCapacity labelExternal(
const exint capacity) noexcept;
1225 static void deallocateArray(
T *
data) noexcept;
1251 static void constructElement(
T &
dst);
1254 static void destroyElement(
T &
dst) noexcept;
1255 static void destroyRange([[maybe_unused]]
T *
dst,
exint n) noexcept;
1293 static void bitwiseRelocate(
T *
dst,
const T *
src,
exint n) noexcept;
1298 static void bitwiseRelocateNonoverlapping(
1347 template<
typename OS,
typename S>
1348 friend OS &operator<<(OS &os, const UT_Array<S> &d);
1364 template <
typename T,
typename S>
1371 for (
exint i = 0; i <
n; i++)
1372 dest(i) =
T(
src(i));
1374 template <
typename T,
typename S>
1380 for (
exint i = 0; i <
n; i++)
1381 dest(i) =
T(src[i]);
1383 template <
typename T,
typename S>
1389 for (
exint i = 0; i <
n; i++)
1390 dest[i] =
T(
src(i));
1392 template <
typename T,
typename S>
1397 for (
int64 i = 0; i <
n; i++)
1398 dest[i] =
T(src[i]);
1404 template<
typename OS,
typename S>
1406 operator<<(OS &os, const UT_Array<S> &d)
1413 template <
typename T>
UT_API size_t
1418 template <
template <
typename>
class ArrayT,
typename T>
1420 UTarrayDeepMemoryUsage(
const ArrayT<T> &arr,
bool inclusive)
1422 int64 mem = inclusive ?
sizeof(arr) : 0;
1423 mem += arr.getMemoryUsage(
false);
1424 for (
auto &&item : arr)
1425 mem += item.getMemoryUsage(
false);
1430 template <
typename T>
1434 arr.
sort([](
const T &
a,
const T &
b) {
return a <
b; });
1438 template <
typename T>
1448 template <
typename T>
1449 struct DefaultClearer;
1451 template <
typename T>
1460 static const bool clearNeedsDestruction =
false;
1476 template <
typename T>
1483 #if defined(MBSD) || defined(_LIBCPP_VERSION)
1485 template <
typename CharT,
typename Traits,
typename Allocator>
1487 #elif defined(__GLIBCXX__)
1488 #include <bits/stringfwd.h>
1489 template <
typename CharT,
typename Traits,
typename Allocator>
1493 template <
typename CharT,
typename Traits,
typename Allocator>
1497 #endif // __UT_ARRAY_H_INCLUDED__
reference operator*() const
base_iterator & operator++()
Pre-increment operator.
int isEqual(const UT_Array< T > &a, Comparator compare) const
base_iterator & operator--()
Pre-decrement operator.
exint insert(T &&t, exint i)
IndexedCompare(const UT_Array< V > &values, const ComparatorBool &compare)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
const T & operator[](exint i) const
void merge(const UT_Array< T > &other, int direction, bool allow_dups, ComparatorBool is_less={})
const T * getRawArray() const
bool isHeapBuffer() const
Returns true if the data used by the array was allocated on the heap.
pointer operator->() const
base_iterator operator+(exint n) const
GLenum GLuint GLsizei bufsize
void validateEmplaceArgs() const
Base case for validateEmplaceArgs().
GLsizei GLenum const void * indices
std::make_unsigned_t< exint > UT_LabeledCapacityRep
bool operator!=(const UT_Array< T > &a) const
void stableSort(ComparatorBool is_less={})
void bumpCapacity(exint min_capacity)
void setSizeIfNeeded(exint minsize)
exint insertImpl(S &&s, exint index)
Similar to appendImpl() but for insertion.
SYS_FORCE_INLINE void removeLast()
void unsafeShareData(T *src, exint size, exint capacity)
exint findAndRemove(const S &s)
UT_Array< T > & operator=(const UT_Array< T > &a)
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
void extractRange(exint begin_i, exint end_i, UT_Array< T > &dest)
void collapseIf(IsEqual is_equal)
Remove all matching elements. Also sets the capacity of the array.
T * aliasArray(T *newdata)
void setSizeNoInit(exint newsize)
bool isValidIndex(exint index) const
Return true if given index is valid.
#define SYS_DEPRECATED_HDK_REPLACE(__V__, __R__)
void zero()
Zeros the array if a POD type, else trivial constructs if a class type.
base_iterator< const T, false > const_reverse_iterator
friend void swap(UT_Array< T > &a, UT_Array< T > &b)
UT_API size_t format(char *buffer, size_t bufsize, const UT_Array< T > &v)
exint uniqueSortedFind(const T &item, ComparatorBool is_less={}) const
void move(exint src_idx, exint dst_idx, exint how_many)
const_iterator begin() const
int64 getMemoryUsage(bool inclusive=false) const
void bumpEntries(exint newsize)
const T & heapMax() const
GLboolean GLboolean GLboolean GLboolean a
void cycle(exint how_many)
Cyclically shifts the entire array by how_many.
exint removeIndex(exint index)
static constexpr struct UT_ArrayCT::GeneralizedMove GENERALIZED_MOVE
const_reverse_iterator rend() const
End reverse iterator. Consider using it.atEnd() instead.
void setCapacity(exint new_capacity)
static constexpr SYS_FORCE_INLINE bool isPOD()
exint concat(const UT_Array< T > &a)
Takes another T array and concatenate it onto my end.
exint append(const T &t, bool check_dup)
**But if you need a result
#define UT_ASSERT_MSG_P(ZZ,...)
exint index(const T &t) const
bool operator>=(const base_iterator< ITR, FORWARD > &r) const
exint uniqueSortedInsert(const T &t, Comparator compare)
exint find(const S &s, exint start=0) const
static bool isClear(const UT_Array< T > &v)
void setSize(exint newsize)
bool operator==(const base_iterator< ITR, FR > &r) const
void sortedUnion(const UT_Array< T > &other, ComparatorBool is_less={})
base_iterator operator-(exint n) const
void bumpSize(exint newsize)
bool operator>(const base_iterator< ITR, FORWARD > &r) const
base_iterator< T, false > reverse_iterator
void unsafeShareData(T *src, exint srcsize)
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
exint operator-(const base_iterator< ITR, FORWARD > &r) const
exint sortAndRemoveDuplicates(ComparatorBool is_less={})
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
const_reverse_iterator rbegin() const
Begin iterating over the array in reverse.
exint safeIndex(const T &t) const
void stableSortByKey(const UT_Array< K > &keys, ComparatorBool is_less)
exint apply(int(*apply_func)(T &t, void *d), void *d)
reverse_iterator rbegin()
Begin iterating over the array in reverse.
exint emplace_back(S &&...s)
static void construct(T &dst, S &&...s)
void entries(exint newsize)
Alias of setSize(). setSize() is preferred.
exint uniqueSortedInsertImpl(S &&s, Comparator compare)
const T & operator()(exint i) const
void sort(ComparatorBool is_less={})
Sort using std::sort with bool comparator. Defaults to operator<().
reference operator[](exint n) const
exint insertAt(const T &t, exint index)
T accumulate(const T &init_value, BinaryOp add) const
base_iterator< T, true > iterator
static void clearConstruct(UT_Array< T > *p)
exint sortedInsert(const T &t, Comparator compare)
UT_IteratorRange< reverse_iterator > rrange()
exint insert(const T &t, exint i)
base_iterator(const base_iterator< EIT, FORWARD > &src)
void appendMultiple(const T &t, exint count)
IMATH_HOSTDEVICE constexpr Color4< T > operator*(S a, const Color4< T > &v) IMATH_NOEXCEPT
Reverse multiplication: S * Color4.
base_iterator(IT *c, IT *e)
void stableSortRange(ComparatorBool is_less, exint start, exint end)
Like stableSort, but operates on a subset of the array.
static constexpr struct UT_ArrayCT::ExternalCapacity EXTERNAL_CAPACITY
T forcedGet(exint i) const
static void copyConstruct(T &dst, const T &src)
void setCapacityIfNeeded(exint min_capacity)
#define SYS_DEPRECATED_HDK(__V__)
exint removeIf(IsEqual is_equal)
const_iterator end() const
End const iterator. Consider using it.atEnd() instead.
base_iterator & operator-=(exint n)
exint sortedRemoveDuplicates()
void sortedSetDifference(const UT_Array< T > &other, ComparatorBool is_less={})
GLboolean GLboolean GLboolean b
void unsafeShareData(UT_Array< T > &src)
reverse_iterator rend()
End reverse iterator.
bool operator()(I a, I b) const
bool operator!=(const base_iterator< ITR, FR > &r) const
exint sortedRemoveDuplicatesIf(CompareEqual compare_equal)
exint entries() const
Alias of size(). size() is preferred.
T selectNthLargest(exint idx, ComparatorBool is_less={})
base_iterator & operator+=(exint n)
void stdsort(ComparatorBool is_less)
Sort using std::sort. The ComparatorBool uses the less-than semantics.
#define SYS_DECLARE_IS_NOT_TR_TEMPLATE(...)
Version for class template.
static constexpr struct UT_ArrayCT::ExternalMove EXTERNAL_MOVE
GLenum GLsizei GLsizei GLint * values
base_iterator operator--(int)
Post-decrement operator.
static void clear(UT_Array< T > &v)
int(* Comparator)(const T *, const T *)
UT_EXTERN_TEMPLATE(UT_Array< UT_StringHolder >)
base_iterator< const T, true > const_iterator
void stableArgSort(UT_Array< I > &indices, ComparatorBool is_less) const
void truncate(exint maxsize)
Decreases, but never expands, to the given maxsize.
void constant(const T &v)
Quickly set the array to a single value.
void removeItem(const reverse_iterator &it)
Remove item specified by the reverse_iterator.
void sortedIntersection(const UT_Array< T > &other, ComparatorBool is_less={})
void UTconvertArray(UT_Array< T > &dest, const UT_Array< S > &src)
Comparator class for stableSortIndices.
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
UT_Array(const UT_Array< T > &a)
void clear()
Resets list to an empty list.
void stableSortIndices(UT_Array< I > &indices, ComparatorBool is_less) const
UT_IteratorRange< iterator > range()
UT_IteratorRange< const_iterator > range() const
GA_API const UT_StringHolder rest
T heapPop(Comparator compare)
std::random_access_iterator_tag iterator_category
exint heapPush(const T &t, Comparator compare)
void sort(I begin, I end, const Pred &pred)
void reverse()
Reverses the array by swapping elements in mirrored locations.
exint multipleInsert(exint index, exint count)
Insert an element "count" times at the given index. Return the index.
void removeRange(exint begin_i, exint end_i)
base_iterator operator++(int)
Post-increment operator.
void swap(UT_Array< T > &other)
exint insert(exint index)
bool hasSortedSubset(const UT_Array< T > &other, ComparatorBool is_less={}) const
iterator end()
End iterator.
UT_IteratorRange< const_reverse_iterator > rrange() const
bool isEmpty() const
Returns true iff there are no occupied elements in the array.
bool operator==(const UT_Array< T > &a) const
exint sortedFind(const T &t, Comparator compare) const