core::array search functions can now work with other template types.

Previously search functions only worked when called with the same type as the array elements had.
Which forced users sometimes to create dummy objects to be able to search for elements by another type.
linear_search and linear_reverse_search now work with any type for which <T>::operator== is implemented.
Similar binary_search now works when <T>::operator< is implemented in both directions (T < E and E < T).
Note: It might be possible to further improve binary_search so only one operator< is needed (I think STL managed that somehow).
So if someone likes a challenge - have a go at it! :-)

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6398 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2022-05-14 18:27:35 +00:00
parent ca4bbcb71f
commit 0f7eb1f6e1
3 changed files with 28 additions and 17 deletions

@ -1,6 +1,7 @@
--------------------------
Changes in 1.9 (not yet released)
- core::array search functions can now work with any types as long as corresponding operator= (linear_search) or operator< (binary_search) are implemented.
- Add checks for sane image sizes in some image loaders (so far: bmp, jpg, tga, png).
Thanks @sfan5 for the original patch (got modified a bit): https://github.com/minetest/irrlicht/commit/dbd39120e7ed8c0c97e48e2df62347627f3c1d42
- Add IImage::checkDataSizeLimit and make IImage getDataSizeFromFormat return size_t so image loaders can check if sizes are sane.

@ -432,10 +432,12 @@ public:
/** The array will be sorted before the binary search if it is not
already sorted. Caution is advised! Be careful not to call this on
unsorted const arrays, or the slower method will be used.
Only works if corresponding operator< is implemented.
\param element Element to search for.
\return Position of the searched element if it was found,
otherwise -1 is returned. */
s32 binary_search(const T& element)
template <class E>
s32 binary_search(const E& element)
{
sort();
return binary_search(element, 0, used-1);
@ -445,10 +447,12 @@ public:
//! Performs a binary search for an element if possible, returns -1 if not found.
/** This method is for const arrays and so cannot call sort(), if the array is
not sorted then linear_search will be used instead. Potentially very slow!
Only works if corresponding operator< is implemented.
\param element Element to search for.
\return Position of the searched element if it was found,
otherwise -1 is returned. */
s32 binary_search(const T& element) const
template <class E>
s32 binary_search(const E& element) const
{
if (is_sorted)
return binary_search(element, 0, used-1);
@ -458,12 +462,14 @@ public:
//! Performs a binary search for an element, returns -1 if not found.
/** \param element: Element to search for.
/** Only works if corresponding operator< is implemented.
\param element: Element to search for.
\param left First left index
\param right Last right index.
\return Position of the searched element if it was found, otherwise -1
is returned. */
s32 binary_search(const T& element, s32 left, s32 right) const
template <class E>
s32 binary_search(const E& element, s32 left, s32 right) const
{
if (!used)
return -1;
@ -497,11 +503,13 @@ public:
//! it is used for searching a multiset
/** The array will be sorted before the binary search if it is not
already sorted.
Only works if corresponding operator< is implemented.
\param element Element to search for.
\param &last return lastIndex of equal elements
\return Position of the first searched element if it was found,
otherwise -1 is returned. */
s32 binary_search_multi(const T& element, s32 &last)
template <class E>
s32 binary_search_multi(const E& element, s32 &last)
{
sort();
s32 index = binary_search(element, 0, used-1);
@ -526,29 +534,31 @@ public:
}
//! Finds an element in linear time, which is very slow.
/** Use binary_search for faster finding. Only works if ==operator is
implemented.
//! Finds an element by searching linearly from array start to end
/** Can be slow with large arrays, try binary_search for those.
Only works if corresponding operator== is implemented.
\param element Element to search for.
\return Position of the searched element if it was found, otherwise -1
is returned. */
s32 linear_search(const T& element) const
template <class E>
s32 linear_search(const E& element) const
{
for (u32 i=0; i<used; ++i)
if (element == data[i])
if (data[i] == element)
return (s32)i;
return -1;
}
//! Finds an element in linear time, which is very slow.
/** Use binary_search for faster finding. Only works if ==operator is
implemented.
\param element: Element to search for.
//! Finds an element by searching linearly from array end to start.
/** Can be slow with large arrays, try binary_search for those.
Only works if corresponding operator== is implemented.
\param element Element to search for.
\return Position of the searched element if it was found, otherwise -1
is returned. */
s32 linear_reverse_search(const T& element) const
template <class E>
s32 linear_reverse_search(const E& element) const
{
for (s32 i=used-1; i>=0; --i)
if (data[i] == element)

@ -1,4 +1,4 @@
Tests finished. 72 tests of 72 passed.
Compiled as DEBUG
Test suite pass at GMT Sun May 08 15:37:29 2022
Test suite pass at GMT Sat May 14 18:16:57 2022