15 #ifndef __UT_ARRAYIMPL_H_INCLUDED__
16 #define __UT_ARRAYIMPL_H_INCLUDED__
34 #define UT_RELOCATION_SAFETY_NONE 0
35 #define UT_RELOCATION_SAFETY_PATCHY 1
36 #define UT_RELOCATION_SAFETY_PERMISSIVE 2
37 #define UT_RELOCATION_SAFETY_NORMAL 3
38 #define UT_RELOCATION_SAFETY_MAXIMUM 4
41 #define UT_RELOCATION_SAFETY_LEVEL UT_RELOCATION_SAFETY_PATCHY
44 #if (UT_RELOCATION_SAFETY_LEVEL >= UT_RELOCATION_SAFETY_MAXIMUM)
47 template<
typename T >
50 #elif (UT_RELOCATION_SAFETY_LEVEL >= UT_RELOCATION_SAFETY_NORMAL)
53 template<
typename T >
56 #elif (UT_RELOCATION_SAFETY_LEVEL >= UT_RELOCATION_SAFETY_PERMISSIVE)
60 template<
typename T >
63 SYS_IsTriviallyRelocatable< T >::value ||
64 LegacyTrivialRelocationNoCV< std::remove_cv_t< T > >::value
68 #elif (UT_RELOCATION_SAFETY_LEVEL >= UT_RELOCATION_SAFETY_PATCHY)
72 template<
typename T >
75 ( ! UnsafeTrivialRelocationNoCV< std::remove_cv_t< T > >::value ) ||
76 LegacyTrivialRelocationNoCV< std::remove_cv_t< T > >::value
84 "Not trivially relocatable"
88 #else // if (UT_RELOCATION_SAFETY_LEVEL >= UT_RELOCATION_SAFETY_NONE)
93 template<
typename T >
98 template<
typename T >
101 template <
typename T>
102 typename UT_Array<T>::LabeledCapacity
107 #ifdef UT_ARRAY_STRICT_LABELED_CAPACITY
121 template <
typename T>
122 typename UT_Array<T>::LabeledCapacity
127 #ifdef UT_ARRAY_STRICT_LABELED_CAPACITY
141 template <
typename T>
145 #ifdef UT_ARRAY_STRICT_LABELED_CAPACITY
156 template <
typename T>
160 constexpr
auto elem_size =
sizeof(
T);
167 return (T *)malloc( capacity * elem_size );
171 template <typename T>
175 constexpr
auto elem_size =
sizeof(
T);
182 return (T *)realloc( data, capacity * elem_size );
186 template <typename T>
188 UT_Array<T>::isHeapBuffer(T* data)
const
190 return (data != (T *)(((
char*)
this) +
sizeof(*
this)));
193 template <
typename T>
199 T *data = allocateArray(capacity);
202 if (!isHeapBuffer(data))
209 data = allocateArray(capacity);
211 deallocateArray(prev);
217 template <
typename T>
228 template <typename T>
231 if constexpr( ! SYS_IsPod_v< T > )
238 memset((
void *)&dst, 0,
sizeof(T));
242 template <
typename T>
245 if constexpr( ! SYS_IsPod_v< T > )
247 for (
exint i = 0; i <
n; i++)
263 memset((
void *)dst, 0,
sizeof(T));
268 memset((
void *)dst, 0,
sizeof(T) * n);
272 template <
typename T>
275 if constexpr( ! SYS_IsPod_v< T > )
281 template <
typename T>
284 if constexpr( ! SYS_IsPod_v< T > )
286 for (
exint i = 0; i <
n; i++)
293 template <
typename T>
297 for(
exint i = 0; i !=
n; ++i )
299 new( dst + i ) T{ std::move( src[ i ] ) };
304 template <
typename T>
308 for(
exint i = n - 1; i >= 0; --i )
310 new( dst + i ) T{ std::move( src[ i ] ) };
315 template <
typename T>
321 standardRelocateIncreasing( dst, src, n );
325 standardRelocateDecreasing( dst, src, n );
330 template <
typename T>
340 template <
typename T>
351 ::memmove( (
void*)dst, (
const void*)src, n *
sizeof(T) );
354 template <
typename T>
369 ::memcpy( (
void*)dst, (
const void*)src, n *
sizeof(T) );
372 template <
typename T>
379 if constexpr( SYS_UseTrivialRelocation_v< T > )
386 bitwiseRelocateNonoverlapping( dst, src, n );
391 standardRelocateIncreasing( dst, src, n );
395 template <
typename T>
398 if constexpr( SYS_UseTrivialRelocation_v< T > )
405 bitwiseRelocate( dst, src, n );
410 standardRelocateIncreasing( dst, src, n );
414 template <
typename T>
417 if constexpr( SYS_UseTrivialRelocation_v< T > )
424 bitwiseRelocate( dst, src, n );
429 standardRelocateDecreasing( dst, src, n );
433 template <
typename T>
439 if constexpr( SYS_UseTrivialRelocation_v< T > )
446 bitwiseRelocate( dst, src, n );
451 standardRelocate( dst, src, n );
455 template <
typename T>
462 if constexpr( SYS_UseTrivialRelocation_v< T > )
471 char* bytes_dst{
reinterpret_cast< char*
>(
dst ) };
472 char* bytes_src{
reinterpret_cast< char*
>(
src ) };
474 const auto num_bytes{ n *
sizeof(
T ) };
475 for(
exint b = 0;
b != num_bytes; ++
b )
477 UTswap( bytes_dst[
b ], bytes_src[ b ] );
484 for(
exint i = 0; i !=
n; ++i )
486 T t{ std::move( src[ i ] ) };
489 new( src + i ) T{ std::move( dst[ i ] ) };
492 new( dst + i ) T{ std::move(
t ) };
497 template <
typename T>
501 if constexpr( SYS_IsPod_v< T > )
505 bitwiseRelocateNonoverlapping(dst, src, n);
510 for (
exint i = 0; i <
n; i++)
512 new ( dst + i ) T{ src[i] };
517 template <
typename T>
520 : myCapacity(labelOwned(a.
size())), mySize(a.
size())
524 myData = allocateArrayHeapIdentifiable(a.
size());
525 copyNonoverlapping(myData, a.
array(), a.
size());
533 template <
typename T>
536 : myCapacity(labelOwned(init.
size())), mySize(init.
size())
540 myData = allocateArrayHeapIdentifiable(init.size());
541 copyNonoverlapping(myData, init.begin(), init.size());
549 template <
typename T>
556 template <
typename T>
559 myData{ capacity ? allocateArrayHeapIdentifiable(capacity) :
nullptr },
560 myCapacity{ labelOwned(capacity) },
561 mySize{ (capacity <
size) ? capacity :
size }
564 constructRange(myData, mySize);
567 template <
typename T>
570 myData{ capacity ? allocateArrayHeapIdentifiable(capacity) :
nullptr },
571 myCapacity{ labelOwned(capacity) },
576 template <
typename T>
580 destroyRange(myData, mySize);
585 deallocateArray(myData);
591 myCapacity = labelOwned(0);
594 template <
typename T>
596 const UT_ArrayCT::ExternalCapacity,
598 const exint external_capacity
600 myData{ external_data },
601 myCapacity{ labelExternal(external_capacity) },
606 template <
typename T>
608 const UT_ArrayCT::ExternalMove,
610 const exint external_capacity,
617 template <
typename T>
619 const UT_ArrayCT::GeneralizedMove,
621 const exint external_capacity,
624 myData{ external_data },
625 myCapacity{ labelExternal(external_capacity) },
628 if( !
a.isHeapBuffer() )
630 if(
a.mySize > external_capacity )
632 myData = allocateArrayHeapIdentifiable(
a.mySize);
633 myCapacity = labelOwned(
a.mySize);
636 relocateNonoverlapping(myData,
a.myData,
a.mySize);
648 template <
typename T>
654 T *heap_data{
nullptr };
658 heap_data = allocateArray(capacity);
659 relocateNonoverlapping(heap_data, myData, mySize);
663 myCapacity = labelOwned(capacity);
674 template <
typename T>
679 ( ( ! isHeapBuffer() ) || ( ! other.
isHeapBuffer() ) ) &&
680 ( ( other.mySize <= capacity() ) && ( mySize <= other.
capacity() ) )
689 swapNonoverlapping( myData, other.myData,
SYSmin( mySize, other.mySize ) );
691 if( mySize < other.mySize )
693 relocateNonoverlapping( myData + mySize, other.myData + mySize, other.mySize - mySize );
695 else if( other.mySize < mySize )
697 relocateNonoverlapping( other.myData + other.mySize, myData + other.mySize, mySize - other.mySize );
702 if( ! isHeapBuffer() )
704 convertToHeapBuffer( capacity() );
709 other.convertToHeapBuffer( other.
capacity() );
712 UTswap(myData, other.myData);
713 UTswap(myCapacity, other.myCapacity);
716 UTswap(mySize, other.mySize);
719 template <
typename T>
725 bumpCapacity(index + 1);
727 constructRange(myData + mySize, index - mySize + 1);
732 bumpCapacity(mySize + 1);
735 relocateDecreasing(myData + index + 1, myData + index, mySize-index);
737 constructElement(myData[index]);
743 template <
typename T>
744 template <
typename S>
748 if (mySize == capacity())
753 setCapacity(UTbumpAlloc(capacity()));
755 construct(myData[mySize], std::forward<S>(myData[idx]));
757 construct(myData[mySize], std::forward<S>(
s));
761 construct(myData[mySize], std::forward<S>(
s));
766 template <
typename T>
767 template <
typename...
S>
771 #if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_PARANOID
772 validateEmplaceArgs(std::forward<S>(
s)...);
775 if (mySize == capacity())
777 setCapacity(UTbumpAlloc(capacity()));
780 construct(myData[mySize], std::forward<S>(
s)...);
784 template <
typename T>
788 bumpCapacity(mySize + count);
789 copyNonoverlapping(myData + mySize, pt, count);
793 template <
typename T>
800 if (mySize + count >= capacity())
802 exint tidx = safeIndex(t);
804 bumpCapacity(mySize + count);
807 copyConstruct(myData[mySize+i], tidx >= 0 ? myData[tidx] : t);
812 copyConstruct(myData[mySize+i], t);
817 template <
typename T>
824 template <
typename T>
825 template <
typename ComparatorBool,
typename>
829 exint low, mid, high;
835 mid = (low + high) / 2;
836 if (is_less(t, myData[mid]))
838 else if (is_less(myData[mid], t))
850 template <
typename T>
851 template <
typename S>
855 exint low, mid, high;
861 mid = (low + high) / 2;
864 else if (
compare(&
s, &myData[mid]) > 0)
869 insertImpl(std::forward<S>(
s), low);
873 template <
typename T>
874 template <
typename ComparatorBool,
typename>
878 exint low, mid, high;
884 mid = (low + high) / 2;
885 if (t == myData[mid])
887 else if (is_less(t, myData[mid]))
896 template <
typename T>
897 template <
typename ComparatorBool,
typename>
907 if (is_less(myData[idx + h], item))
916 return (idx !=
size() && !is_less(item, myData[idx])) ? idx : -1;
919 template <
typename T>
926 template <
typename T>
934 while( i > 0 &&
compare(&myData[(i - 1) / 2], &t) < 0 )
936 myData[i] = myData[(i - 1) / 2];
943 template <
typename T>
951 myData[0] = myData[mySize - 1];
952 removeAt(mySize - 1);
960 exint cidx = 2 * idx + 1;
961 if( cidx < mySize &&
compare(&myData[largest], &myData[cidx]) < 0 )
965 if( cidx < mySize &&
compare(&myData[largest], &myData[cidx]) < 0 )
973 UTswap(myData[idx], myData[largest]);
980 template <
typename T>
984 bumpCapacity(mySize + a.mySize);
985 copyNonoverlapping(myData + mySize, a.myData, a.mySize);
991 template <
typename T>
1002 const exint n =
a.mySize;
1003 bumpCapacity(mySize + n);
1004 relocateNonoverlapping(myData + mySize,
a.myData, n);
1011 template <
typename T>
1017 if (beg_index >= mySize)
1019 bumpCapacity(end_index);
1021 constructRange(myData + mySize, end_index - mySize);
1026 bumpCapacity(mySize+count);
1028 relocateDecreasing(myData + end_index, myData + beg_index, mySize-beg_index);
1031 constructRange(myData + beg_index, count);
1036 template <
typename T>
1037 template <
typename S>
1041 if (index == mySize)
1045 (
void) appendImpl(std::forward<S>(
s));
1047 else if (index > mySize)
1049 exint src_i = safeIndex(
s);
1051 bumpCapacity(index + 1);
1053 constructRange(myData + mySize, index - mySize);
1056 construct(myData[index], std::forward<S>(myData[src_i]));
1058 construct(myData[index], std::forward<S>(
s));
1064 exint src_i = safeIndex(
s);
1066 bumpCapacity(mySize + 1);
1068 relocateDecreasing(myData + index + 1, myData + index, mySize-index);
1074 construct(myData[index], std::forward<S>(myData[src_i]));
1076 construct(myData[index], std::forward<S>(
s));
1084 template <
typename T>
1085 template <
typename S>
1090 return (idx < 0) ? -1 : removeAt((
exint)idx);
1093 template <
typename T>
1097 destroyElement(myData[idx]);
1098 if (idx != --mySize)
1100 relocateIncreasing(myData + idx, myData + idx + 1, mySize - idx);
1106 template <
typename T>
1113 const exint nelements = end_i - begin_i;
1119 destroyRange(myData + begin_i, nelements);
1120 relocateIncreasing(myData + begin_i, myData + end_i, mySize - end_i);
1121 mySize -= nelements;
1124 template <
typename T>
1133 exint nelements = end_i - begin_i;
1140 relocate(dest.myData, myData + begin_i, nelements);
1142 dest.mySize = nelements;
1151 relocateIncreasing(myData + begin_i, myData + end_i, mySize - end_i);
1154 mySize -= nelements;
1160 template <
typename T>
1171 if (src_idx + how_many >
size())
1172 how_many =
size() - src_idx;
1175 if (dst_idx + how_many >
size())
1176 dst_idx =
size() - how_many;
1177 if (src_idx != dst_idx && how_many > 0)
1181 T* tmp = allocateArray(savelen);
1183 if (src_idx > dst_idx && how_many > 0)
1189 relocateNonoverlapping(tmp, &myData[dst_idx], savelen);
1190 relocate(&myData[dst_idx], &myData[src_idx], how_many);
1191 relocateNonoverlapping(&myData[dst_idx + how_many], tmp, savelen);
1193 if (src_idx < dst_idx && how_many > 0)
1200 relocateNonoverlapping(tmp, &myData[src_idx + how_many], savelen);
1201 relocate(&myData[dst_idx], &myData[src_idx], how_many);
1202 relocateNonoverlapping(&myData[src_idx], tmp, savelen);
1205 deallocateArray(tmp);
1209 template <
typename T>
1210 template <
typename IsEqual>
1216 for (dst = 0; dst < mySize; dst++)
1218 if (is_equal(myData[dst]))
1222 for (
exint idx = dst+1; idx < mySize; idx++)
1224 if (!is_equal(myData[idx]))
1227 myData[
dst] = std::move(myData[idx]);
1236 destroyRange(myData + dst, mySize - dst);
1242 template <
typename T>
1249 if (how_many == 0 || mySize < 1)
1252 numShift = how_many % (
exint)mySize;
1253 if (numShift < 0) numShift += mySize;
1254 remaining = mySize - numShift;
1261 T* tmp = allocateArray(numShift);
1263 relocate(tmp, myData + remaining, numShift);
1264 relocate(myData + numShift, myData, remaining);
1265 relocate(myData + 0, tmp, numShift);
1267 deallocateArray(tmp);
1270 template <
typename T>
1274 for (
exint i = 0; i < mySize; i++)
1285 template <
typename T>
1289 if constexpr( SYS_IsPod_v< T > )
1291 ::memset((
void *)myData, 0, mySize*
sizeof(
T));
1295 constructRange(myData, mySize);
1299 template <
typename T>
1300 template <
typename S>
1304 const T *
end = myData + mySize;
1305 for (
const T *p = myData + start; p <
end; ++p)
1307 return (p - myData);
1311 template <
typename T>
1312 template <
typename IsEqual>
1316 const T *
end = myData + mySize;
1317 for (
const T *p = myData + start; p <
end; ++p)
1319 return (p - myData);
1323 template <
typename T>
1329 if( mySize == 0 )
return -1;
1332 found = (
T *)::bsearch(&t, myData, mySize,
sizeof(
T),
1334 return found ? (found - myData) : -1;
1337 template <
typename T>
1341 exint n = mySize / 2;
1342 for (
exint i = 0; i <
n; i++ )
1343 UTswap(myData[i], myData[mySize-1-i]);
1346 template <
typename T>
1353 template <
typename T>
1354 template <
typename ComparatorBool>
1371 template <
typename T>
1376 if (new_capacity == capacity())
1382 if (!isHeapBuffer())
1384 if (new_capacity < mySize)
1387 destroyRange(myData + new_capacity, mySize - new_capacity);
1388 mySize = new_capacity;
1390 else if (new_capacity > capacity())
1392 convertToHeapBuffer(new_capacity);
1397 UT_ASSERT_P(new_capacity >= mySize && new_capacity <= capacity());
1402 if (new_capacity == 0)
1406 destroyRange(myData, mySize);
1407 deallocateArray(myData);
1410 myCapacity = labelOwned(0);
1415 if (new_capacity < mySize)
1417 destroyRange(myData + new_capacity, mySize - new_capacity);
1418 mySize = new_capacity;
1423 if constexpr( SYS_UseTrivialRelocation_v< T > )
1425 myData = reallocateArray(myData, new_capacity);
1430 myData = allocateArray(new_capacity);
1433 relocateNonoverlapping(myData, prev, mySize);
1436 deallocateArray(prev);
1441 myData = allocateArray(new_capacity);
1445 if (!isHeapBuffer())
1452 myData = allocateArray(new_capacity);
1455 relocateNonoverlapping(myData, prev, mySize);
1458 deallocateArray(prev);
1461 myCapacity = labelOwned(new_capacity);
1465 template <
typename T>
1480 template <
typename T>
1484 const exint new_size = a.size();
1487 setCapacityIfNeeded(new_size);
1491 destroyRange(myData, mySize);
1493 copyNonoverlapping(myData, a.begin(), new_size);
1500 template <
typename T>
1506 if((!isHeapBuffer()) &&
a.isHeapBuffer())
1508 destroyRange(myData, mySize);
1510 convertToHeapBuffer(0);
1520 template <
typename T>
1524 if (
this == &a)
return true;
1525 if (mySize != a.
size())
return false;
1526 for (
exint i = 0; i < mySize; i++)
1527 if (!(myData[i] ==
a(i)))
return false;
1531 template <
typename T>
1535 return (!
operator==(a));
1538 template <
typename T>
1539 template <
typename ComparatorBool,
typename>
1543 if (
this == &a)
return true;
1544 if (mySize != a.
size())
return false;
1545 for (
exint i = 0; i < mySize; i++)
1547 if (!is_equal(myData[i], a[i]))
return false;
1552 template <
typename T>
1559 template <
typename T>
1564 for (i = 0; i < mySize; i++)
1566 if (apply_func(myData[i], d))
1578 template <
typename T>
1579 template <
typename ComparatorBool>
1583 ComparatorBool is_less)
1590 if (other.
size() == 0)
1598 UT_ASSERT( direction == -1 || direction == +1 );
1599 direction = (direction > 0) ? +1 : -1;
1603 while( our_idx <
size() && other_idx < other.
size() )
1605 const T &our_item = (*this)(our_idx);
1606 const T &other_item = other(other_idx);
1609 if (our_item == other_item)
1611 else if (is_less(our_item, other_item))
1620 item_dir = ( (item_dir > 0) ? +1 : -1 ) *
direction;
1625 result.
append( our_item );
1628 else if( item_dir > 0 )
1630 result.
append( other_item );
1635 result.
append( our_item );
1638 result.
append( other_item );
1644 for( ; our_idx <
size(); our_idx++ )
1645 result.
append( (*
this)(our_idx) );
1646 for( ; other_idx < other.
size(); other_idx++ )
1647 result.
append( other(other_idx) );
1653 template <
typename T>
1662 template <
typename T>
1663 template <
typename ComparatorBool,
typename>
1669 return std::includes(
1670 myData, myData + mySize,
1671 other.myData, other.myData + other.mySize,
1675 template <
typename T>
1682 template <
typename T>
1692 template <
typename T>
1699 template <
typename T>
1709 template <
typename T>
1716 template <
typename T>
1726 template <
typename T>
1727 template <
typename ComparatorBool,
typename>
1732 sortedUnion( other, temp, is_less );
1736 template <
typename T>
1737 template <
typename ComparatorBool,
typename>
1742 ComparatorBool is_less)
const
1745 UT_ASSERT(&result !=
this && &result != &other);
1753 template <
typename T>
1754 template <
typename ComparatorBool,
typename>
1758 ComparatorBool is_less)
1761 sortedIntersection( other, temp, is_less );
1765 template <
typename T>
1766 template <
typename ComparatorBool,
typename>
1771 ComparatorBool is_less)
const
1774 UT_ASSERT(&result !=
this && &result != &other);
1777 std::set_intersection(
1782 template <
typename T>
1783 template <
typename ComparatorBool,
typename>
1787 ComparatorBool is_less)
1790 sortedSetDifference(other, temp, is_less);
1794 template <
typename T>
1795 template <
typename ComparatorBool,
typename>
1800 ComparatorBool is_less)
const
1803 UT_ASSERT(&result !=
this && &result != &other);
1806 std::set_difference(
1811 template <
typename T>
1812 template <
typename CompareEqual>
1823 for (
exint i = 1; i <
n; i++)
1825 if (!compare_equal((*
this)(i), (*
this)(i-1)))
1828 (*this)(
dst) = (*
this)(i);
1839 template<
typename T>
1840 struct srdCompareEqual
1842 bool operator()(
const T&
x,
const T&
y)
const {
return (x == y); }
1846 template <
typename T>
1850 srdCompareEqual<T>
cmp;
1851 return sortedRemoveDuplicatesIf(cmp);
1854 template <
typename T>
1855 template <
typename BinaryOp>
1860 for (
exint i = 0; i < mySize; i++)
1861 sum =
add(sum, myData[i]);
1865 #endif // __UT_ARRAYIMPL_H_INCLUDED__
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
int(* ut_ptr_compare_func_t)(const void *, const void *)
void merge(const UT_Array< T > &other, int direction, bool allow_dups, ComparatorBool is_less={})
bool isHeapBuffer() const
Returns true if the data used by the array was allocated on the heap.
void UTnth_element(IT start, IT nth, IT end, COMPARE isAbeforeB)
bool operator!=(const UT_Array< T > &a) const
#define SYS_PRAGMA_PUSH_WARN()
exint insertImpl(S &&s, exint index)
Similar to appendImpl() but for insertion.
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)
GLsizei const GLfloat * value
void extractRange(exint begin_i, exint end_i, UT_Array< T > &dest)
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, float failrelative, float warnrelative, ROI roi={}, int nthreads=0)
void zero()
Zeros the array if a POD type, else trivial constructs if a class type.
exint uniqueSortedFind(const T &item, ComparatorBool is_less={}) const
void move(exint src_idx, exint dst_idx, exint how_many)
GLboolean GLboolean GLboolean GLboolean a
void cycle(exint how_many)
Cyclically shifts the entire array by how_many.
static constexpr struct UT_ArrayCT::GeneralizedMove GENERALIZED_MOVE
void setCapacity(exint new_capacity)
PUGI__FN void sort(I begin, I end, const Pred &pred)
exint concat(const UT_Array< T > &a)
Takes another T array and concatenate it onto my end.
**But if you need a result
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
constexpr UT_LabeledCapacityRep LABELED_CAPACITY_MASK_VALUE
exint uniqueSortedInsert(const T &t, Comparator compare)
exint find(const S &s, exint start=0) const
void sortedUnion(const UT_Array< T > &other, ComparatorBool is_less={})
constexpr UT_LabeledCapacityRep LABELED_CAPACITY_FLAG_EXTERNAL
IMATH_HOSTDEVICE constexpr int cmp(T a, T b) IMATH_NOEXCEPT
exint findIf(IsEqual is_equal, exint start=0) const
exint apply(int(*apply_func)(T &t, void *d), void *d)
exint emplace_back(S &&...s)
constexpr UT_LabeledCapacity ownedLabeledCapacity(const exint capacity) noexcept
constexpr UT_LabeledCapacity externalLabeledCapacity(const exint capacity) noexcept
exint uniqueSortedInsertImpl(S &&s, Comparator compare)
void sort(ComparatorBool is_less={})
Sort using std::sort with bool comparator. Defaults to operator<().
T accumulate(const T &init_value, BinaryOp add) const
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
exint sortedInsert(const T &t, Comparator compare)
#define SYS_PRAGMA_DISABLE_FREE_NONHEAP_OBJECT()
void appendMultiple(const T &t, exint count)
void setCapacityIfNeeded(exint min_capacity)
#define SYS_PRAGMA_POP_WARN()
exint removeIf(IsEqual is_equal)
exint sortedRemoveDuplicates()
void sortedSetDifference(const UT_Array< T > &other, ComparatorBool is_less={})
GLboolean GLboolean GLboolean b
constexpr exint capacityValue(const UT_LabeledCapacity &a) noexcept
constexpr bool UTareOverlapping(const T *const a, const T *const b, exint n) noexcept
exint sortedRemoveDuplicatesIf(CompareEqual compare_equal)
T selectNthLargest(exint idx, ComparatorBool is_less={})
#define SYS_PRAGMA_DISABLE_ALLOC_SIZE_LARGER_THAN()
GLfloat GLfloat GLfloat GLfloat h
UT_Compare::Less< T > UTcompareLess(UT_Compare::Ternary< T > compare)
LeafData & operator=(const LeafData &)=delete
VULKAN_HPP_CONSTEXPR_14 VULKAN_HPP_INLINE T exchange(T &obj, U &&newValue)
UT_Compare::Equal< T > UTcompareEqual(UT_Compare::Ternary< T > compare)
bool isEqual(const UT_Array< T > &a, ComparatorBool is_equal) const
#define SYS_PRAGMA_DISABLE_MISMATCHED_NEW_DELETE()
void constant(const T &v)
Quickly set the array to a single value.
void sortedIntersection(const UT_Array< T > &other, ComparatorBool is_less={})
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
UT_Array(const UT_Array< T > &a)
T heapPop(Comparator compare)
exint heapPush(const T &t, Comparator compare)
std::string OIIO_UTIL_API concat(string_view s, string_view t)
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)
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.
constexpr auto SYS_UseTrivialRelocation_v
bool operator==(const UT_Array< T > &a) const
exint sortedFind(const T &t, Comparator compare) const
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.