Made strCmp, strCmpI and strCmpV constexpr. (#470)

This commit is contained in:
Branimir Karadžić
2026-10-21 14:43:01 -07:00
committed by GitHub
parent c500a9228e
commit 97aa6da7db
4 changed files with 147 additions and 130 deletions

View File

@@ -577,6 +577,133 @@ namespace bx
return int32_t(ptr - _str);
}
typedef char (*CharFn)(char _ch);
inline BX_CONSTEXPR_FUNC char toNoop(char _ch)
{
return _ch;
}
template<CharFn fn>
inline constexpr int32_t strCmp(const char* _lhs, int32_t _lhsMax, const char* _rhs, int32_t _rhsMax)
{
int32_t max = min(_lhsMax, _rhsMax);
for (
; 0 < max && fn(*_lhs) == fn(*_rhs)
; ++_lhs, ++_rhs, --max
)
{
if (*_lhs == '\0'
|| *_rhs == '\0')
{
break;
}
}
if (0 == max)
{
return _lhsMax == _rhsMax ? 0 : _lhsMax > _rhsMax ? 1 : -1;
}
return fn(*_lhs) - fn(*_rhs);
}
inline constexpr int32_t strCmp(const StringView& _lhs, const StringView& _rhs, int32_t _max)
{
return strCmp<toNoop>(
_lhs.getPtr()
, min(_lhs.getLength(), _max)
, _rhs.getPtr()
, min(_rhs.getLength(), _max)
);
}
inline constexpr int32_t strCmpI(const StringView& _lhs, const StringView& _rhs, int32_t _max)
{
return strCmp<toLower>(
_lhs.getPtr()
, min(_lhs.getLength(), _max)
, _rhs.getPtr()
, min(_rhs.getLength(), _max)
);
}
inline constexpr int32_t strCmpV(const char* _lhs, int32_t _lhsMax, const char* _rhs, int32_t _rhsMax)
{
int32_t max = min(_lhsMax, _rhsMax);
int32_t ii = 0;
int32_t idx = 0;
bool zero = true;
for (
; 0 < max && _lhs[ii] == _rhs[ii]
; ++ii, --max
)
{
const uint8_t ch = _lhs[ii];
if ('\0' == ch
|| '\0' == _rhs[ii])
{
break;
}
if (!isNumeric(ch) )
{
idx = ii+1;
zero = true;
}
else if ('0' != ch)
{
zero = false;
}
}
if (0 == max)
{
return _lhsMax == _rhsMax ? 0 : _lhs[ii] - _rhs[ii];
}
if ('0' != _lhs[idx]
&& '0' != _rhs[idx])
{
int32_t jj = 0;
for (jj = ii
; 0 < max && isNumeric(_lhs[jj])
; ++jj, --max
)
{
if (!isNumeric(_rhs[jj]) )
{
return 1;
}
}
if (isNumeric(_rhs[jj]))
{
return -1;
}
}
else if (zero
&& idx < ii
&& (isNumeric(_lhs[ii]) || isNumeric(_rhs[ii]) ) )
{
return (_lhs[ii] - '0') - (_rhs[ii] - '0');
}
return 0 == max && _lhsMax == _rhsMax ? 0 : _lhs[ii] - _rhs[ii];
}
inline constexpr int32_t strCmpV(const StringView& _lhs, const StringView& _rhs, int32_t _max)
{
return strCmpV(
_lhs.getPtr()
, min(_lhs.getLength(), _max)
, _rhs.getPtr()
, min(_rhs.getLength(), _max)
);
}
inline bool hasPrefix(const StringView& _str, const StringView& _prefix)
{
const int32_t len = _prefix.getLength();

View File

@@ -375,13 +375,13 @@ namespace bx
void toUpper(char* _inOutStr, int32_t _max = INT32_MAX);
/// String compare.
int32_t strCmp(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX);
constexpr int32_t strCmp(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX);
/// Case insensitive string compare.
int32_t strCmpI(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX);
constexpr int32_t strCmpI(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX);
// Compare as strings holding indices/version numbers.
int32_t strCmpV(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX);
constexpr int32_t strCmpV(const StringView& _lhs, const StringView& _rhs, int32_t _max = INT32_MAX);
/// Get string length.
constexpr int32_t strLen(const char* _str, int32_t _max = INT32_MAX);