ascii.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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 <util/generic/string.h>
  55. #include "y_absl/base/attributes.h"
  56. #include "y_absl/base/config.h"
  57. #include "y_absl/strings/string_view.h"
  58. namespace y_absl {
  59. Y_ABSL_NAMESPACE_BEGIN
  60. namespace ascii_internal {
  61. // Declaration for an array of bitfields holding character information.
  62. Y_ABSL_DLL extern const unsigned char kPropertyBits[256];
  63. // Declaration for the array of characters to upper-case characters.
  64. Y_ABSL_DLL extern const char kToUpper[256];
  65. // Declaration for the array of characters to lower-case characters.
  66. Y_ABSL_DLL extern const char kToLower[256];
  67. } // namespace ascii_internal
  68. // ascii_isalpha()
  69. //
  70. // Determines whether the given character is an alphabetic character.
  71. inline bool ascii_isalpha(unsigned char c) {
  72. return (ascii_internal::kPropertyBits[c] & 0x01) != 0;
  73. }
  74. // ascii_isalnum()
  75. //
  76. // Determines whether the given character is an alphanumeric character.
  77. inline bool ascii_isalnum(unsigned char c) {
  78. return (ascii_internal::kPropertyBits[c] & 0x04) != 0;
  79. }
  80. // ascii_isspace()
  81. //
  82. // Determines whether the given character is a whitespace character (space,
  83. // tab, vertical tab, formfeed, linefeed, or carriage return).
  84. inline bool ascii_isspace(unsigned char c) {
  85. return (ascii_internal::kPropertyBits[c] & 0x08) != 0;
  86. }
  87. // ascii_ispunct()
  88. //
  89. // Determines whether the given character is a punctuation character.
  90. inline bool ascii_ispunct(unsigned char c) {
  91. return (ascii_internal::kPropertyBits[c] & 0x10) != 0;
  92. }
  93. // ascii_isblank()
  94. //
  95. // Determines whether the given character is a blank character (tab or space).
  96. inline bool ascii_isblank(unsigned char c) {
  97. return (ascii_internal::kPropertyBits[c] & 0x20) != 0;
  98. }
  99. // ascii_iscntrl()
  100. //
  101. // Determines whether the given character is a control character.
  102. inline bool ascii_iscntrl(unsigned char c) {
  103. return (ascii_internal::kPropertyBits[c] & 0x40) != 0;
  104. }
  105. // ascii_isxdigit()
  106. //
  107. // Determines whether the given character can be represented as a hexadecimal
  108. // digit character (i.e. {0-9} or {A-F}).
  109. inline bool ascii_isxdigit(unsigned char c) {
  110. return (ascii_internal::kPropertyBits[c] & 0x80) != 0;
  111. }
  112. // ascii_isdigit()
  113. //
  114. // Determines whether the given character can be represented as a decimal
  115. // digit character (i.e. {0-9}).
  116. inline bool ascii_isdigit(unsigned char c) { return c >= '0' && c <= '9'; }
  117. // ascii_isprint()
  118. //
  119. // Determines whether the given character is printable, including spaces.
  120. inline bool ascii_isprint(unsigned char c) { return c >= 32 && c < 127; }
  121. // ascii_isgraph()
  122. //
  123. // Determines whether the given character has a graphical representation.
  124. inline bool ascii_isgraph(unsigned char c) { return c > 32 && c < 127; }
  125. // ascii_isupper()
  126. //
  127. // Determines whether the given character is uppercase.
  128. inline bool ascii_isupper(unsigned char c) { return c >= 'A' && c <= 'Z'; }
  129. // ascii_islower()
  130. //
  131. // Determines whether the given character is lowercase.
  132. inline bool ascii_islower(unsigned char c) { return c >= 'a' && c <= 'z'; }
  133. // ascii_isascii()
  134. //
  135. // Determines whether the given character is ASCII.
  136. inline bool ascii_isascii(unsigned char c) { return c < 128; }
  137. // ascii_tolower()
  138. //
  139. // Returns an ASCII character, converting to lowercase if uppercase is
  140. // passed. Note that character values > 127 are simply returned.
  141. inline char ascii_tolower(unsigned char c) {
  142. return ascii_internal::kToLower[c];
  143. }
  144. // Converts the characters in `s` to lowercase, changing the contents of `s`.
  145. void AsciiStrToLower(TString* s);
  146. // Creates a lowercase string from a given y_absl::string_view.
  147. Y_ABSL_MUST_USE_RESULT inline TString AsciiStrToLower(y_absl::string_view s) {
  148. TString result(s);
  149. y_absl::AsciiStrToLower(&result);
  150. return result;
  151. }
  152. // ascii_toupper()
  153. //
  154. // Returns the ASCII character, converting to upper-case if lower-case is
  155. // passed. Note that characters values > 127 are simply returned.
  156. inline char ascii_toupper(unsigned char c) {
  157. return ascii_internal::kToUpper[c];
  158. }
  159. // Converts the characters in `s` to uppercase, changing the contents of `s`.
  160. void AsciiStrToUpper(TString* s);
  161. // Creates an uppercase string from a given y_absl::string_view.
  162. Y_ABSL_MUST_USE_RESULT inline TString AsciiStrToUpper(y_absl::string_view s) {
  163. TString result(s);
  164. y_absl::AsciiStrToUpper(&result);
  165. return result;
  166. }
  167. // Returns y_absl::string_view with whitespace stripped from the beginning of the
  168. // given string_view.
  169. Y_ABSL_MUST_USE_RESULT inline y_absl::string_view StripLeadingAsciiWhitespace(
  170. y_absl::string_view str) {
  171. auto it = std::find_if_not(str.begin(), str.end(), y_absl::ascii_isspace);
  172. return str.substr(static_cast<size_t>(it - str.begin()));
  173. }
  174. // Strips in place whitespace from the beginning of the given string.
  175. inline void StripLeadingAsciiWhitespace(TString* str) {
  176. auto it = std::find_if_not(str->cbegin(), str->cend(), y_absl::ascii_isspace);
  177. str->erase(str->begin(), it);
  178. }
  179. // Returns y_absl::string_view with whitespace stripped from the end of the given
  180. // string_view.
  181. Y_ABSL_MUST_USE_RESULT inline y_absl::string_view StripTrailingAsciiWhitespace(
  182. y_absl::string_view str) {
  183. auto it = std::find_if_not(str.rbegin(), str.rend(), y_absl::ascii_isspace);
  184. return str.substr(0, static_cast<size_t>(str.rend() - it));
  185. }
  186. // Strips in place whitespace from the end of the given string
  187. inline void StripTrailingAsciiWhitespace(TString* str) {
  188. auto it = std::find_if_not(str->rbegin(), str->rend(), y_absl::ascii_isspace);
  189. str->erase(static_cast<size_t>(str->rend() - it));
  190. }
  191. // Returns y_absl::string_view with whitespace stripped from both ends of the
  192. // given string_view.
  193. Y_ABSL_MUST_USE_RESULT inline y_absl::string_view StripAsciiWhitespace(
  194. y_absl::string_view str) {
  195. return StripTrailingAsciiWhitespace(StripLeadingAsciiWhitespace(str));
  196. }
  197. // Strips in place whitespace from both ends of the given string
  198. inline void StripAsciiWhitespace(TString* str) {
  199. StripTrailingAsciiWhitespace(str);
  200. StripLeadingAsciiWhitespace(str);
  201. }
  202. // Removes leading, trailing, and consecutive internal whitespace.
  203. void RemoveExtraAsciiWhitespace(TString*);
  204. Y_ABSL_NAMESPACE_END
  205. } // namespace y_absl
  206. #endif // Y_ABSL_STRINGS_ASCII_H_