// case-sensitive Boyer-Moore search BidiIter find_(BidiIter begin, BidiIter end, Traits const &traits) const { typedef typename boost::iterator_difference<BidiIter>::type diff_type; diff_type const endpos = std::distance(begin, end); diff_type offset = static_cast<diff_type>(this->length_); for(diff_type curpos = offset; curpos < endpos; curpos += offset) { std::advance(begin, offset); char_type const *pat_tmp = this->last_; BidiIter str_tmp = begin; for(; traits.translate(*str_tmp) == *pat_tmp; --pat_tmp, --str_tmp) { if(pat_tmp == this->begin_) { return str_tmp; } } offset = this->offsets_[traits.hash(traits.translate(*begin))]; } return end; }
void set_char(char_type ch, bool icase, Traits const &traits) { if(this->test_icase_(icase)) { ch = icase ? traits.translate_nocase(ch) : traits.translate(ch); this->bset_.set(traits.hash(ch)); } }
void set_range(char_type from, char_type to, bool no, bool icase, Traits const &traits) { int_type ifrom = std::char_traits<char_type>::to_int_type(from); int_type ito = std::char_traits<char_type>::to_int_type(to); BOOST_ASSERT(ifrom <= ito); // bound the computational complexity. BUGBUG could set the inverse range if(no || 256 < (ito - ifrom)) { this->set_all(); } else if(this->test_icase_(icase)) { for(int_type i = ifrom; i <= ito; ++i) { char_type ch = std::char_traits<char_type>::to_char_type(i); ch = icase ? traits.translate_nocase(ch) : traits.translate(ch); this->bset_.set(traits.hash(ch)); } } }
std::string expected(void) const { std::string result; auto i = this->subparsers.begin(), e = this->subparsers.end(); while(i != e) { result.append((*i)->expected()); ++i; if(i != e) { result.append(" "); result.append(traits.translate( shared_data, "OR" )); result.append(" "); } } return result; }
bool is_word(Traits const &tr, char_type ch) const { detail::ignore_unused(tr); return tr.isctype(tr.translate(ch), this->word_); }
inline Char translate(Char ch, Traits const &tr, mpl::false_) // case-sensitive { return tr.translate(ch); }
bool in_set(Traits const &traits, char_type ch) const { char_type const *begin = &this->set_[0], *end = begin + Size; ch = this->icase_ ? traits.translate_nocase(ch) : traits.translate(ch); return end != std::find(begin, end, ch); }
bool test(char_type ch, Traits const &traits, mpl::false_) const { BOOST_ASSERT(!this->icase_); return this->bset_.test(traits.hash(traits.translate(ch))); }
bool test(char_type ch, Traits const &traits) const { ch = this->icase_ ? traits.translate_nocase(ch) : traits.translate(ch); return this->bset_.test(traits.hash(ch)); }
int index(void) const { // if we have exactly one constructor index if(match_indices.size() == 1) { // then return it return match_indices.front(); } // if we have nothing if(match_indices.empty()) { throw std::runtime_error( traits.translate( shared_data, "No matching constructor for input" ) + " '" + input_string + "'. " + traits.translate( shared_data, "Expecting:" ) + " " + this->expected() + "." ); } // if we have multiple matching constructors if(match_indices.size() > 1) { std::string msg; msg.append(traits.translate( shared_data, "Ambiguous input." )); msg.append(" "); msg.append(traits.translate( shared_data, "Candidates are:" )); msg.append(" "); auto i = match_indices.begin(), e = match_indices.end(); while(i != e) { msg.append(this->subparsers[*i]->expected()); ++i; if(i != e) { msg.append(" "); msg.append(traits.translate( shared_data, "OR" )); msg.append(" "); } } msg.append(". "); msg.append(traits.translate( shared_data, "You may need to add explicit casts " "to disambiguate." )); throw std::runtime_error(msg); } assert(!"Never should get here!"); return 0; }