00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ABSL_STRINGS_INTERNAL_CHAR_MAP_H_
00021 #define ABSL_STRINGS_INTERNAL_CHAR_MAP_H_
00022
00023 #include <cstddef>
00024 #include <cstdint>
00025 #include <cstring>
00026
00027 #include "absl/base/macros.h"
00028 #include "absl/base/port.h"
00029
00030 namespace absl {
00031 namespace strings_internal {
00032
00033 class Charmap {
00034 public:
00035 constexpr Charmap() : m_() {}
00036
00037
00038
00039 Charmap(const char* str, int len) : m_() {
00040 while (len--) SetChar(*str++);
00041 }
00042
00043
00044
00045 explicit Charmap(const char* str) : m_() {
00046 while (*str) SetChar(*str++);
00047 }
00048
00049 constexpr bool contains(unsigned char c) const {
00050 return (m_[c / 64] >> (c % 64)) & 0x1;
00051 }
00052
00053
00054 bool IntersectsWith(const Charmap& c) const {
00055 for (size_t i = 0; i < ABSL_ARRAYSIZE(m_); ++i) {
00056 if ((m_[i] & c.m_[i]) != 0) return true;
00057 }
00058 return false;
00059 }
00060
00061 bool IsZero() const {
00062 for (uint64_t c : m_) {
00063 if (c != 0) return false;
00064 }
00065 return true;
00066 }
00067
00068
00069 static constexpr Charmap Char(char x) {
00070 return Charmap(CharMaskForWord(x, 0), CharMaskForWord(x, 1),
00071 CharMaskForWord(x, 2), CharMaskForWord(x, 3));
00072 }
00073
00074
00075
00076
00077 static constexpr Charmap FromString(const char* s) {
00078 return *s == 0 ? Charmap() : (Char(*s) | FromString(s + 1));
00079 }
00080
00081
00082 static constexpr Charmap Range(char lo, char hi) {
00083 return Charmap(RangeForWord(lo, hi, 0), RangeForWord(lo, hi, 1),
00084 RangeForWord(lo, hi, 2), RangeForWord(lo, hi, 3));
00085 }
00086
00087 friend constexpr Charmap operator&(const Charmap& a, const Charmap& b) {
00088 return Charmap(a.m_[0] & b.m_[0], a.m_[1] & b.m_[1], a.m_[2] & b.m_[2],
00089 a.m_[3] & b.m_[3]);
00090 }
00091
00092 friend constexpr Charmap operator|(const Charmap& a, const Charmap& b) {
00093 return Charmap(a.m_[0] | b.m_[0], a.m_[1] | b.m_[1], a.m_[2] | b.m_[2],
00094 a.m_[3] | b.m_[3]);
00095 }
00096
00097 friend constexpr Charmap operator~(const Charmap& a) {
00098 return Charmap(~a.m_[0], ~a.m_[1], ~a.m_[2], ~a.m_[3]);
00099 }
00100
00101 private:
00102 constexpr Charmap(uint64_t b0, uint64_t b1, uint64_t b2, uint64_t b3)
00103 : m_{b0, b1, b2, b3} {}
00104
00105 static constexpr uint64_t RangeForWord(unsigned char lo, unsigned char hi,
00106 uint64_t word) {
00107 return OpenRangeFromZeroForWord(hi + 1, word) &
00108 ~OpenRangeFromZeroForWord(lo, word);
00109 }
00110
00111
00112 static constexpr uint64_t OpenRangeFromZeroForWord(uint64_t upper,
00113 uint64_t word) {
00114 return (upper <= 64 * word)
00115 ? 0
00116 : (upper >= 64 * (word + 1))
00117 ? ~static_cast<uint64_t>(0)
00118 : (~static_cast<uint64_t>(0) >> (64 - upper % 64));
00119 }
00120
00121 static constexpr uint64_t CharMaskForWord(unsigned char x, uint64_t word) {
00122 return (x / 64 == word) ? (static_cast<uint64_t>(1) << (x % 64)) : 0;
00123 }
00124
00125 private:
00126 void SetChar(unsigned char c) {
00127 m_[c / 64] |= static_cast<uint64_t>(1) << (c % 64);
00128 }
00129
00130 uint64_t m_[4];
00131 };
00132
00133
00134 constexpr Charmap UpperCharmap() { return Charmap::Range('A', 'Z'); }
00135 constexpr Charmap LowerCharmap() { return Charmap::Range('a', 'z'); }
00136 constexpr Charmap DigitCharmap() { return Charmap::Range('0', '9'); }
00137 constexpr Charmap AlphaCharmap() { return LowerCharmap() | UpperCharmap(); }
00138 constexpr Charmap AlnumCharmap() { return DigitCharmap() | AlphaCharmap(); }
00139 constexpr Charmap XDigitCharmap() {
00140 return DigitCharmap() | Charmap::Range('A', 'F') | Charmap::Range('a', 'f');
00141 }
00142 constexpr Charmap PrintCharmap() { return Charmap::Range(0x20, 0x7e); }
00143 constexpr Charmap SpaceCharmap() { return Charmap::FromString("\t\n\v\f\r "); }
00144 constexpr Charmap CntrlCharmap() {
00145 return Charmap::Range(0, 0x7f) & ~PrintCharmap();
00146 }
00147 constexpr Charmap BlankCharmap() { return Charmap::FromString("\t "); }
00148 constexpr Charmap GraphCharmap() { return PrintCharmap() & ~SpaceCharmap(); }
00149 constexpr Charmap PunctCharmap() { return GraphCharmap() & ~AlnumCharmap(); }
00150
00151 }
00152 }
00153
00154 #endif // ABSL_STRINGS_INTERNAL_CHAR_MAP_H_