Home > Software engineering >  pipe istream_view and views::transform. How?
pipe istream_view and views::transform. How?

Time:12-09

Sorry, I was searching a lot, but I still do not understand.

Let's assume that I want to read line by line with an istream_view using a line proxy and convert the result to lowercase.

It would be nice, if I could write

#include <iostream>
#include <sstream>
#include <string>
#include <iterator>
#include <ranges>
#include <algorithm>

namespace rng = std::ranges;

struct CompleteLine {    // Line Proxy for the input Iterator
    friend std::istream& operator>>(std::istream& is, CompleteLine& cl) { std::getline(is, cl.completeLine); return is; }
    operator std::string() const { return completeLine; }  // cast operator
    std::string completeLine{};
};

std::istringstream iss{ R"(1 Line AAA
2 Line BBB
3 Line CCC)" };

int main() {

    for (const std::string& line : rng::istream_view<CompleteLine>(iss) | std::views::transform(std::tolower)) {
        std::cout << line << '\n';
    }
}

But obviously I cannot. I does not compile.

How would I use ranges, views and pipes to get a correct solution?

CodePudding user response:

How would I use ranges, views and pipes to get a correct solution?

Your attempt is correct. However, it should be noted that rng::istream_view<CompleteLine>(iss) will generate a range whose elements are strings, while tolower acts on a single character.

This should work

for (const std::string& line : std::views::istream<CompleteLine>(iss)
                             | std::views::transform([](std::string line) {
                                  std::ranges::transform(line, line.begin(), 
                                    [](auto c) { return std::tolower(c); });
                                  return line;
                               })) {
    std::cout << line << '\n';
}

Demo

Prefer views::istream over ranges::istream_view. Prefer using lambdas instead of taking the address of toupper directly, the standard does not allow to do this.

  • Related