Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::search on single-pass range

I'd like to read from a std::istream until a certain sequence of characters is found, i.e., I'd like to implement the following interface:

void read_until (std::istream &is, std::string_view needle);

Using std::istreambuf_iterator, I believe this is equivalent to a combination of std::search on a single-pass iterator. Unfortunately, the std::boyer_moore_searcher needs random-access iterators.

Are there any easy implementations of the above interface using the C++ standard library (and a bit of memory proportional to the size of sv), or do I have to code it myself?

like image 631
Toby Brull Avatar asked Feb 26 '18 21:02

Toby Brull


1 Answers

void read_until (std::istream &is, std::string_view needle) {
  if (needle.size()==0) return;
  std::string buff;
  buff.reserve(needle.size());
  auto it = std::find_if( std::istream_iterator<char>(is), std::istream_iterator<char>(), [&](char c) {
    buff.push_back(c);
    if (buff.size() < needle.size()) {
      return false;
    }
    if (buff == needle)
      return true;
    buff.erase(buff.begin());
    return false;
  });
}

that is the best I can do with std algorithms.

For optimization, using a circular buff might save a bit of work.

like image 155
Yakk - Adam Nevraumont Avatar answered Oct 27 '22 00:10

Yakk - Adam Nevraumont