25 assert(!Matches.empty());
26 for (
unsigned i = 0, e = Matches[0]->first.size(); i != e; ++i) {
28 char Letter = Matches[0]->first[i];
30 for (
unsigned str = 0, e = Matches.size(); str != e; ++str)
31 if (Matches[str]->first[i] != Letter)
35 return Matches[0]->first.size();
44 EmitStringMatcherForChar(
const std::vector<const StringPair*> &Matches,
45 unsigned CharNo,
unsigned IndentCount)
const {
46 assert(!Matches.empty() &&
"Must have at least one string to match!");
47 std::string Indent(IndentCount*2+4,
' ');
51 if (CharNo == Matches[0]->first.size()) {
52 assert(Matches.size() == 1 &&
"Had duplicate keys to match on");
57 std::pair<StringRef, StringRef>
Split = Code.split(
'\n');
58 OS << Indent << Split.first <<
"\t // \"" << Matches[0]->first <<
"\"\n";
61 while (!Code.empty()) {
62 Split = Code.split(
'\n');
63 OS << Indent << Split.first <<
"\n";
70 std::map<char, std::vector<const StringPair*> > MatchesByLetter;
72 for (
unsigned i = 0, e = Matches.size(); i != e; ++i)
73 MatchesByLetter[Matches[i]->first[CharNo]].push_back(Matches[i]);
78 if (MatchesByLetter.size() == 1) {
80 unsigned NumChars = FirstNonCommonLetter-CharNo;
86 OS << Indent <<
"if (" << StrVariableName <<
"[" << CharNo <<
"] != '"
87 << Matches[0]->first[CharNo] <<
"')\n";
88 OS << Indent <<
" break;\n";
92 OS << Indent <<
"if (memcmp(" << StrVariableName <<
".data()+" << CharNo
93 <<
", \"" << Matches[0]->first.
substr(CharNo, NumChars) <<
"\", "
94 << NumChars <<
"))\n";
95 OS << Indent <<
" break;\n";
98 return EmitStringMatcherForChar(Matches, FirstNonCommonLetter, IndentCount);
103 OS << Indent <<
"switch (" << StrVariableName <<
"[" << CharNo <<
"]) {\n";
104 OS << Indent <<
"default: break;\n";
106 for (std::map<
char, std::vector<const StringPair*> >::iterator
LI =
107 MatchesByLetter.begin(), E = MatchesByLetter.end();
LI != E; ++
LI) {
109 OS << Indent <<
"case '" <<
LI->first <<
"':\t // "
110 <<
LI->second.size() <<
" string";
111 if (
LI->second.size() != 1) OS <<
's';
112 OS <<
" to match.\n";
113 if (EmitStringMatcherForChar(
LI->second, CharNo+1, IndentCount+1))
114 OS << Indent <<
" break;\n";
117 OS << Indent <<
"}\n";
126 if (Matches.empty())
return;
129 std::map<unsigned, std::vector<const StringPair*> > MatchesByLength;
131 for (
unsigned i = 0, e = Matches.size(); i != e; ++i)
132 MatchesByLength[Matches[i].first.size()].push_back(&Matches[i]);
136 OS.
indent(Indent*2+2) <<
"switch (" << StrVariableName <<
".size()) {\n";
137 OS.
indent(Indent*2+2) <<
"default: break;\n";
139 for (std::map<
unsigned, std::vector<const StringPair*> >::iterator
LI =
140 MatchesByLength.begin(), E = MatchesByLength.end();
LI != E; ++
LI) {
141 OS.
indent(Indent*2+2) <<
"case " <<
LI->first <<
":\t // "
143 <<
" string" << (
LI->second.size() == 1 ?
"" :
"s") <<
" to match.\n";
144 if (EmitStringMatcherForChar(
LI->second, 0, Indent))
145 OS.
indent(Indent*2+4) <<
"break;\n";
148 OS.
indent(Indent*2+2) <<
"}\n";
std::pair< std::string, std::string > StringPair
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
StringRef substr(size_t Start, size_t N=npos) const
LoopInfoBase< BlockT, LoopT > * LI
static void Split(std::vector< std::string > &V, const StringRef S)
static unsigned FindFirstNonCommonLetter(const std::vector< const StringMatcher::StringPair * > &Matches)
void Emit(unsigned Indent=0) const