Files
fs2open.github.com/code/globalincs/vmallocator.cpp
T
Goober5000 133b033ea0 some upgrades to vmallocator.h
Make `SCP_vector`, `SCP_list`, `SCP_set`, and `SCP_multiset` subclasses of their STL counterparts.  This allows helper functions to be added to each, including the `contains()` function which is not available until C++20.  (This has minor effects on other parts of the codebase that treated `SCP_` and `std::` as synonyms.)  Since there is now a nontrivial amount of code that needs to be in a .cpp file, create vmallocator.cpp.

Note that `SCP_string` truncation has been refactored to use length rather than C-string size to be consistent with other `std::basic_string` functions.

Also, remove some enum class hashing code which is no longer necessary now that the codebase is at C++17.
2025-02-02 14:54:26 -05:00

129 lines
2.3 KiB
C++

// Stuff that can't be included in vmallocator.h
#include "globalincs/vmallocator.h"
std::locale SCP_default_locale("");
void SCP_tolower(SCP_string &str)
{
std::for_each(str.begin(), str.end(), [](char &ch) { ch = SCP_tolower(ch); });
}
void SCP_toupper(SCP_string &str)
{
std::for_each(str.begin(), str.end(), [](char &ch) { ch = SCP_toupper(ch); });
}
void SCP_tolower(char *str)
{
for (; *str != '\0'; ++str)
*str = SCP_tolower(*str);
}
void SCP_toupper(char *str)
{
for (; *str != '\0'; ++str)
*str = SCP_toupper(*str);
}
// in-place modification of string to title case; this is a bit naive but it is good enough for the time being
void SCP_totitle(char *str)
{
bool prev_alpha = false;
for (; *str != '\0'; ++str)
{
bool this_alpha = (*str >= 'a' && *str <= 'z') || (*str >= 'A' && *str <= 'Z');
if (this_alpha)
{
if (prev_alpha)
*str = SCP_tolower(*str);
else
*str = SCP_toupper(*str);
}
prev_alpha = this_alpha;
}
}
// in-place modification of string to title case; same naive algorithm as above
void SCP_totitle(SCP_string &str)
{
SCP_string title_str;
bool prev_alpha = false;
std::for_each(str.begin(), str.end(), [&prev_alpha](char &ch)
{
bool this_alpha = (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
if (this_alpha)
{
if (prev_alpha)
ch = SCP_tolower(ch);
else
ch = SCP_toupper(ch);
}
prev_alpha = this_alpha;
});
}
bool SCP_truncate(SCP_string &str, size_t len)
{
if (str.length() > len)
{
str.resize(len);
return true;
}
else
return false;
}
bool lcase_equal(const SCP_string& _Left, const SCP_string& _Right)
{
if (_Left.size() != _Right.size())
return false;
auto l_it = _Left.cbegin();
auto r_it = _Right.cbegin();
while (l_it != _Left.cend())
{
if (SCP_tolower(*l_it) != SCP_tolower(*r_it))
return false;
++l_it;
++r_it;
}
return true;
}
bool lcase_lessthan(const SCP_string& _Left, const SCP_string& _Right)
{
auto l_it = _Left.cbegin();
auto r_it = _Right.cbegin();
while (true)
{
if (l_it == _Left.cend())
return (r_it != _Right.cend());
else if (r_it == _Right.cend())
return false;
auto lch = SCP_tolower(*l_it);
auto rch = SCP_tolower(*r_it);
if (lch < rch)
return true;
else if (lch > rch)
return false;
++l_it;
++r_it;
}
return true;
}