// 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 init_(Traits const &traits, mpl::false_) { for(unsigned char offset = this->length_; offset; --offset, ++this->last_) { this->offsets_[traits.hash(*this->last_)] = offset; } }
// case-insensitive Boyer-Moore search with case-folding BidiIter find_nocase_fold_(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); string_type const *pat_tmp = &this->fold_.back(); BidiIter str_tmp = begin; for(; pat_tmp->end() != std::find(pat_tmp->begin(), pat_tmp->end(), *str_tmp); --pat_tmp, --str_tmp) { if(pat_tmp == &this->fold_.front()) { return str_tmp; } } offset = this->offsets_[traits.hash(*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 init_(Traits const &traits, mpl::true_) { this->fold_.reserve(this->length_ + 1); for(unsigned char offset = this->length_; offset; --offset, ++this->last_) { this->fold_.push_back(traits.fold_case(*this->last_)); for(typename string_type::const_iterator beg = this->fold_.back().begin(), end = this->fold_.back().end(); beg != end; ++beg) { this->offsets_[traits.hash(*beg)] = offset; } } this->fold_.push_back(traits.fold_case(*this->last_)); }
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)); } } }
bool test(char_type ch, Traits const &traits, mpl::true_) const { BOOST_ASSERT(this->icase_); return this->bset_.test(traits.hash(traits.translate_nocase(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)); }