string.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //
  2. // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_STRING_HPP
  10. #define BOOST_BEAST_STRING_HPP
  11. #include <boost/beast/core/detail/config.hpp>
  12. #include <boost/version.hpp>
  13. #include <boost/utility/string_view.hpp>
  14. #include <algorithm>
  15. namespace boost {
  16. namespace beast {
  17. /// The type of string view used by the library
  18. using string_view = boost::string_view;
  19. /// The type of basic string view used by the library
  20. template<class CharT, class Traits>
  21. using basic_string_view =
  22. boost::basic_string_view<CharT, Traits>;
  23. namespace detail {
  24. inline
  25. char
  26. ascii_tolower(char c)
  27. {
  28. return ((static_cast<unsigned>(c) - 65U) < 26) ?
  29. c + 'a' - 'A' : c;
  30. }
  31. template<class = void>
  32. bool
  33. iequals(
  34. beast::string_view lhs,
  35. beast::string_view rhs)
  36. {
  37. auto n = lhs.size();
  38. if(rhs.size() != n)
  39. return false;
  40. auto p1 = lhs.data();
  41. auto p2 = rhs.data();
  42. char a, b;
  43. while(n--)
  44. {
  45. a = *p1++;
  46. b = *p2++;
  47. if(a != b)
  48. {
  49. // slow loop
  50. do
  51. {
  52. if(ascii_tolower(a) != ascii_tolower(b))
  53. return false;
  54. a = *p1++;
  55. b = *p2++;
  56. }
  57. while(n--);
  58. return true;
  59. }
  60. }
  61. return true;
  62. }
  63. } // detail
  64. /** Returns `true` if two strings are equal, using a case-insensitive comparison.
  65. The case-comparison operation is defined only for low-ASCII characters.
  66. @param lhs The string on the left side of the equality
  67. @param rhs The string on the right side of the equality
  68. */
  69. inline
  70. bool
  71. iequals(
  72. beast::string_view lhs,
  73. beast::string_view rhs)
  74. {
  75. return detail::iequals(lhs, rhs);
  76. }
  77. /** A case-insensitive less predicate for strings.
  78. The case-comparison operation is defined only for low-ASCII characters.
  79. */
  80. struct iless
  81. {
  82. bool
  83. operator()(
  84. string_view lhs,
  85. string_view rhs) const
  86. {
  87. using std::begin;
  88. using std::end;
  89. return std::lexicographical_compare(
  90. begin(lhs), end(lhs), begin(rhs), end(rhs),
  91. [](char c1, char c2)
  92. {
  93. return detail::ascii_tolower(c1) < detail::ascii_tolower(c2);
  94. }
  95. );
  96. }
  97. };
  98. /** A case-insensitive equality predicate for strings.
  99. The case-comparison operation is defined only for low-ASCII characters.
  100. */
  101. struct iequal
  102. {
  103. bool
  104. operator()(
  105. string_view lhs,
  106. string_view rhs) const
  107. {
  108. return iequals(lhs, rhs);
  109. }
  110. };
  111. } // beast
  112. } // boost
  113. #endif