ascii.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. //
  2. // Copyright 2017 The Abseil Authors.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // https://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. // -----------------------------------------------------------------------------
  17. // File: ascii.h
  18. // -----------------------------------------------------------------------------
  19. //
  20. // This package contains functions operating on characters and strings
  21. // restricted to standard ASCII. These include character classification
  22. // functions analogous to those found in the ANSI C Standard Library <ctype.h>
  23. // header file.
  24. //
  25. // C++ implementations provide <ctype.h> functionality based on their
  26. // C environment locale. In general, reliance on such a locale is not ideal, as
  27. // the locale standard is problematic (and may not return invariant information
  28. // for the same character set, for example). These `ascii_*()` functions are
  29. // hard-wired for standard ASCII, much faster, and guaranteed to behave
  30. // consistently. They will never be overloaded, nor will their function
  31. // signature change.
  32. //
  33. // `ascii_isalnum()`, `ascii_isalpha()`, `ascii_isascii()`, `ascii_isblank()`,
  34. // `ascii_iscntrl()`, `ascii_isdigit()`, `ascii_isgraph()`, `ascii_islower()`,
  35. // `ascii_isprint()`, `ascii_ispunct()`, `ascii_isspace()`, `ascii_isupper()`,
  36. // `ascii_isxdigit()`
  37. // Analogous to the <ctype.h> functions with similar names, these
  38. // functions take an unsigned char and return a bool, based on whether the
  39. // character matches the condition specified.
  40. //
  41. // If the input character has a numerical value greater than 127, these
  42. // functions return `false`.
  43. //
  44. // `ascii_tolower()`, `ascii_toupper()`
  45. // Analogous to the <ctype.h> functions with similar names, these functions
  46. // take an unsigned char and return a char.
  47. //
  48. // If the input character is not an ASCII {lower,upper}-case letter (including
  49. // numerical values greater than 127) then the functions return the same value
  50. // as the input character.
  51. #ifndef Y_ABSL_STRINGS_ASCII_H_
  52. #define Y_ABSL_STRINGS_ASCII_H_
  53. #include <algorithm>
  54. #include <cstddef>
  55. #include <util/generic/string.h>
  56. #include "y_absl/base/attributes.h"
  57. #include "y_absl/base/config.h"
  58. #include "y_absl/base/nullability.h"
  59. #include "y_absl/strings/string_view.h"
  60. namespace y_absl {
  61. Y_ABSL_NAMESPACE_BEGIN
  62. namespace ascii_internal {
  63. // Declaration for an array of bitfields holding character information.
  64. Y_ABSL_DLL extern const unsigned char kPropertyBits[256];
  65. // Declaration for the array of characters to upper-case characters.
  66. Y_ABSL_DLL extern const char kToUpper[256];
  67. // Declaration for the array of characters to lower-case characters.
  68. Y_ABSL_DLL extern const char kToLower[256];
  69. } // namespace ascii_internal
  70. // ascii_isalpha()
  71. //
  72. // Determines whether the given character is an alphabetic character.
  73. inline bool ascii_isalpha(unsigned char c) {
  74. return (ascii_internal::kPropertyBits[c] & 0x01) != 0;
  75. }
  76. // ascii_isalnum()
  77. //
  78. // Determines whether the given character is an alphanumeric character.
  79. inline bool ascii_isalnum(unsigned char c) {
  80. return (ascii_internal::kPropertyBits[c] & 0x04) != 0;
  81. }
  82. // ascii_isspace()
  83. //
  84. // Determines whether the given character is a whitespace character (space,
  85. // tab, vertical tab, formfeed, linefeed, or carriage return).
  86. inline bool ascii_isspace(unsigned char c) {
  87. return (ascii_internal::kPropertyBits[c] & 0x08) != 0;
  88. }
  89. // ascii_ispunct()
  90. //
  91. // Determines whether the given character is a punctuation character.
  92. inline bool ascii_ispunct(unsigned char c) {
  93. return (ascii_internal::kPropertyBits[c] & 0x10) != 0;
  94. }
  95. // ascii_isblank()
  96. //
  97. // Determines whether the given character is a blank character (tab or space).
  98. inline bool ascii_isblank(unsigned char c) {
  99. return (ascii_internal::kPropertyBits[c] & 0x20) != 0;
  100. }
  101. // ascii_iscntrl()
  102. //
  103. // Determines whether the given character is a control character.
  104. inline bool ascii_iscntrl(unsigned char c) {
  105. return (ascii_internal::kPropertyBits[c] & 0x40) != 0;
  106. }
  107. // ascii_isxdigit()
  108. //
  109. // Determines whether the given character can be represented as a hexadecimal
  110. // digit character (i.e. {0-9} or {A-F}).
  111. inline bool ascii_isxdigit(unsigned char c) {
  112. return (ascii_internal::kPropertyBits[c] & 0x80) != 0;
  113. }
  114. // ascii_isdigit()
  115. //
  116. // Determines whether the given character can be represented as a decimal
  117. // digit character (i.e. {0-9}).
  118. inline bool ascii_isdigit(unsigned char c) { return c >= '0' && c <= '9'; }
  119. // ascii_isprint()
  120. //
  121. // Determines whether the given character is printable, including spaces.
  122. inline bool ascii_isprint(unsigned char c) { return c >= 32 && c < 127; }
  123. // ascii_isgraph()
  124. //
  125. // Determines whether the given character has a graphical representation.
  126. inline bool ascii_isgraph(unsigned char c) { return c > 32 && c < 127; }
  127. // ascii_isupper()
  128. //
  129. // Determines whether the given character is uppercase.
  130. inline bool ascii_isupper(unsigned char c) { return c >= 'A' && c <= 'Z'; }
  131. // ascii_islower()
  132. //
  133. // Determines whether the given character is lowercase.
  134. inline bool ascii_islower(unsigned char c) { return c >= 'a' && c <= 'z'; }
  135. // ascii_isascii()
  136. //
  137. // Determines whether the given character is ASCII.
  138. inline bool ascii_isascii(unsigned char c) { return c < 128; }
  139. // ascii_tolower()
  140. //
  141. // Returns an ASCII character, converting to lowercase if uppercase is
  142. // passed. Note that character values > 127 are simply returned.
  143. inline char ascii_tolower(unsigned char c) {
  144. return ascii_internal::kToLower[c];
  145. }
  146. // Converts the characters in `s` to lowercase, changing the contents of `s`.
  147. void AsciiStrToLower(y_absl::Nonnull<TString*> s);
  148. // Creates a lowercase string from a given y_absl::string_view.
  149. Y_ABSL_MUST_USE_RESULT inline TString AsciiStrToLower(y_absl::string_view s) {
  150. TString result(s);
  151. y_absl::AsciiStrToLower(&result);
  152. return result;
  153. }
  154. // ascii_toupper()
  155. //
  156. // Returns the ASCII character, converting to upper-case if lower-case is
  157. // passed. Note that characters values > 127 are simply returned.
  158. inline char ascii_toupper(unsigned char c) {
  159. return ascii_internal::kToUpper[c];
  160. }
  161. // Converts the characters in `s` to uppercase, changing the contents of `s`.
  162. void AsciiStrToUpper(y_absl::Nonnull<TString*> s);
  163. // Creates an uppercase string from a given y_absl::string_view.
  164. Y_ABSL_MUST_USE_RESULT inline TString AsciiStrToUpper(y_absl::string_view s) {
  165. TString result(s);
  166. y_absl::AsciiStrToUpper(&result);
  167. return result;
  168. }
  169. // Returns y_absl::string_view with whitespace stripped from the beginning of the
  170. // given string_view.
  171. Y_ABSL_MUST_USE_RESULT inline y_absl::string_view StripLeadingAsciiWhitespace(
  172. y_absl::string_view str) {
  173. auto it = std::find_if_not(str.begin(), str.end(), y_absl::ascii_isspace);
  174. return str.substr(static_cast<size_t>(it - str.begin()));
  175. }
  176. // Strips in place whitespace from the beginning of the given string.
  177. inline void StripLeadingAsciiWhitespace(y_absl::Nonnull<TString*> str) {
  178. auto it = std::find_if_not(str->cbegin(), str->cend(), y_absl::ascii_isspace);
  179. str->erase(str->begin(), it);
  180. }
  181. // Returns y_absl::string_view with whitespace stripped from the end of the given
  182. // string_view.
  183. Y_ABSL_MUST_USE_RESULT inline y_absl::string_view StripTrailingAsciiWhitespace(
  184. y_absl::string_view str) {
  185. auto it = std::find_if_not(str.rbegin(), str.rend(), y_absl::ascii_isspace);
  186. return str.substr(0, static_cast<size_t>(str.rend() - it));
  187. }
  188. // Strips in place whitespace from the end of the given string
  189. inline void StripTrailingAsciiWhitespace(y_absl::Nonnull<TString*> str) {
  190. auto it = std::find_if_not(str->rbegin(), str->rend(), y_absl::ascii_isspace);
  191. str->erase(static_cast<size_t>(str->rend() - it));
  192. }
  193. // Returns y_absl::string_view with whitespace stripped from both ends of the
  194. // given string_view.
  195. Y_ABSL_MUST_USE_RESULT inline y_absl::string_view StripAsciiWhitespace(
  196. y_absl::string_view str) {
  197. return StripTrailingAsciiWhitespace(StripLeadingAsciiWhitespace(str));
  198. }
  199. // Strips in place whitespace from both ends of the given string
  200. inline void StripAsciiWhitespace(y_absl::Nonnull<TString*> str) {
  201. StripTrailingAsciiWhitespace(str);
  202. StripLeadingAsciiWhitespace(str);
  203. }
  204. // Removes leading, trailing, and consecutive internal whitespace.
  205. void RemoveExtraAsciiWhitespace(y_absl::Nonnull<TString*> str);
  206. Y_ABSL_NAMESPACE_END
  207. } // namespace y_absl
  208. #endif // Y_ABSL_STRINGS_ASCII_H_