Added lower/upperBound, templatizes comparison functions.

This commit is contained in:
Бранимир Караџић
2022-08-21 16:21:51 -07:00
parent 2a81637f99
commit a8545d7b5b
4 changed files with 429 additions and 48 deletions

View File

@@ -9,6 +9,92 @@
namespace bx
{
template<typename Ty>
inline int32_t compareAscending(const void* _lhs, const void* _rhs)
{
const Ty lhs = *static_cast<const Ty*>(_lhs);
const Ty rhs = *static_cast<const Ty*>(_rhs);
return (lhs > rhs) - (lhs < rhs);
}
template<typename Ty>
inline int32_t compareDescending(const void* _lhs, const void* _rhs)
{
return compareAscending<Ty>(_rhs, _lhs);
}
template<>
inline int32_t compareAscending<const char*>(const void* _lhs, const void* _rhs)
{
return strCmp(*(const char**)_lhs, *(const char**)_rhs);
}
template<>
inline int32_t compareAscending<StringView>(const void* _lhs, const void* _rhs)
{
return strCmp(*(const StringView*)_lhs, *(const StringView*)_rhs);
}
template<typename Ty>
void quickSort(Ty* _data, uint32_t _num, const ComparisonFn _fn)
{
quickSort( (void*)_data, _num, sizeof(Ty), _fn);
}
template<typename Ty>
void quickSort(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
{
quickSort(_data, _num, _stride, _fn);
}
template<typename Ty>
uint32_t lowerBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn)
{
return lowerBound( (const void*)&_key, _data, _num, sizeof(Ty), _fn);
}
template<typename Ty>
uint32_t lowerBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
{
return lowerBound( (const void*)&_key, _data, _num, _stride, _fn);
}
template<typename Ty>
uint32_t upperBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn)
{
return upperBound( (const void*)&_key, _data, _num, sizeof(Ty), _fn);
}
template<typename Ty>
uint32_t upperBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
{
return upperBound( (const void*)&_key, _data, _num, _stride, _fn);
}
template<typename Ty>
bool isSorted(const Ty* _data, uint32_t _num, const ComparisonFn _fn)
{
return isSorted(_data, _num, sizeof(Ty), _fn);
}
template<typename Ty>
bool isSorted(const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
{
return isSorted(_data, _num, _stride, _fn);
}
template<typename Ty>
int32_t binarySearch(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn)
{
return binarySearch( (const void*)&_key, _data, _num, sizeof(Ty), _fn);
}
template<typename Ty>
int32_t binarySearch(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
{
return binarySearch( (const void*)&_key, _data, _num, _stride, _fn);
}
namespace radix_sort_detail
{
constexpr uint32_t kBits = 11;

View File

@@ -7,6 +7,8 @@
#define BX_SORT_H_HEADER_GUARD
#include "bx.h"
#include "math.h"
#include "string.h"
namespace bx
{
@@ -19,6 +21,26 @@ namespace bx
///
typedef int32_t (*ComparisonFn)(const void* _lhs, const void* _rhs);
/// The function compares the `_lhs` and `_rhs` values.
///
/// @returns Returns value:
/// - less than zero if `_lhs` is less than `_rhs`
/// - zero if `_lhs` is equivalent to `_rhs`
/// - greater than zero if `_lhs` is greater than `_rhs`
///
template<typename Ty>
int32_t compareAscending(const void* _lhs, const void* _rhs);
/// The function compares the `_lhs` and `_rhs` values.
///
/// @returns Returns value:
/// - less than zero if `_lhs` is greated than `_rhs`
/// - zero if `_lhs` is equivalent to `_rhs`
/// - greater than zero if `_lhs` is less than `_rhs`
///
template<typename Ty>
int32_t compareDescending(const void* _lhs, const void* _rhs);
/// Performs sort (Quick Sort algorithm).
///
/// @param _data Pointer to sorted array data.
@@ -33,39 +55,24 @@ namespace bx
, const ComparisonFn _fn
);
/// Performs sort (Quick Sort algorithm).
///
void radixSort(
uint32_t* _keys
, uint32_t* _tempKeys
, uint32_t _size
);
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _fn Comparison function.
///
template<typename Ty>
void quickSort(Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
/// Performs sort (Quick Sort algorithm).
///
template <typename Ty>
void radixSort(
uint32_t* _keys
, uint32_t* _tempKeys
, Ty* _values
, Ty* _tempValues
, uint32_t _size
);
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _stride Element stride in bytes.
/// @param _fn Comparison function.
///
void radixSort(
uint64_t* _keys
, uint64_t* _tempKeys
, uint32_t _size
);
///
template <typename Ty>
void radixSort(
uint64_t* _keys
, uint64_t* _tempKeys
, Ty* _values
, Ty* _tempValues
, uint32_t _size
);
template<typename Ty>
void quickSort(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
/// Performs check if array is sorted.
///
@@ -83,6 +90,115 @@ namespace bx
, const ComparisonFn _fn
);
/// Performs check if array is sorted.
///
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _fn Comparison function.
///
/// @returns Returns `true` if array is sorted, otherwise returns `false`.
///
template<typename Ty>
bool isSorted(const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
/// Performs check if array is sorted.
///
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _stride Element stride in bytes.
/// @param _fn Comparison function.
///
/// @returns Returns `true` if array is sorted, otherwise returns `false`.
///
template<typename Ty>
bool isSorted(const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
/// Returns an index to the first element greater or equal than the `_key` value.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _stride Element stride in bytes.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns an index to the first element greater or equal than the `_key` value.
///
uint32_t lowerBound(const void* _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
/// Returns an index to the first element greater or equal than the `_key` value.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns an index to the first element greater or equal than the `_key` value.
///
template<typename Ty>
uint32_t lowerBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
/// Returns an index to the first element greater or equal than the `_key` value.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _stride Element stride in bytes.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns an index to the first element greater or equal than the `_key` value.
///
template<typename Ty>
uint32_t lowerBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
/// Returns an index to the first element greater than the `_key` value.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _stride Element stride in bytes.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns an index to the first element greater than the `_key` value.
///
uint32_t upperBound(const void* _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
/// Returns an index to the first element greater than the `_key` value.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns an index to the first element greater than the `_key` value.
///
template<typename Ty>
uint32_t upperBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
/// Returns an index to the first element greater than the `_key` value.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _stride Element stride in bytes.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns an index to the first element greater than the `_key` value.
///
template<typename Ty>
uint32_t upperBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
/// Performs binary search of a sorted array.
///
/// @param _key Pointer to the key to search for.
@@ -103,6 +219,69 @@ namespace bx
, const ComparisonFn _fn
);
/// Performs binary search of a sorted array.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns index of element or -1 if the key is not found in sorted array.
///
template<typename Ty>
int32_t binarySearch(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
/// Performs binary search of a sorted array.
///
/// @param _key Pointer to the key to search for.
/// @param _data Pointer to sorted array data.
/// @param _num Number of elements.
/// @param _stride Element stride in bytes.
/// @param _fn Comparison function.
///
/// @remarks Array must be sorted!
///
/// @returns Returns index of element or -1 if the key is not found in sorted array.
///
template<typename Ty>
int32_t binarySearch(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride = sizeof(Ty), const ComparisonFn _fn = compareAscending<Ty>);
///
void radixSort(
uint32_t* _keys
, uint32_t* _tempKeys
, uint32_t _size
);
///
template <typename Ty>
void radixSort(
uint32_t* _keys
, uint32_t* _tempKeys
, Ty* _values
, Ty* _tempValues
, uint32_t _size
);
///
void radixSort(
uint64_t* _keys
, uint64_t* _tempKeys
, uint32_t _size
);
///
template <typename Ty>
void radixSort(
uint64_t* _keys
, uint64_t* _tempKeys
, Ty* _values
, Ty* _tempValues
, uint32_t _size
);
} // namespace bx
#include "inline/sort.inl"