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>
1317 if( mySize == 0 )
return -1;
1320 found = (
T *)::bsearch(&t, myData, mySize,
sizeof(
T),
1322 return found ? (found - myData) : -1;
1325 template <
typename T>
1329 exint n = mySize / 2;
1330 for (
exint i = 0; i <
n; i++ )
1331 UTswap(myData[i], myData[mySize-1-i]);
1334 template <
typename T>
1341 template <
typename T>
1342 template <
typename ComparatorBool>
1359 template <
typename T>
1364 if (new_capacity == capacity())
1370 if (!isHeapBuffer())
1372 if (new_capacity < mySize)
1375 destroyRange(myData + new_capacity, mySize - new_capacity);
1376 mySize = new_capacity;
1378 else if (new_capacity > capacity())
1380 convertToHeapBuffer(new_capacity);
1385 UT_ASSERT_P(new_capacity >= mySize && new_capacity <= capacity());
1390 if (new_capacity == 0)
1394 destroyRange(myData, mySize);
1395 deallocateArray(myData);
1398 myCapacity = labelOwned(0);
1403 if (new_capacity < mySize)
1405 destroyRange(myData + new_capacity, mySize - new_capacity);
1406 mySize = new_capacity;
1411 if constexpr( SYS_UseTrivialRelocation_v< T > )
1413 myData = reallocateArray(myData, new_capacity);
1418 myData = allocateArray(new_capacity);
1421 relocateNonoverlapping(myData, prev, mySize);
1424 deallocateArray(prev);
1429 myData = allocateArray(new_capacity);
1433 if (!isHeapBuffer())
1440 myData = allocateArray(new_capacity);
1443 relocateNonoverlapping(myData, prev, mySize);
1446 deallocateArray(prev);
1449 myCapacity = labelOwned(new_capacity);
1453 template <
typename T>
1468 template <
typename T>
1472 const exint new_size = a.size();
1475 setCapacityIfNeeded(new_size);
1479 destroyRange(myData, mySize);
1481 copyNonoverlapping(myData, a.begin(), new_size);
1488 template <
typename T>
1494 if((!isHeapBuffer()) &&
a.isHeapBuffer())
1496 destroyRange(myData, mySize);
1498 convertToHeapBuffer(0);
1508 template <
typename T>
1512 if (
this == &a)
return true;
1513 if (mySize != a.
size())
return false;
1514 for (
exint i = 0; i < mySize; i++)
1515 if (!(myData[i] ==
a(i)))
return false;
1519 template <
typename T>
1523 return (!
operator==(a));
1526 template <
typename T>
1527 template <
typename ComparatorBool,
typename>
1531 if (
this == &a)
return true;
1532 if (mySize != a.
size())
return false;
1533 for (
exint i = 0; i < mySize; i++)
1535 if (!is_equal(myData[i], a[i]))
return false;
1540 template <
typename T>
1547 template <
typename T>
1552 for (i = 0; i < mySize; i++)
1554 if (apply_func(myData[i], d))
1566 template <
typename T>
1567 template <
typename ComparatorBool>
1571 ComparatorBool is_less)
1578 if (other.
size() == 0)
1586 UT_ASSERT( direction == -1 || direction == +1 );
1587 direction = (direction > 0) ? +1 : -1;
1591 while( our_idx <
size() && other_idx < other.
size() )
1593 const T &our_item = (*this)(our_idx);
1594 const T &other_item = other(other_idx);
1597 if (our_item == other_item)
1599 else if (is_less(our_item, other_item))
1608 item_dir = ( (item_dir > 0) ? +1 : -1 ) *
direction;
1613 result.
append( our_item );
1616 else if( item_dir > 0 )
1618 result.
append( other_item );
1623 result.
append( our_item );
1626 result.
append( other_item );
1632 for( ; our_idx <
size(); our_idx++ )
1633 result.
append( (*
this)(our_idx) );
1634 for( ; other_idx < other.
size(); other_idx++ )
1635 result.
append( other(other_idx) );
1641 template <
typename T>
1650 template <
typename T>
1651 template <
typename ComparatorBool,
typename>
1657 return std::includes(
1658 myData, myData + mySize,
1659 other.myData, other.myData + other.mySize,
1663 template <
typename T>
1670 template <
typename T>
1680 template <
typename T>
1687 template <
typename T>
1697 template <
typename T>
1704 template <
typename T>
1714 template <
typename T>
1715 template <
typename ComparatorBool,
typename>
1720 sortedUnion( other, temp, is_less );
1724 template <
typename T>
1725 template <
typename ComparatorBool,
typename>
1730 ComparatorBool is_less)
const
1733 UT_ASSERT(&result !=
this && &result != &other);
1741 template <
typename T>
1742 template <
typename ComparatorBool,
typename>
1746 ComparatorBool is_less)
1749 sortedIntersection( other, temp, is_less );
1753 template <
typename T>
1754 template <
typename ComparatorBool,
typename>
1759 ComparatorBool is_less)
const
1762 UT_ASSERT(&result !=
this && &result != &other);
1765 std::set_intersection(
1770 template <
typename T>
1771 template <
typename ComparatorBool,
typename>
1775 ComparatorBool is_less)
1778 sortedSetDifference(other, temp, is_less);
1782 template <
typename T>
1783 template <
typename ComparatorBool,
typename>
1788 ComparatorBool is_less)
const
1791 UT_ASSERT(&result !=
this && &result != &other);
1794 std::set_difference(
1799 template <
typename T>
1800 template <
typename CompareEqual>
1811 for (
exint i = 1; i <
n; i++)
1813 if (!compare_equal((*
this)(i), (*
this)(i-1)))
1816 (*this)(
dst) = (*
this)(i);
1827 template<
typename T>
1828 struct srdCompareEqual
1830 bool operator()(
const T&
x,
const T&
y)
const {
return (x == y); }
1834 template <
typename T>
1838 srdCompareEqual<T>
cmp;
1839 return sortedRemoveDuplicatesIf(cmp);
1842 template <
typename T>
1843 template <
typename BinaryOp>
1848 for (
exint i = 0; i < mySize; i++)
1849 sum =
add(sum, myData[i]);
1853 #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)
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)
exint concat(const UT_Array< T > &a)
Takes another T array and concatenate it onto my end.
**But if you need a result
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
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
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 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)
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
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
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.