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>
356 ::memmove( (
void*)dst, (const
void*)src, n * sizeof(T) );
360 template <typename T>
362 UT_Array<T>::bitwiseRelocateNonoverlapping(
380 ::memcpy( (
void*)dst, (const
void*)src, n * sizeof(T) );
384 template <typename T>
386 UT_Array<T>::relocateNonoverlapping(T *const dst, T *const src,
exint n)
391 if constexpr( SYS_UseTrivialRelocation_v< T > )
398 bitwiseRelocateNonoverlapping( dst, src, n );
403 standardRelocateIncreasing( dst, src, n );
407 template <
typename T>
410 if constexpr( SYS_UseTrivialRelocation_v< T > )
417 bitwiseRelocate( dst, src, n );
422 standardRelocateIncreasing( dst, src, n );
426 template <
typename T>
429 if constexpr( SYS_UseTrivialRelocation_v< T > )
436 bitwiseRelocate( dst, src, n );
441 standardRelocateDecreasing( dst, src, n );
445 template <
typename T>
451 if constexpr( SYS_UseTrivialRelocation_v< T > )
458 bitwiseRelocate( dst, src, n );
463 standardRelocate( dst, src, n );
467 template <
typename T>
474 if constexpr( SYS_UseTrivialRelocation_v< T > )
483 char* bytes_dst{
reinterpret_cast< char*
>(
dst ) };
484 char* bytes_src{
reinterpret_cast< char*
>(
src ) };
486 const auto num_bytes{ n *
sizeof( T ) };
487 for(
exint b = 0;
b != num_bytes; ++
b )
489 UTswap( bytes_dst[
b ], bytes_src[ b ] );
496 for(
exint i = 0; i !=
n; ++i )
498 T
t{ std::move( src[ i ] ) };
501 new( src + i ) T{ std::move( dst[ i ] ) };
504 new( dst + i ) T{ std::move(
t ) };
509 template <
typename T>
513 if constexpr( SYS_IsPod_v< T > )
517 bitwiseRelocateNonoverlapping(dst, src, n);
522 for (
exint i = 0; i <
n; i++)
524 new ( dst + i ) T{ src[i] };
529 template <
typename T>
532 : myCapacity(labelOwned(a.
size())), mySize(a.
size())
536 myData = allocateArrayHeapIdentifiable(a.
size());
537 copyNonoverlapping(myData, a.
array(), a.
size());
545 template <
typename T>
548 : myCapacity(labelOwned(init.
size())), mySize(init.
size())
552 myData = allocateArrayHeapIdentifiable(init.size());
553 copyNonoverlapping(myData, init.begin(), init.size());
561 template <
typename T>
568 template <
typename T>
571 myData{ capacity ? allocateArrayHeapIdentifiable(capacity) :
nullptr },
572 myCapacity{ labelOwned(capacity) },
573 mySize{ (capacity <
size) ? capacity :
size }
576 constructRange(myData, mySize);
579 template <
typename T>
582 myData{ capacity ? allocateArrayHeapIdentifiable(capacity) :
nullptr },
583 myCapacity{ labelOwned(capacity) },
588 template <
typename T>
592 destroyRange(myData, mySize);
597 deallocateArray(myData);
603 myCapacity = labelOwned(0);
606 template <
typename T>
608 const UT_ArrayCT::ExternalCapacity,
610 const exint external_capacity
612 myData{ external_data },
613 myCapacity{ labelExternal(external_capacity) },
618 template <
typename T>
620 const UT_ArrayCT::ExternalMove,
622 const exint external_capacity,
629 template <
typename T>
631 const UT_ArrayCT::GeneralizedMove,
633 const exint external_capacity,
636 myData{ external_data },
637 myCapacity{ labelExternal(external_capacity) },
640 if( !
a.isHeapBuffer() )
642 if(
a.mySize > external_capacity )
644 myData = allocateArrayHeapIdentifiable(
a.mySize);
645 myCapacity = labelOwned(
a.mySize);
648 relocateNonoverlapping(myData,
a.myData,
a.mySize);
660 template <
typename T>
666 T *heap_data{
nullptr };
670 heap_data = allocateArray(capacity);
671 relocateNonoverlapping(heap_data, myData, mySize);
675 myCapacity = labelOwned(capacity);
686 template <
typename T>
691 ( ( ! isHeapBuffer() ) || ( ! other.
isHeapBuffer() ) ) &&
692 ( ( other.mySize <= capacity() ) && ( mySize <= other.
capacity() ) )
701 swapNonoverlapping( myData, other.myData,
SYSmin( mySize, other.mySize ) );
703 if( mySize < other.mySize )
705 relocateNonoverlapping( myData + mySize, other.myData + mySize, other.mySize - mySize );
707 else if( other.mySize < mySize )
709 relocateNonoverlapping( other.myData + other.mySize, myData + other.mySize, mySize - other.mySize );
714 if( ! isHeapBuffer() )
716 convertToHeapBuffer( capacity() );
721 other.convertToHeapBuffer( other.
capacity() );
724 UTswap(myData, other.myData);
725 UTswap(myCapacity, other.myCapacity);
728 UTswap(mySize, other.mySize);
731 template <
typename T>
737 bumpCapacity(index + 1);
739 constructRange(myData + mySize, index - mySize + 1);
744 bumpCapacity(mySize + 1);
747 relocateDecreasing(myData + index + 1, myData + index, mySize-index);
749 constructElement(myData[index]);
755 template <
typename T>
756 template <
typename S>
760 if (mySize == capacity())
765 setCapacity(UTbumpAlloc(capacity()));
767 construct(myData[mySize], std::forward<S>(myData[idx]));
769 construct(myData[mySize], std::forward<S>(
s));
773 construct(myData[mySize], std::forward<S>(
s));
778 template <
typename T>
779 template <
typename...
S>
783 #if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_PARANOID
784 validateEmplaceArgs(std::forward<S>(
s)...);
787 if (mySize == capacity())
789 setCapacity(UTbumpAlloc(capacity()));
792 construct(myData[mySize], std::forward<S>(
s)...);
796 template <
typename T>
800 bumpCapacity(mySize + count);
801 copyNonoverlapping(myData + mySize, pt, count);
805 template <
typename T>
812 if (mySize + count >= capacity())
814 exint tidx = safeIndex(t);
816 bumpCapacity(mySize + count);
819 copyConstruct(myData[mySize+i], tidx >= 0 ? myData[tidx] : t);
824 copyConstruct(myData[mySize+i], t);
829 template <
typename T>
836 template <
typename T>
837 template <
typename ComparatorBool,
typename>
841 exint low, mid, high;
847 mid = (low + high) / 2;
848 if (is_less(t, myData[mid]))
850 else if (is_less(myData[mid], t))
862 template <
typename T>
863 template <
typename S>
867 exint low, mid, high;
873 mid = (low + high) / 2;
876 else if (
compare(&
s, &myData[mid]) > 0)
881 insertImpl(std::forward<S>(
s), low);
885 template <
typename T>
886 template <
typename ComparatorBool,
typename>
890 exint low, mid, high;
896 mid = (low + high) / 2;
897 if (t == myData[mid])
899 else if (is_less(t, myData[mid]))
908 template <
typename T>
909 template <
typename ComparatorBool,
typename>
919 if (is_less(myData[idx + h], item))
928 return (idx !=
size() && !is_less(item, myData[idx])) ? idx : -1;
931 template <
typename T>
938 template <
typename T>
946 while( i > 0 &&
compare(&myData[(i - 1) / 2], &t) < 0 )
948 myData[i] = myData[(i - 1) / 2];
955 template <
typename T>
963 myData[0] = myData[mySize - 1];
964 removeAt(mySize - 1);
972 exint cidx = 2 * idx + 1;
973 if( cidx < mySize &&
compare(&myData[largest], &myData[cidx]) < 0 )
977 if( cidx < mySize &&
compare(&myData[largest], &myData[cidx]) < 0 )
985 UTswap(myData[idx], myData[largest]);
992 template <
typename T>
996 bumpCapacity(mySize + a.mySize);
997 copyNonoverlapping(myData + mySize, a.myData, a.mySize);
1003 template <
typename T>
1014 const exint n =
a.mySize;
1015 bumpCapacity(mySize + n);
1016 relocateNonoverlapping(myData + mySize,
a.myData, n);
1023 template <
typename T>
1029 if (beg_index >= mySize)
1031 bumpCapacity(end_index);
1033 constructRange(myData + mySize, end_index - mySize);
1038 bumpCapacity(mySize+count);
1040 relocateDecreasing(myData + end_index, myData + beg_index, mySize-beg_index);
1043 constructRange(myData + beg_index, count);
1048 template <
typename T>
1049 template <
typename S>
1053 if (index == mySize)
1057 (
void) appendImpl(std::forward<S>(
s));
1059 else if (index > mySize)
1061 exint src_i = safeIndex(
s);
1063 bumpCapacity(index + 1);
1065 constructRange(myData + mySize, index - mySize);
1068 construct(myData[index], std::forward<S>(myData[src_i]));
1070 construct(myData[index], std::forward<S>(
s));
1076 exint src_i = safeIndex(
s);
1078 bumpCapacity(mySize + 1);
1080 relocateDecreasing(myData + index + 1, myData + index, mySize-index);
1086 construct(myData[index], std::forward<S>(myData[src_i]));
1088 construct(myData[index], std::forward<S>(
s));
1096 template <
typename T>
1097 template <
typename S>
1102 return (idx < 0) ? -1 : removeAt((
exint)idx);
1105 template <
typename T>
1109 destroyElement(myData[idx]);
1110 if (idx != --mySize)
1112 relocateIncreasing(myData + idx, myData + idx + 1, mySize - idx);
1118 template <
typename T>
1125 const exint nelements = end_i - begin_i;
1131 destroyRange(myData + begin_i, nelements);
1132 relocateIncreasing(myData + begin_i, myData + end_i, mySize - end_i);
1133 mySize -= nelements;
1136 template <
typename T>
1145 exint nelements = end_i - begin_i;
1152 relocate(dest.myData, myData + begin_i, nelements);
1154 dest.mySize = nelements;
1163 relocateIncreasing(myData + begin_i, myData + end_i, mySize - end_i);
1166 mySize -= nelements;
1172 template <
typename T>
1183 if (src_idx + how_many >
size())
1184 how_many =
size() - src_idx;
1187 if (dst_idx + how_many >
size())
1188 dst_idx =
size() - how_many;
1189 if (src_idx != dst_idx && how_many > 0)
1193 T* tmp = allocateArray(savelen);
1195 if (src_idx > dst_idx && how_many > 0)
1201 relocateNonoverlapping(tmp, &myData[dst_idx], savelen);
1202 relocate(&myData[dst_idx], &myData[src_idx], how_many);
1203 relocateNonoverlapping(&myData[dst_idx + how_many], tmp, savelen);
1205 if (src_idx < dst_idx && how_many > 0)
1212 relocateNonoverlapping(tmp, &myData[src_idx + how_many], savelen);
1213 relocate(&myData[dst_idx], &myData[src_idx], how_many);
1214 relocateNonoverlapping(&myData[src_idx], tmp, savelen);
1217 deallocateArray(tmp);
1221 template <
typename T>
1222 template <
typename IsEqual>
1228 for (dst = 0; dst < mySize; dst++)
1230 if (is_equal(myData[dst]))
1234 for (
exint idx = dst+1; idx < mySize; idx++)
1236 if (!is_equal(myData[idx]))
1239 myData[
dst] = std::move(myData[idx]);
1248 destroyRange(myData + dst, mySize - dst);
1254 template <
typename T>
1261 if (how_many == 0 || mySize < 1)
1264 numShift = how_many % (
exint)mySize;
1265 if (numShift < 0) numShift += mySize;
1266 remaining = mySize - numShift;
1273 T* tmp = allocateArray(numShift);
1275 relocate(tmp, myData + remaining, numShift);
1276 relocate(myData + numShift, myData, remaining);
1277 relocate(myData + 0, tmp, numShift);
1279 deallocateArray(tmp);
1282 template <
typename T>
1286 for (
exint i = 0; i < mySize; i++)
1297 template <
typename T>
1301 if constexpr( SYS_IsPod_v< T > )
1303 ::memset((
void *)myData, 0, mySize*
sizeof(T));
1307 constructRange(myData, mySize);
1311 template <
typename T>
1312 template <
typename S>
1316 const T *
end = myData + mySize;
1317 for (
const T *p = myData + start; p <
end; ++p)
1319 return (p - myData);
1323 template <
typename T>
1324 template <
typename IsEqual>
1328 const T *
end = myData + mySize;
1329 for (
const T *p = myData + start; p <
end; ++p)
1331 return (p - myData);
1335 template <
typename T>
1341 if( mySize == 0 )
return -1;
1344 found = (T *)::bsearch(&t, myData, mySize,
sizeof(T),
1346 return found ? (found - myData) : -1;
1349 template <
typename T>
1353 exint n = mySize / 2;
1354 for (
exint i = 0; i <
n; i++ )
1355 UTswap(myData[i], myData[mySize-1-i]);
1358 template <
typename T>
1365 template <
typename T>
1366 template <
typename ComparatorBool>
1383 template <
typename T>
1388 if (new_capacity == capacity())
1394 if (!isHeapBuffer())
1396 if (new_capacity < mySize)
1399 destroyRange(myData + new_capacity, mySize - new_capacity);
1400 mySize = new_capacity;
1402 else if (new_capacity > capacity())
1404 convertToHeapBuffer(new_capacity);
1409 UT_ASSERT_P(new_capacity >= mySize && new_capacity <= capacity());
1414 if (new_capacity == 0)
1418 destroyRange(myData, mySize);
1419 deallocateArray(myData);
1422 myCapacity = labelOwned(0);
1427 if (new_capacity < mySize)
1429 destroyRange(myData + new_capacity, mySize - new_capacity);
1430 mySize = new_capacity;
1435 if constexpr( SYS_UseTrivialRelocation_v< T > )
1437 myData = reallocateArray(myData, new_capacity);
1442 myData = allocateArray(new_capacity);
1445 relocateNonoverlapping(myData, prev, mySize);
1448 deallocateArray(prev);
1453 myData = allocateArray(new_capacity);
1457 if (!isHeapBuffer())
1464 myData = allocateArray(new_capacity);
1467 relocateNonoverlapping(myData, prev, mySize);
1470 deallocateArray(prev);
1473 myCapacity = labelOwned(new_capacity);
1477 template <
typename T>
1492 template <
typename T>
1496 const exint new_size = a.size();
1499 setCapacityIfNeeded(new_size);
1503 destroyRange(myData, mySize);
1505 copyNonoverlapping(myData, a.begin(), new_size);
1512 template <
typename T>
1518 if((!isHeapBuffer()) &&
a.isHeapBuffer())
1520 destroyRange(myData, mySize);
1522 convertToHeapBuffer(0);
1532 template <
typename T>
1536 if (
this == &a)
return true;
1537 if (mySize != a.
size())
return false;
1538 for (
exint i = 0; i < mySize; i++)
1539 if (!(myData[i] ==
a(i)))
return false;
1543 template <
typename T>
1547 return (!
operator==(a));
1550 template <
typename T>
1551 template <
typename ComparatorBool,
typename>
1555 if (
this == &a)
return true;
1556 if (mySize != a.
size())
return false;
1557 for (
exint i = 0; i < mySize; i++)
1559 if (!is_equal(myData[i], a[i]))
return false;
1564 template <
typename T>
1571 template <
typename T>
1576 for (i = 0; i < mySize; i++)
1578 if (apply_func(myData[i], d))
1590 template <
typename T>
1591 template <
typename ComparatorBool>
1595 ComparatorBool is_less)
1602 if (other.
size() == 0)
1610 UT_ASSERT( direction == -1 || direction == +1 );
1611 direction = (direction > 0) ? +1 : -1;
1615 while( our_idx <
size() && other_idx < other.
size() )
1617 const T &our_item = (*this)(our_idx);
1618 const T &other_item = other(other_idx);
1621 if (our_item == other_item)
1623 else if (is_less(our_item, other_item))
1632 item_dir = ( (item_dir > 0) ? +1 : -1 ) *
direction;
1637 result.
append( our_item );
1640 else if( item_dir > 0 )
1642 result.
append( other_item );
1647 result.
append( our_item );
1650 result.
append( other_item );
1656 for( ; our_idx <
size(); our_idx++ )
1657 result.
append( (*
this)(our_idx) );
1658 for( ; other_idx < other.
size(); other_idx++ )
1659 result.
append( other(other_idx) );
1668 template <
typename T>
1669 template <
typename ComparatorBool>
1673 ComparatorBool is_less) noexcept
1680 if (other.size() == 0)
1684 concat(std::move(other));
1693 while( our_idx <
size() && other_idx < other.size() )
1695 T &our_item = (*this)(our_idx);
1696 T &other_item = other(other_idx);
1699 if (our_item == other_item)
1701 else if (is_less(our_item, other_item))
1710 item_dir = ( (item_dir > 0) ? +1 : -1 ) *
direction;
1715 result.
append( std::move(our_item) );
1718 else if( item_dir > 0 )
1720 result.
append( std::move(other_item) );
1725 result.
append( std::move(our_item) );
1728 result.
append( std::move(other_item) );
1733 UT_ASSERT( our_idx ==
size() || other_idx == other.size() );
1734 for( ; our_idx <
size(); our_idx++ )
1735 result.
append( std::move((*
this)(our_idx)) );
1736 for( ; other_idx < other.size(); other_idx++ )
1737 result.
append( std::move(other(other_idx)) );
1747 template <
typename T>
1756 template <
typename T>
1757 template <
typename ComparatorBool,
typename>
1763 return std::includes(
1764 myData, myData + mySize,
1765 other.myData, other.myData + other.mySize,
1769 template <
typename T>
1776 template <
typename T>
1786 template <
typename T>
1793 template <
typename T>
1803 template <
typename T>
1810 template <
typename T>
1820 template <
typename T>
1821 template <
typename ComparatorBool,
typename>
1826 sortedUnion( other, temp, is_less );
1830 template <
typename T>
1831 template <
typename ComparatorBool,
typename>
1836 ComparatorBool is_less)
const
1839 UT_ASSERT(&result !=
this && &result != &other);
1847 template <
typename T>
1848 template <
typename ComparatorBool,
typename>
1852 ComparatorBool is_less)
1855 sortedIntersection( other, temp, is_less );
1859 template <
typename T>
1860 template <
typename ComparatorBool,
typename>
1865 ComparatorBool is_less)
const
1868 UT_ASSERT(&result !=
this && &result != &other);
1871 std::set_intersection(
1876 template <
typename T>
1877 template <
typename ComparatorBool,
typename>
1881 ComparatorBool is_less)
1884 sortedSetDifference(other, temp, is_less);
1888 template <
typename T>
1889 template <
typename ComparatorBool,
typename>
1894 ComparatorBool is_less)
const
1897 UT_ASSERT(&result !=
this && &result != &other);
1900 std::set_difference(
1905 template <
typename T>
1906 template <
typename CompareEqual>
1917 for (
exint i = 1; i <
n; i++)
1919 if (!compare_equal((*
this)(i), (*
this)(i-1)))
1922 (*this)(
dst) = (*
this)(i);
1933 template<
typename T>
1934 struct srdCompareEqual
1936 bool operator()(
const T&
x,
const T&
y)
const {
return (x == y); }
1940 template <
typename T>
1944 srdCompareEqual<T>
cmp;
1945 return sortedRemoveDuplicatesIf(cmp);
1948 template <
typename T>
1949 template <
typename BinaryOp>
1954 for (
exint i = 0; i < mySize; i++)
1955 sum =
add(sum, myData[i]);
1959 #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
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
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.
#define SYS_PRAGMA_DISABLE_STRINGOP_OVERREAD()
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