mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-12 21:45:19 -04:00
32c32a73ca
Merges 44 upstream commits from zeldaret/tp decomp/main. Conflict resolutions: - .github/workflows/build.yml: keep deleted (not needed for PC port) - README.md: keep PC port README - J3DAnimation.h: keep OFFSET_PTR macro + add upstream forward decl - J3DModelLoader.h: keep BE(u32) mBlockNum + add field_0x1c - d_com_inf_game.h: keep PC port inlines + add upstream declarations - global.h: keep MULTI_CHAR macro + add FABSF macro - JUTConsole.cpp: keep uintptr_t cast for 64-bit - JUTDbPrint.cpp: keep PC enter_() helper + add cstring include - JUTResFont.cpp: take upstream loop/struct improvements with BE types - JUTCacheFont.cpp: take upstream decomp fix - float.h: use upstream !PLATFORM_GCN guard - d_a_npc_bouS/theB.cpp: keep MULTI_CHAR() for PC portability - d_a_npc_henna.cpp: keep uintptr_t + use upstream var name - d_demo.cpp: keep near_/far_ field renames for PC - d_resorce.cpp: keep uintptr_t + fix var name to res - d_s_room.cpp, m_Do_graphic.cpp: keep dusk includes + add cstring - m_Do_main.cpp: keep JHIComPortManager + use JAS_GLOBAL_INSTANCE_INIT - angle_utils.h: remove redundant types.h include
170 lines
4.6 KiB
C++
170 lines
4.6 KiB
C++
#ifndef JGADGET_SEARCH_H
|
|
#define JGADGET_SEARCH_H
|
|
|
|
#include <dolphin/types.h>
|
|
#include <iterator>
|
|
#include <functional>
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
|
|
namespace JGadget {
|
|
namespace search {
|
|
template <typename T>
|
|
struct TExpandStride_ {
|
|
#ifdef TARGET_PC
|
|
static T get(T n) { return n << 3; }
|
|
#endif
|
|
};
|
|
|
|
template <>
|
|
struct TExpandStride_<s32> {
|
|
static s32 get(s32 n) { return n << 3; }
|
|
};
|
|
|
|
struct TPR1IsEqual_string_ {
|
|
TPR1IsEqual_string_(const char* sz) {
|
|
string_ = sz;
|
|
}
|
|
|
|
bool operator()(const char* sz) const {
|
|
bool ret;
|
|
if (string_ == NULL) {
|
|
ret = sz == NULL;
|
|
} else {
|
|
ret = sz != NULL && strcmp(string_, sz) == 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
const char* string_;
|
|
};
|
|
|
|
} // namespace search
|
|
|
|
const char* toStringFromIndex(int index, const char* const* pValue, u32 count, const char* fallback);
|
|
int toIndexFromString_linear(const char*, const char* const*, u32, int);
|
|
|
|
template <typename T>
|
|
inline const T& toValueFromIndex(int idx, const T* pValue, u32 count, const T& fallback) {
|
|
JUT_ASSERT(200, pValue!=NULL);
|
|
u32 index = idx;
|
|
if (index >= count) {
|
|
return fallback;
|
|
} else {
|
|
return pValue[index];
|
|
}
|
|
}
|
|
|
|
template <typename T, typename Predicate>
|
|
inline int toIndexFromValue_linear_if(Predicate p, const T* pValue, u32 count, int fallback) {
|
|
JUT_ASSERT(212, pValue!=NULL);
|
|
|
|
const T* first = pValue;
|
|
const T* last = pValue + count;
|
|
const T* found = std::find_if(first, last, p);
|
|
|
|
if (found == last) {
|
|
return fallback;
|
|
}
|
|
|
|
return std::distance(first, found);
|
|
}
|
|
|
|
template <typename Category, typename T, typename Distance, typename Pointer, typename Reference>
|
|
struct TIterator : public std::iterator<Category, T, Distance, Pointer, Reference> {
|
|
};
|
|
|
|
template <typename Iterator>
|
|
struct TIterator_reverse : public std::reverse_iterator<Iterator> {
|
|
TIterator_reverse() {}
|
|
TIterator_reverse(Iterator it) : std::reverse_iterator<Iterator>(it) {}
|
|
};
|
|
|
|
template <typename Iterator, typename T, typename Predicate>
|
|
inline Iterator findUpperBound_binary_all(Iterator first, Iterator last, const T& val, Predicate p) {
|
|
return std::upper_bound(first, last, val, p);
|
|
}
|
|
|
|
template <typename Iterator, typename T, typename Predicate>
|
|
inline Iterator findUpperBound_binary_begin(Iterator first, Iterator last, const T& val, Predicate p) {
|
|
if (first == last) {
|
|
return last;
|
|
}
|
|
|
|
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
|
|
difference_type dist = std::distance(first, last);
|
|
difference_type stride = 1;
|
|
search::TExpandStride_<difference_type> expand;
|
|
Iterator i = first;
|
|
|
|
while (true) {
|
|
if (p(val, *i)) {
|
|
if (stride == 1) {
|
|
return i;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
first = i;
|
|
dist -= stride;
|
|
if (dist <= 0) {
|
|
i = last;
|
|
break;
|
|
}
|
|
i += stride;
|
|
stride = expand.get(stride);
|
|
}
|
|
|
|
return findUpperBound_binary_all(first, i, val, p);
|
|
}
|
|
|
|
template <typename Iterator, typename T, typename Predicate>
|
|
inline Iterator findUpperBound_binary_end(Iterator first, Iterator last, const T& val, Predicate p) {
|
|
if (first == last) {
|
|
return last;
|
|
}
|
|
|
|
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
|
|
--last;
|
|
difference_type dist = std::distance(first, last);
|
|
difference_type stride = 1;
|
|
search::TExpandStride_<difference_type> expand;
|
|
Iterator i = last;
|
|
|
|
while (true) {
|
|
if (!p(val, *i)) {
|
|
if (stride == 1) {
|
|
return ++i;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
last = i;
|
|
dist -= stride;
|
|
if (dist <= 0) {
|
|
i = first;
|
|
break;
|
|
}
|
|
i -= stride;
|
|
stride = expand.get(stride);
|
|
}
|
|
|
|
return findUpperBound_binary_all(i, ++last, val, p);
|
|
}
|
|
|
|
template <typename Iterator, typename T, typename Predicate>
|
|
inline Iterator findUpperBound_binary_current(Iterator first, Iterator last, Iterator current, const T& val, Predicate p) {
|
|
return current == last || p(val, *current) ?
|
|
findUpperBound_binary_end(first, current, val, p) :
|
|
findUpperBound_binary_begin(current, last, val, p);
|
|
}
|
|
|
|
template <typename Iterator, typename T>
|
|
inline Iterator findUpperBound_binary_current(Iterator first, Iterator last, Iterator current, const T& val) {
|
|
return findUpperBound_binary_current(first, last, current, val, std::less<T>());
|
|
}
|
|
|
|
} // namespace JGadget
|
|
|
|
#endif /* JGADGET_SEARCH_H */
|