Merge pull request #3 from lioncash/str

hecl/hecl: Minor changes and improvements to string utilities
This commit is contained in:
Phillip Stephens 2019-08-15 07:47:17 -07:00 committed by GitHub
commit 23551de349
2 changed files with 91 additions and 58 deletions

View File

@ -26,7 +26,6 @@ namespace hecl {
#if HECL_UCS2 #if HECL_UCS2
typedef wchar_t SystemChar; typedef wchar_t SystemChar;
static inline size_t StrLen(const SystemChar* str) { return wcslen(str); }
typedef std::wstring SystemString; typedef std::wstring SystemString;
typedef std::wstring_view SystemStringView; typedef std::wstring_view SystemStringView;
static inline void ToLower(SystemString& str) { std::transform(str.begin(), str.end(), str.begin(), towlower); } static inline void ToLower(SystemString& str) { std::transform(str.begin(), str.end(), str.begin(), towlower); }
@ -37,15 +36,22 @@ static inline void ToUpper(SystemString& str) { std::transform(str.begin(), str.
typedef struct _stat Sstat; typedef struct _stat Sstat;
#else #else
typedef char SystemChar; typedef char SystemChar;
static inline size_t StrLen(const SystemChar* str) { return strlen(str); }
typedef std::string SystemString; typedef std::string SystemString;
typedef std::string_view SystemStringView; typedef std::string_view SystemStringView;
static inline void ToLower(SystemString& str) { std::transform(str.begin(), str.end(), str.begin(), tolower); } static inline void ToLower(SystemString& str) {
static inline void ToUpper(SystemString& str) { std::transform(str.begin(), str.end(), str.begin(), toupper); } std::transform(str.begin(), str.end(), str.begin(),
[](SystemChar c) { return std::tolower(static_cast<unsigned char>(c)); });
}
static inline void ToUpper(SystemString& str) {
std::transform(str.begin(), str.end(), str.begin(),
[](SystemChar c) { return std::toupper(static_cast<unsigned char>(c)); });
}
#ifndef _SYS_STR #ifndef _SYS_STR
#define _SYS_STR(val) val #define _SYS_STR(val) val
#endif #endif
typedef struct stat Sstat; typedef struct stat Sstat;
#endif #endif
constexpr size_t StrLen(const SystemChar* str) { return std::char_traits<SystemChar>::length(str); }
} // namespace hecl } // namespace hecl

View File

@ -22,20 +22,22 @@ extern "C" int rep_closefrom(int lower);
#endif #endif
#include <Windows.h> #include <Windows.h>
#include <cwchar> #include <cwchar>
#include <cwctype>
#include <Shlwapi.h> #include <Shlwapi.h>
#include "winsupport.hpp" #include "winsupport.hpp"
#endif #endif
#include <algorithm>
#include <cinttypes> #include <cinttypes>
#include <ctime>
#include <cstdarg> #include <cstdarg>
#include <cstdio> #include <cstdio>
#include <ctime>
#include <functional> #include <functional>
#include <string>
#include <algorithm>
#include <regex>
#include <list> #include <list>
#include <map> #include <map>
#include <regex>
#include <string>
#include "logvisor/logvisor.hpp" #include "logvisor/logvisor.hpp"
#include "athena/Global.hpp" #include "athena/Global.hpp"
#include "../extern/boo/xxhash/xxhash.h" #include "../extern/boo/xxhash/xxhash.h"
@ -109,46 +111,66 @@ class SystemUTF8Conv {
public: public:
explicit SystemUTF8Conv(SystemStringView str) : m_utf8(WideToUTF8(str)) {} explicit SystemUTF8Conv(SystemStringView str) : m_utf8(WideToUTF8(str)) {}
std::string_view str() const { return m_utf8; } std::string_view str() const { return m_utf8; }
const char* c_str() const { return m_utf8.c_str(); } const char* c_str() const { return m_utf8.c_str(); }
std::string operator+(std::string_view other) const { return m_utf8 + other.data(); }
friend std::string operator+(const SystemUTF8Conv& lhs, std::string_view rhs) { return lhs.m_utf8 + rhs.data(); }
friend std::string operator+(std::string_view lhs, const SystemUTF8Conv& rhs) {
return std::string(lhs).append(rhs.m_utf8);
}
}; };
inline std::string operator+(std::string_view lhs, const SystemUTF8Conv& rhs) { return std::string(lhs) + rhs.c_str(); }
class SystemStringConv { class SystemStringConv {
std::wstring m_sys; std::wstring m_sys;
public: public:
explicit SystemStringConv(std::string_view str) : m_sys(UTF8ToWide(str)) {} explicit SystemStringConv(std::string_view str) : m_sys(UTF8ToWide(str)) {}
SystemStringView sys_str() const { return m_sys; } SystemStringView sys_str() const { return m_sys; }
const SystemChar* c_str() const { return m_sys.c_str(); } const SystemChar* c_str() const { return m_sys.c_str(); }
std::wstring operator+(const std::wstring_view other) const { return m_sys + other.data(); }
friend std::wstring operator+(const SystemStringConv& lhs, const std::wstring_view rhs) {
return lhs.m_sys + rhs.data();
}
friend std::wstring operator+(std::wstring_view lhs, const SystemStringConv& rhs) {
return std::wstring(lhs).append(rhs.m_sys);
}
}; };
inline std::wstring operator+(std::wstring_view lhs, const SystemStringConv& rhs) {
return std::wstring(lhs) + rhs.c_str();
}
#else #else
class SystemUTF8Conv { class SystemUTF8Conv {
std::string_view m_utf8; std::string_view m_utf8;
public: public:
explicit SystemUTF8Conv(SystemStringView str) : m_utf8(str) {} explicit SystemUTF8Conv(SystemStringView str) : m_utf8(str) {}
std::string_view str() const { return m_utf8; } std::string_view str() const { return m_utf8; }
const char* c_str() const { return m_utf8.data(); } const char* c_str() const { return m_utf8.data(); }
std::string operator+(std::string_view other) const { return std::string(m_utf8) + other.data(); }
friend std::string operator+(const SystemUTF8Conv& lhs, std::string_view rhs) {
return std::string(lhs.m_utf8).append(rhs);
}
friend std::string operator+(std::string_view lhs, const SystemUTF8Conv& rhs) {
return std::string(lhs).append(rhs.m_utf8);
}
}; };
inline std::string operator+(std::string_view lhs, const SystemUTF8Conv& rhs) { return std::string(lhs) + rhs.c_str(); }
class SystemStringConv { class SystemStringConv {
std::string_view m_sys; std::string_view m_sys;
public: public:
explicit SystemStringConv(std::string_view str) : m_sys(str) {} explicit SystemStringConv(std::string_view str) : m_sys(str) {}
SystemStringView sys_str() const { return m_sys; } SystemStringView sys_str() const { return m_sys; }
const SystemChar* c_str() const { return m_sys.data(); } const SystemChar* c_str() const { return m_sys.data(); }
std::string operator+(std::string_view other) const { return std::string(m_sys) + other.data(); }
friend std::string operator+(const SystemStringConv& lhs, std::string_view rhs) {
return std::string(lhs.m_sys).append(rhs);
}
friend std::string operator+(std::string_view lhs, const SystemStringConv& rhs) {
return std::string(lhs).append(rhs.m_sys);
}
}; };
inline std::string operator+(std::string_view lhs, const SystemStringConv& rhs) {
return std::string(lhs) + rhs.c_str();
}
#endif #endif
void SanitizePath(std::string& path); void SanitizePath(std::string& path);
@ -309,11 +331,8 @@ inline int StrCmp(const SystemChar* str1, const SystemChar* str2) {
inline int StrNCmp(const SystemChar* str1, const SystemChar* str2, size_t count) { inline int StrNCmp(const SystemChar* str1, const SystemChar* str2, size_t count) {
if (!str1 || !str2) if (!str1 || !str2)
return str1 != str2; return str1 != str2;
#if HECL_UCS2
return wcsncmp(str1, str2, count); return std::char_traits<SystemChar>::compare(str1, str2, count);
#else
return strncmp(str1, str2, count);
#endif
} }
inline int StrCaseCmp(const SystemChar* str1, const SystemChar* str2) { inline int StrCaseCmp(const SystemChar* str1, const SystemChar* str2) {
@ -391,13 +410,12 @@ inline int ConsoleWidth(bool* ok = nullptr) {
} }
class MultiProgressPrinter; class MultiProgressPrinter;
typedef std::basic_regex<SystemChar> SystemRegex;
typedef std::regex_token_iterator<SystemString::const_iterator> SystemRegexTokenIterator;
typedef std::match_results<SystemString::const_iterator> SystemRegexMatch;
class ProjectRootPath; class ProjectRootPath;
using SystemRegex = std::basic_regex<SystemChar>;
using SystemRegexMatch = std::match_results<SystemString::const_iterator>;
using SystemRegexTokenIterator = std::regex_token_iterator<SystemString::const_iterator>;
/** /**
* @brief Hash representation used for all storable and comparable objects * @brief Hash representation used for all storable and comparable objects
* *
@ -470,20 +488,16 @@ public:
*/ */
struct CaseInsensitiveCompare { struct CaseInsensitiveCompare {
bool operator()(std::string_view lhs, std::string_view rhs) const { bool operator()(std::string_view lhs, std::string_view rhs) const {
#if _WIN32 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](char lhs, char rhs) {
if (_stricmp(lhs.data(), rhs.data()) < 0) return std::tolower(static_cast<unsigned char>(lhs)) < std::tolower(static_cast<unsigned char>(rhs));
#else });
if (strcasecmp(lhs.data(), rhs.data()) < 0)
#endif
return true;
return false;
} }
#if _WIN32 #if _WIN32
bool operator()(std::wstring_view lhs, std::wstring_view rhs) const { bool operator()(std::wstring_view lhs, std::wstring_view rhs) const {
if (_wcsicmp(lhs.data(), rhs.data()) < 0) return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](wchar_t lhs, wchar_t rhs) {
return true; return std::towlower(lhs) < std::towlower(rhs);
return false; });
} }
#endif #endif
}; };
@ -500,8 +514,8 @@ public:
size_t m_fileSz; size_t m_fileSz;
bool m_isDir; bool m_isDir;
Entry(const hecl::SystemString& path, const hecl::SystemChar* name, size_t sz, bool isDir) Entry(hecl::SystemString path, const hecl::SystemChar* name, size_t sz, bool isDir)
: m_path(path), m_name(name), m_fileSz(sz), m_isDir(isDir) {} : m_path(std::move(path)), m_name(name), m_fileSz(sz), m_isDir(isDir) {}
}; };
private: private:
@ -578,7 +592,8 @@ public:
return SystemString(beginIt, absPathForward.cend()); return SystemString(beginIt, absPathForward.cend());
} }
} }
LogModule.report(logvisor::Fatal, fmt(_SYS_STR("unable to resolve '{}' as project relative '{}'")), absPath, m_projRoot); LogModule.report(logvisor::Fatal, fmt(_SYS_STR("unable to resolve '{}' as project relative '{}'")), absPath,
m_projRoot);
return SystemString(); return SystemString();
} }
@ -1040,21 +1055,21 @@ public:
static bool BeginsWith(SystemStringView str, SystemStringView test) { static bool BeginsWith(SystemStringView str, SystemStringView test) {
if (test.size() > str.size()) if (test.size() > str.size())
return false; return false;
return !StrNCmp(str.data(), test.data(), test.size()); return str.compare(0, test.size(), test) == 0;
} }
static bool EndsWith(SystemStringView str, SystemStringView test) { static bool EndsWith(SystemStringView str, SystemStringView test) {
if (test.size() > str.size()) if (test.size() > str.size())
return false; return false;
return !StrNCmp(&*(str.end() - test.size()), test.data(), test.size()); return str.compare(str.size() - test.size(), SystemStringView::npos, test) == 0;
} }
static std::string TrimWhitespace(std::string_view str) { static std::string TrimWhitespace(std::string_view str) {
auto bit = str.begin(); auto bit = str.begin();
while (bit != str.cend() && isspace(*bit)) while (bit != str.cend() && std::isspace(static_cast<unsigned char>(*bit)))
++bit; ++bit;
auto eit = str.end(); auto eit = str.end();
while (eit != str.cbegin() && isspace(*(eit - 1))) while (eit != str.cbegin() && std::isspace(static_cast<unsigned char>(*(eit - 1))))
--eit; --eit;
return {bit, eit}; return {bit, eit};
} }
@ -1063,21 +1078,21 @@ public:
static bool BeginsWith(std::string_view str, std::string_view test) { static bool BeginsWith(std::string_view str, std::string_view test) {
if (test.size() > str.size()) if (test.size() > str.size())
return false; return false;
return !strncmp(str.data(), test.data(), test.size()); return str.compare(0, test.size(), test) == 0;
} }
static bool EndsWith(std::string_view str, std::string_view test) { static bool EndsWith(std::string_view str, std::string_view test) {
if (test.size() > str.size()) if (test.size() > str.size())
return false; return false;
return !strncmp(&*(str.end() - test.size()), test.data(), test.size()); return str.compare(str.size() - test.size(), std::string_view::npos, test) == 0;
} }
static SystemString TrimWhitespace(SystemStringView str) { static SystemString TrimWhitespace(SystemStringView str) {
auto bit = str.begin(); auto bit = str.begin();
while (bit != str.cend() && iswspace(*bit)) while (bit != str.cend() && std::iswspace(*bit))
++bit; ++bit;
auto eit = str.end(); auto eit = str.end();
while (eit != str.cbegin() && iswspace(*(eit - 1))) while (eit != str.cbegin() && std::iswspace(*(eit - 1)))
--eit; --eit;
return {bit, eit}; return {bit, eit};
} }
@ -1096,9 +1111,9 @@ class ResourceLock {
bool good; bool good;
public: public:
operator bool() const { return good; } explicit operator bool() const { return good; }
static bool InProgress(const ProjectPath& path); static bool InProgress(const ProjectPath& path);
ResourceLock(const ProjectPath& path) { good = SetThreadRes(path); } explicit ResourceLock(const ProjectPath& path) : good{SetThreadRes(path)} {}
~ResourceLock() { ~ResourceLock() {
if (good) if (good)
ClearThreadRes(); ClearThreadRes();
@ -1196,13 +1211,25 @@ constexpr uint32_t SBig(uint32_t val) { return bswap32(val); }
constexpr int64_t SBig(int64_t val) { return bswap64(val); } constexpr int64_t SBig(int64_t val) { return bswap64(val); }
constexpr uint64_t SBig(uint64_t val) { return bswap64(val); } constexpr uint64_t SBig(uint64_t val) { return bswap64(val); }
constexpr float SBig(float val) { constexpr float SBig(float val) {
union { float f; atInt32 i; } uval1 = {val}; union {
union { atInt32 i; float f; } uval2 = {bswap32(uval1.i)}; float f;
atInt32 i;
} uval1 = {val};
union {
atInt32 i;
float f;
} uval2 = {bswap32(uval1.i)};
return uval2.f; return uval2.f;
} }
constexpr double SBig(double val) { constexpr double SBig(double val) {
union { double f; atInt64 i; } uval1 = {val}; union {
union { atInt64 i; double f; } uval2 = {bswap64(uval1.i)}; double f;
atInt64 i;
} uval1 = {val};
union {
atInt64 i;
double f;
} uval2 = {bswap64(uval1.i)};
return uval2.f; return uval2.f;
} }
#ifndef SBIG #ifndef SBIG
@ -1254,7 +1281,7 @@ constexpr double SBig(double val) { return val; }
template <typename SizeT> template <typename SizeT>
constexpr void hash_combine_impl(SizeT& seed, SizeT value) { constexpr void hash_combine_impl(SizeT& seed, SizeT value) {
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);
} }
} // namespace hecl } // namespace hecl