11 #ifndef __UT_Permute__
12 #define __UT_Permute__
32 template<
typename IT,
typename PRED>
41 while (isbeforesplit(*start))
54 }
while(!isbeforesplit(*end));
74 template<
typename IT,
typename COMPARE>
89 auto diff = (end-
start);
90 auto hdiff = (diff>>1);
91 const IT mid = (start+hdiff);
92 const IT
last = end-1;
97 if (isAbeforeB(*last, *start))
99 if (isAbeforeB(*mid, *start))
101 if (isAbeforeB(*last, *mid))
111 if (isAbeforeB(*mid, *start))
115 if (isAbeforeB(*last, *mid))
127 {
return isAbeforeB(v, pivot); }
138 {
return !isAbeforeB(pivot, v); }
144 else if (nth < split2)
154 if (isAbeforeB(*(end-1), *start))
155 UTswap(*start, *(end-1));
162 template<
typename IT>
196 memcpy(tmp.
array(), a.
ptr(), nbytes);
197 memcpy(a.
ptr(), b.
ptr(), nbytes);
198 memcpy(b.
ptr(), tmp.
array(), nbytes);
287 namespace UT_Permute {
289 template <
typename T,
typename INT>
298 return myPermute[&rhs-myLow] < myMid;
302 const INT *myPermute;
306 template <
typename INT>
316 return myPermute[(((
char*)rhs.
ptr())-((
char*)myLow.
ptr()))/myLow.
elementBytes()] < myMid;
320 const INT *myPermute;
324 template<
typename INT>
336 static const int theCrossover = 1024;
338 template <
typename T,
typename INT>
340 permuteInPlaceRHelper(T *vals, INT *permute, INT low, INT high)
344 for (INT i = low; i < high; i++)
345 tmp[permute[i]-low] = vals[i];
346 memcpy(vals + low, tmp, size*
sizeof(T));
349 template <
typename INT>
351 permuteInPlaceRHelper(
void *vals,
size_t element_bytes, INT *permute, INT low, INT high)
355 for (INT i = low; i < high; i++)
357 memcpy(tmp.array() + element_bytes*(permute[i]-low), ((
const char *)vals) + element_bytes*i, element_bytes);
359 memcpy(((
char *)vals) + element_bytes*low, tmp.array(), size*element_bytes);
363 template <typename T, typename INT>
365 permuteInPlaceR(T *vals, INT *permute, INT low, INT high)
368 if (size < theCrossover)
370 permuteInPlaceRHelper(vals, permute, low, high);
374 INT mid = (low + high) / 2;
378 Partition<T,INT>(vals + low, permute + low, mid));
381 PartitionPermute<INT>(mid));
383 tbb::parallel_invoke(
384 [=]() { permuteInPlaceR(vals, permute, low, mid); },
385 [=]() { permuteInPlaceR(vals, permute, mid, high); }
390 template <
typename INT>
395 if (size < theCrossover)
397 permuteInPlaceRHelper(vals.
ptr(), vals.
elementBytes(), permute, low, high);
401 INT mid = (low + high) / 2;
405 PartitionUnknown<INT>(vals + low, permute + low, mid));
408 PartitionPermute<INT>(mid));
410 tbb::parallel_invoke(
411 [=]() { permuteInPlaceR(vals, permute, low, mid); },
412 [=]() { permuteInPlaceR(vals, permute, mid, high); }
422 template <
typename T,
typename INT>
424 UTpermuteInPlace(T *vals, INT *permute, INT size)
426 UT_Permute::permuteInPlaceR(vals, permute,
INT(0), size);
430 template <
typename T,
typename INT>
432 UTpermute(T *vals,
const INT *permute, INT size)
435 memcpy(tmp_permute, permute, size*
sizeof(INT));
437 UT_Permute::permuteInPlaceR(vals, tmp_permute.array(),
INT(0),
size);
443 template <
typename T,
typename INT>
445 UTinversePermute(T *vals,
const INT *permute, INT size)
448 for (INT i = 0; i <
size; i++)
449 tmp_permute[permute[i]] = i;
451 UT_Permute::permuteInPlaceR(vals, tmp_permute.array(),
INT(0),
size);
458 template <
typename INT>
460 UTinversePermute(
void *vals,
size_t element_bytes,
const INT *permute, INT nelements)
463 for (INT i = 0; i < nelements; i++)
464 tmp_permute[permute[i]] = i;
466 UT_Permute::permuteInPlaceR(
UT_VariableSizePtr(vals, element_bytes), tmp_permute.array(),
INT(0), nelements);
469 template <
typename INT>
473 for (
int i = 0; i <
size; i++)
476 for (
int i = size; i-- > 1; )
478 int k = twist.
urandom() % (i+1);
bool operator()(INT rhs) const
UT_VariableSizePtr operator+(const size_t i) const
bool operator==(const UT_VariableSizePtr &that) const
void UTnth_element(IT start, IT nth, IT end, COMPARE isAbeforeB)
UT_VariableSizeRef(void *p, size_t element_bytes)
IT UTpartition(IT start, IT end, PRED isbeforesplit)
bool operator!=(const UT_VariableSizePtr &that) const
Partition(T *low, const INT *permute, INT mid)
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
UT_VariableSizeRef operator*() const
GA_API const UT_StringHolder twist
PartitionPermute(INT mid)
GLboolean GLboolean GLboolean GLboolean a
UT_VariableSizePtr & operator++()
const size_t myElementBytes
bool operator<=(const UT_VariableSizePtr &that) const
bool operator>(const UT_VariableSizePtr &that) const
UT_VariableSizeRef & operator=(const UT_VariableSizeRef &that)=delete
UT_VariableSizePtr & operator--()
bool operator()(const T &rhs) const
const size_t myElementBytes
GLboolean GLboolean GLboolean b
void operator-=(const size_t i)
__hostdev__ uint64_t last(uint32_t i) const
size_t elementBytes() const
PartitionUnknown(UT_VariableSizePtr low, const INT *permute, INT mid)
bool operator()(const UT_VariableSizeRef &rhs) const
UT_VariableSizePtr operator-(const size_t i) const
GA_API const UT_StringHolder pivot
size_t elementBytes() const
UT_VariableSizePtr(void *p, size_t element_bytes)
bool operator<(const UT_VariableSizePtr &that) const
UT_VariableSizeRef operator[](const size_t i) const
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
void operator+=(const size_t i)
bool operator>=(const UT_VariableSizePtr &that) const