alstring.cpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #include "config.h"
  2. #include "alstring.h"
  3. #include <algorithm>
  4. #include <cctype>
  5. #include <cwctype>
  6. #include <cstring>
  7. #include <string>
  8. namespace al {
  9. int case_compare(const std::string_view str0, const std::string_view str1) noexcept
  10. {
  11. using Traits = std::string_view::traits_type;
  12. auto ch0 = str0.cbegin();
  13. auto ch1 = str1.cbegin();
  14. auto ch1end = ch1 + std::min(str0.size(), str1.size());
  15. while(ch1 != ch1end)
  16. {
  17. const int u0{std::toupper(Traits::to_int_type(*ch0))};
  18. const int u1{std::toupper(Traits::to_int_type(*ch1))};
  19. if(const int diff{u0-u1}) return diff;
  20. ++ch0; ++ch1;
  21. }
  22. if(str0.size() < str1.size()) return -1;
  23. if(str0.size() > str1.size()) return 1;
  24. return 0;
  25. }
  26. int case_compare(const std::wstring_view str0, const std::wstring_view str1) noexcept
  27. {
  28. using Traits = std::wstring_view::traits_type;
  29. auto ch0 = str0.cbegin();
  30. auto ch1 = str1.cbegin();
  31. auto ch1end = ch1 + std::min(str0.size(), str1.size());
  32. while(ch1 != ch1end)
  33. {
  34. const auto u0 = std::towupper(Traits::to_int_type(*ch0));
  35. const auto u1 = std::towupper(Traits::to_int_type(*ch1));
  36. if(const auto diff = static_cast<int>(u0-u1)) return diff;
  37. ++ch0; ++ch1;
  38. }
  39. if(str0.size() < str1.size()) return -1;
  40. if(str0.size() > str1.size()) return 1;
  41. return 0;
  42. }
  43. int strcasecmp(const char *str0, const char *str1) noexcept
  44. { return case_compare(str0, str1); }
  45. int strncasecmp(const char *str0, const char *str1, std::size_t len) noexcept
  46. {
  47. return case_compare(std::string_view{str0, std::min(std::strlen(str0), len)},
  48. std::string_view{str1, std::min(std::strlen(str1), len)});
  49. }
  50. } // namespace al