00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/strings/internal/char_map.h"
00016
00017 #include <cctype>
00018 #include <string>
00019 #include <vector>
00020
00021 #include "gmock/gmock.h"
00022 #include "gtest/gtest.h"
00023
00024 namespace {
00025
00026 constexpr absl::strings_internal::Charmap everything_map =
00027 ~absl::strings_internal::Charmap();
00028 constexpr absl::strings_internal::Charmap nothing_map{};
00029
00030 TEST(Charmap, AllTests) {
00031 const absl::strings_internal::Charmap also_nothing_map("", 0);
00032 ASSERT_TRUE(everything_map.contains('\0'));
00033 ASSERT_TRUE(!nothing_map.contains('\0'));
00034 ASSERT_TRUE(!also_nothing_map.contains('\0'));
00035 for (unsigned char ch = 1; ch != 0; ++ch) {
00036 ASSERT_TRUE(everything_map.contains(ch));
00037 ASSERT_TRUE(!nothing_map.contains(ch));
00038 ASSERT_TRUE(!also_nothing_map.contains(ch));
00039 }
00040
00041 const absl::strings_internal::Charmap symbols("&@#@^!@?", 5);
00042 ASSERT_TRUE(symbols.contains('&'));
00043 ASSERT_TRUE(symbols.contains('@'));
00044 ASSERT_TRUE(symbols.contains('#'));
00045 ASSERT_TRUE(symbols.contains('^'));
00046 ASSERT_TRUE(!symbols.contains('!'));
00047 ASSERT_TRUE(!symbols.contains('?'));
00048 int cnt = 0;
00049 for (unsigned char ch = 1; ch != 0; ++ch)
00050 cnt += symbols.contains(ch);
00051 ASSERT_EQ(cnt, 4);
00052
00053 const absl::strings_internal::Charmap lets("^abcde", 3);
00054 const absl::strings_internal::Charmap lets2("fghij\0klmnop", 10);
00055 const absl::strings_internal::Charmap lets3("fghij\0klmnop");
00056 ASSERT_TRUE(lets2.contains('k'));
00057 ASSERT_TRUE(!lets3.contains('k'));
00058
00059 ASSERT_TRUE(symbols.IntersectsWith(lets));
00060 ASSERT_TRUE(!lets2.IntersectsWith(lets));
00061 ASSERT_TRUE(lets.IntersectsWith(symbols));
00062 ASSERT_TRUE(!lets.IntersectsWith(lets2));
00063
00064 ASSERT_TRUE(nothing_map.IsZero());
00065 ASSERT_TRUE(!lets.IsZero());
00066 }
00067
00068 namespace {
00069 std::string Members(const absl::strings_internal::Charmap& m) {
00070 std::string r;
00071 for (size_t i = 0; i < 256; ++i)
00072 if (m.contains(i)) r.push_back(i);
00073 return r;
00074 }
00075
00076 std::string ClosedRangeString(unsigned char lo, unsigned char hi) {
00077
00078 std::string s;
00079 while (true) {
00080 s.push_back(lo);
00081 if (lo == hi) break;
00082 ++lo;
00083 }
00084 return s;
00085 }
00086
00087 }
00088
00089 TEST(Charmap, Constexpr) {
00090 constexpr absl::strings_internal::Charmap kEmpty = nothing_map;
00091 EXPECT_THAT(Members(kEmpty), "");
00092 constexpr absl::strings_internal::Charmap kA =
00093 absl::strings_internal::Charmap::Char('A');
00094 EXPECT_THAT(Members(kA), "A");
00095 constexpr absl::strings_internal::Charmap kAZ =
00096 absl::strings_internal::Charmap::Range('A', 'Z');
00097 EXPECT_THAT(Members(kAZ), "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
00098 constexpr absl::strings_internal::Charmap kIdentifier =
00099 absl::strings_internal::Charmap::Range('0', '9') |
00100 absl::strings_internal::Charmap::Range('A', 'Z') |
00101 absl::strings_internal::Charmap::Range('a', 'z') |
00102 absl::strings_internal::Charmap::Char('_');
00103 EXPECT_THAT(Members(kIdentifier),
00104 "0123456789"
00105 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00106 "_"
00107 "abcdefghijklmnopqrstuvwxyz");
00108 constexpr absl::strings_internal::Charmap kAll = everything_map;
00109 for (size_t i = 0; i < 256; ++i) {
00110 EXPECT_TRUE(kAll.contains(i)) << i;
00111 }
00112 constexpr absl::strings_internal::Charmap kHello =
00113 absl::strings_internal::Charmap::FromString("Hello, world!");
00114 EXPECT_THAT(Members(kHello), " !,Hdelorw");
00115
00116
00117 constexpr absl::strings_internal::Charmap kABC =
00118 absl::strings_internal::Charmap::Range('A', 'Z') &
00119 ~absl::strings_internal::Charmap::Range('D', 'Z');
00120 EXPECT_THAT(Members(kABC), "ABC");
00121 }
00122
00123 TEST(Charmap, Range) {
00124
00125
00126 std::vector<size_t> poi = {0, 1, 2, 3, 4, 7, 8, 9, 15,
00127 16, 17, 30, 31, 32, 33, 63, 64, 65,
00128 127, 128, 129, 223, 224, 225, 254, 255};
00129 for (auto lo = poi.begin(); lo != poi.end(); ++lo) {
00130 SCOPED_TRACE(*lo);
00131 for (auto hi = lo; hi != poi.end(); ++hi) {
00132 SCOPED_TRACE(*hi);
00133 EXPECT_THAT(Members(absl::strings_internal::Charmap::Range(*lo, *hi)),
00134 ClosedRangeString(*lo, *hi));
00135 }
00136 }
00137 }
00138
00139 bool AsBool(int x) { return static_cast<bool>(x); }
00140
00141 TEST(CharmapCtype, Match) {
00142 for (int c = 0; c < 256; ++c) {
00143 SCOPED_TRACE(c);
00144 SCOPED_TRACE(static_cast<char>(c));
00145 EXPECT_EQ(AsBool(std::isupper(c)),
00146 absl::strings_internal::UpperCharmap().contains(c));
00147 EXPECT_EQ(AsBool(std::islower(c)),
00148 absl::strings_internal::LowerCharmap().contains(c));
00149 EXPECT_EQ(AsBool(std::isdigit(c)),
00150 absl::strings_internal::DigitCharmap().contains(c));
00151 EXPECT_EQ(AsBool(std::isalpha(c)),
00152 absl::strings_internal::AlphaCharmap().contains(c));
00153 EXPECT_EQ(AsBool(std::isalnum(c)),
00154 absl::strings_internal::AlnumCharmap().contains(c));
00155 EXPECT_EQ(AsBool(std::isxdigit(c)),
00156 absl::strings_internal::XDigitCharmap().contains(c));
00157 EXPECT_EQ(AsBool(std::isprint(c)),
00158 absl::strings_internal::PrintCharmap().contains(c));
00159 EXPECT_EQ(AsBool(std::isspace(c)),
00160 absl::strings_internal::SpaceCharmap().contains(c));
00161 EXPECT_EQ(AsBool(std::iscntrl(c)),
00162 absl::strings_internal::CntrlCharmap().contains(c));
00163 EXPECT_EQ(AsBool(std::isblank(c)),
00164 absl::strings_internal::BlankCharmap().contains(c));
00165 EXPECT_EQ(AsBool(std::isgraph(c)),
00166 absl::strings_internal::GraphCharmap().contains(c));
00167 EXPECT_EQ(AsBool(std::ispunct(c)),
00168 absl::strings_internal::PunctCharmap().contains(c));
00169 }
00170 }
00171
00172 }