Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is There a Standard Algorithm to Copy Until?

I am using an istream_iterator<char> it, so I cannot iterate over the range in reverse (or iterate over it twice, without a great deal of hastle.)

I want to copy until a condition is met. Is there something that would work like this in the standard library:

copy_until(it, istream_iterator<char>(), ostream_iterator<char>(cout), [](const unsigned char i){ return isalpha(i); })

If I have to roll something I can I was just hoping for some magic that I haven't been able to figure out.

EDIT:

The behavior I would expect from my made up copy_until function is:

while(it != istream_iterator<char>()) {
    if(!isalpha(static_cast<unsigned char>(*it))) break;
    cout << *it++;
}
like image 796
Jonathan Mee Avatar asked Dec 23 '22 23:12

Jonathan Mee


2 Answers

Just for completness, since the standard provides no out of box solution, thats my solution:

template<class _InIt, class _OutIt, class _Pr>
inline void copy_until (_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred) {
  while ((_First != _Last) && _Pred(*_First)) {
    *_Dest++ = *_First++;
  }
}

And that's how I use it:

copy_until(std::istreambuf_iterator<char>(is),
           std::istreambuf_iterator<char>(),
           std::ostreambuf_iterator<char>(os), 
           [] (char c) { return <some usefull condition here> });

For instance to read a string with only alnum characters from an input stream:

std::istream& operator>> (std::istream& is, std::string& n) {
  std::ostringstream str;
  copy_until(std::istreambuf_iterator<char>(is),
             std::istreambuf_iterator<char>(),
             std::ostreambuf_iterator<char>(str), 
             std::isalnum);
  n = str.str();
  return is;
}
like image 124
redleg Avatar answered Jan 04 '23 17:01

redleg


There is no copy until out of the box. Since you are copying from istream there is no other option but to use the loop with the break statement in it.

like image 38
SergeyA Avatar answered Jan 04 '23 19:01

SergeyA