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);
725 if (maxsize >= 0 &&
size() > maxsize)
734 destroyRange(myData, mySize);
757 template <
typename ComparatorBool,
758 typename = IsBoolComp<ComparatorBool>>
813 return (i >= 0 && i < mySize) ? myData[i] :
T();
819 return myData[mySize-1];
824 return myData[mySize-1];
833 template <
typename BinaryOp>
840 const T *
array()
const {
return myData; }
843 const T *
data()
const {
return myData; }
848 {
T *
data = myData; myData = newdata;
return data; }
850 template <
typename IT,
bool FORWARD>
866 template<
typename EIT>
868 : myCurrent(src.myCurrent), myEnd(src.myEnd) {}
871 {
return FORWARD ? myCurrent : myCurrent - 1; }
874 {
return FORWARD ? *myCurrent : myCurrent[-1]; }
877 {
return FORWARD ? *myCurrent : myCurrent[-1]; }
880 {
return FORWARD ? myCurrent[
n] : myCurrent[-n - 1]; }
885 if (FORWARD) ++myCurrent;
else --myCurrent;
892 if (FORWARD) ++myCurrent;
else --myCurrent;
898 if (FORWARD) --myCurrent;
else ++myCurrent;
905 if (FORWARD) --myCurrent;
else ++myCurrent;
926 {
return (*
this) += (-
n); }
928 {
return (*
this) + (-
n); }
930 bool atEnd()
const {
return myCurrent == myEnd; }
934 template<
typename ITR,
bool FR>
936 {
return myCurrent == r.myCurrent; }
938 template<
typename ITR,
bool FR>
940 {
return myCurrent != r.myCurrent; }
942 template<
typename ITR>
943 bool operator<(const base_iterator<ITR, FORWARD> &
r)
const
946 return myCurrent <
r.myCurrent;
948 return r.myCurrent < myCurrent;
951 template<
typename ITR>
955 return myCurrent > r.myCurrent;
957 return r.myCurrent > myCurrent;
960 template<
typename ITR>
961 bool operator<=(const base_iterator<ITR, FORWARD> &
r)
const
964 return myCurrent <=
r.myCurrent;
966 return r.myCurrent <= myCurrent;
969 template<
typename ITR>
973 return myCurrent >= r.myCurrent;
975 return r.myCurrent >= myCurrent;
979 template<
typename ITR>
983 return exint(myCurrent - r.myCurrent);
985 return exint(r.myCurrent - myCurrent);
1008 return iterator(myData, myData + mySize);
1066 removeAt(&it.item() - myData);
1075 myData = src.myData;
1076 myCapacity = labelExternal( src.
capacity() );
1077 mySize = src.mySize;
1082 myCapacity = labelExternal( srcsize );
1089 myCapacity = labelExternal( capacity );
1094 myCapacity = labelExternal( 0 );
1111 return SYS_IsPod_v< T >;
1117 template <
typename S>
1121 template <
typename S>
1124 template <
typename S>
1130 template <typename First, typename... Rest>
1134 static_cast<const void *>(&first) <
1135 static_cast<const void *>(myData) ||
1136 static_cast<const void *>(&first) >=
1137 static_cast<const void *>(myData + mySize),
1138 "Argument cannot reference an existing element in the array.");
1149 template <
typename...
S>
1152 new (&
dst)
T(std::forward<S>(
s)...);
1158 if constexpr( SYS_IsPod_v< T > )
1172 class AppendIterator
1175 using iterator_category = std::output_iterator_tag;
1177 using difference_type =
void;
1181 explicit AppendIterator(
UT_Array<T> &arr) : myArray(&arr) {}
1187 myArray->append(val);
1193 myArray->append(std::move(val));
1200 AppendIterator &
operator*() {
return *
this; }
1201 AppendIterator &operator++() {
return *
this; }
1202 AppendIterator operator++(
int) {
return *
this; }
1209 #ifdef UT_ARRAY_STRICT_LABELED_CAPACITY
1219 LabeledCapacity myCapacity;
1225 static LabeledCapacity labelOwned(
const exint capacity) noexcept;
1228 static LabeledCapacity labelExternal(
const exint capacity) noexcept;
1245 static void deallocateArray(
T *
data) noexcept;
1271 static void constructElement(
T &
dst);
1274 static void destroyElement(
T &
dst) noexcept;
1275 static void destroyRange([[maybe_unused]]
T *
dst,
exint n) noexcept;
1313 static void bitwiseRelocate(
T *
dst,
const T *
src,
exint n) noexcept;
1318 static void bitwiseRelocateNonoverlapping(
1367 template<
typename OS,
typename S>
1368 friend OS &operator<<(OS &os, const UT_Array<S> &d);
1384 template <
typename T,
typename S>
1391 for (
exint i = 0; i <
n; i++)
1392 dest(i) =
T(
src(i));
1394 template <
typename T,
typename S>
1400 for (
exint i = 0; i <
n; i++)
1401 dest(i) =
T(src[i]);
1403 template <
typename T,
typename S>
1409 for (
exint i = 0; i <
n; i++)
1410 dest[i] =
T(
src(i));
1412 template <
typename T,
typename S>
1417 for (
int64 i = 0; i <
n; i++)
1418 dest[i] =
T(src[i]);
1424 template<
typename OS,
typename S>
1426 operator<<(OS &os, const UT_Array<S> &d)
1433 template <
typename T>
UT_API size_t
1438 template <
template <
typename>
class ArrayT,
typename T>
1440 UTarrayDeepMemoryUsage(
const ArrayT<T> &arr,
bool inclusive)
1442 int64 mem = inclusive ?
sizeof(arr) : 0;
1443 mem += arr.getMemoryUsage(
false);
1444 for (
auto &&item : arr)
1445 mem += item.getMemoryUsage(
false);
1450 template <
typename T>
1454 arr.
sort([](
const T &
a,
const T &
b) {
return a <
b; });
1458 template <
typename T>
1468 template <
typename T>
1469 struct DefaultClearer;
1471 template <
typename T>
1480 static const bool clearNeedsDestruction =
false;
1496 template <
typename T>
1503 #if defined(MBSD) || defined(_LIBCPP_VERSION)
1505 template <
typename CharT,
typename Traits,
typename Allocator>
1507 #elif defined(__GLIBCXX__)
1508 #include <bits/stringfwd.h>
1509 template <
typename CharT,
typename Traits,
typename Allocator>
1513 template <
typename CharT,
typename Traits,
typename Allocator>
1517 #endif // __UT_ARRAY_H_INCLUDED__
reference operator*() const
base_iterator & operator++()
Pre-increment operator.
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)
void shrinkToFit()
shrinks the capacity to the current size
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
void setSizeAndShrink(exint new_size)
convenience method to set size and shrink-to-fit in a single call
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
bool isEqual(const UT_Array< T > &a, ComparatorBool is_equal) const
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
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate and *a name There is also one special expression reference
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